Merge branches/gcc-4_8-branch rev 208968.
[official-gcc.git] / gcc-4_8-branch / gcc / config / avr / avr.c
blob44d8a83e5eac33414d6fc8f49e7364c20dccb39d
1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2 Copyright (C) 1998-2013 Free Software Foundation, Inc.
3 Contributed by Denis Chertykov (chertykov@gmail.com)
5 This file is part of GCC.
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.
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.
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/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "rtl.h"
26 #include "regs.h"
27 #include "hard-reg-set.h"
28 #include "insn-config.h"
29 #include "conditions.h"
30 #include "insn-attr.h"
31 #include "insn-codes.h"
32 #include "flags.h"
33 #include "reload.h"
34 #include "tree.h"
35 #include "output.h"
36 #include "expr.h"
37 #include "c-family/c-common.h"
38 #include "diagnostic-core.h"
39 #include "obstack.h"
40 #include "function.h"
41 #include "recog.h"
42 #include "optabs.h"
43 #include "ggc.h"
44 #include "langhooks.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "target-def.h"
48 #include "params.h"
49 #include "df.h"
51 /* Maximal allowed offset for an address in the LD command */
52 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
54 /* Return true if STR starts with PREFIX and false, otherwise. */
55 #define STR_PREFIX_P(STR,PREFIX) (0 == strncmp (STR, PREFIX, strlen (PREFIX)))
57 /* The 4 bits starting at SECTION_MACH_DEP are reserved to store the
58 address space where data is to be located.
59 As the only non-generic address spaces are all located in flash,
60 this can be used to test if data shall go into some .progmem* section.
61 This must be the rightmost field of machine dependent section flags. */
62 #define AVR_SECTION_PROGMEM (0xf * SECTION_MACH_DEP)
64 /* Similar 4-bit region for SYMBOL_REF_FLAGS. */
65 #define AVR_SYMBOL_FLAG_PROGMEM (0xf * SYMBOL_FLAG_MACH_DEP)
67 /* Similar 4-bit region in SYMBOL_REF_FLAGS:
68 Set address-space AS in SYMBOL_REF_FLAGS of SYM */
69 #define AVR_SYMBOL_SET_ADDR_SPACE(SYM,AS) \
70 do { \
71 SYMBOL_REF_FLAGS (sym) &= ~AVR_SYMBOL_FLAG_PROGMEM; \
72 SYMBOL_REF_FLAGS (sym) |= (AS) * SYMBOL_FLAG_MACH_DEP; \
73 } while (0)
75 /* Read address-space from SYMBOL_REF_FLAGS of SYM */
76 #define AVR_SYMBOL_GET_ADDR_SPACE(SYM) \
77 ((SYMBOL_REF_FLAGS (sym) & AVR_SYMBOL_FLAG_PROGMEM) \
78 / SYMBOL_FLAG_MACH_DEP)
80 /* Known address spaces. The order must be the same as in the respective
81 enum from avr.h (or designated initialized must be used). */
82 const avr_addrspace_t avr_addrspace[ADDR_SPACE_COUNT] =
84 { ADDR_SPACE_RAM, 0, 2, "", 0, NULL },
85 { ADDR_SPACE_FLASH, 1, 2, "__flash", 0, ".progmem.data" },
86 { ADDR_SPACE_FLASH1, 1, 2, "__flash1", 1, ".progmem1.data" },
87 { ADDR_SPACE_FLASH2, 1, 2, "__flash2", 2, ".progmem2.data" },
88 { ADDR_SPACE_FLASH3, 1, 2, "__flash3", 3, ".progmem3.data" },
89 { ADDR_SPACE_FLASH4, 1, 2, "__flash4", 4, ".progmem4.data" },
90 { ADDR_SPACE_FLASH5, 1, 2, "__flash5", 5, ".progmem5.data" },
91 { ADDR_SPACE_MEMX, 1, 3, "__memx", 0, ".progmemx.data" },
95 /* Holding RAM addresses of some SFRs used by the compiler and that
96 are unique over all devices in an architecture like 'avr4'. */
98 typedef struct
100 /* SREG: The processor status */
101 int sreg;
103 /* RAMPX, RAMPY, RAMPD and CCP of XMEGA */
104 int ccp;
105 int rampd;
106 int rampx;
107 int rampy;
109 /* RAMPZ: The high byte of 24-bit address used with ELPM */
110 int rampz;
112 /* SP: The stack pointer and its low and high byte */
113 int sp_l;
114 int sp_h;
115 } avr_addr_t;
117 static avr_addr_t avr_addr;
120 /* Prototypes for local helper functions. */
122 static const char* out_movqi_r_mr (rtx, rtx[], int*);
123 static const char* out_movhi_r_mr (rtx, rtx[], int*);
124 static const char* out_movsi_r_mr (rtx, rtx[], int*);
125 static const char* out_movqi_mr_r (rtx, rtx[], int*);
126 static const char* out_movhi_mr_r (rtx, rtx[], int*);
127 static const char* out_movsi_mr_r (rtx, rtx[], int*);
129 static int get_sequence_length (rtx insns);
130 static int sequent_regs_live (void);
131 static const char *ptrreg_to_str (int);
132 static const char *cond_string (enum rtx_code);
133 static int avr_num_arg_regs (enum machine_mode, const_tree);
134 static int avr_operand_rtx_cost (rtx, enum machine_mode, enum rtx_code,
135 int, bool);
136 static void output_reload_in_const (rtx*, rtx, int*, bool);
137 static struct machine_function * avr_init_machine_status (void);
140 /* Prototypes for hook implementors if needed before their implementation. */
142 static bool avr_rtx_costs (rtx, int, int, int, int*, bool);
145 /* Allocate registers from r25 to r8 for parameters for function calls. */
146 #define FIRST_CUM_REG 26
148 /* Implicit target register of LPM instruction (R0) */
149 extern GTY(()) rtx lpm_reg_rtx;
150 rtx lpm_reg_rtx;
152 /* (Implicit) address register of LPM instruction (R31:R30 = Z) */
153 extern GTY(()) rtx lpm_addr_reg_rtx;
154 rtx lpm_addr_reg_rtx;
156 /* Temporary register RTX (reg:QI TMP_REGNO) */
157 extern GTY(()) rtx tmp_reg_rtx;
158 rtx tmp_reg_rtx;
160 /* Zeroed register RTX (reg:QI ZERO_REGNO) */
161 extern GTY(()) rtx zero_reg_rtx;
162 rtx zero_reg_rtx;
164 /* RTXs for all general purpose registers as QImode */
165 extern GTY(()) rtx all_regs_rtx[32];
166 rtx all_regs_rtx[32];
168 /* SREG, the processor status */
169 extern GTY(()) rtx sreg_rtx;
170 rtx sreg_rtx;
172 /* RAMP* special function registers */
173 extern GTY(()) rtx rampd_rtx;
174 extern GTY(()) rtx rampx_rtx;
175 extern GTY(()) rtx rampy_rtx;
176 extern GTY(()) rtx rampz_rtx;
177 rtx rampd_rtx;
178 rtx rampx_rtx;
179 rtx rampy_rtx;
180 rtx rampz_rtx;
182 /* RTX containing the strings "" and "e", respectively */
183 static GTY(()) rtx xstring_empty;
184 static GTY(()) rtx xstring_e;
186 /* Current architecture. */
187 const avr_arch_t *avr_current_arch;
189 /* Current device. */
190 const avr_mcu_t *avr_current_device;
192 /* Section to put switch tables in. */
193 static GTY(()) section *progmem_swtable_section;
195 /* Unnamed sections associated to __attribute__((progmem)) aka. PROGMEM
196 or to address space __flash* or __memx. Only used as singletons inside
197 avr_asm_select_section, but it must not be local there because of GTY. */
198 static GTY(()) section *progmem_section[ADDR_SPACE_COUNT];
200 /* Condition for insns/expanders from avr-dimode.md. */
201 bool avr_have_dimode = true;
203 /* To track if code will use .bss and/or .data. */
204 bool avr_need_clear_bss_p = false;
205 bool avr_need_copy_data_p = false;
208 /* Transform UP into lowercase and write the result to LO.
209 You must provide enough space for LO. Return LO. */
211 static char*
212 avr_tolower (char *lo, const char *up)
214 char *lo0 = lo;
216 for (; *up; up++, lo++)
217 *lo = TOLOWER (*up);
219 *lo = '\0';
221 return lo0;
225 /* Custom function to count number of set bits. */
227 static inline int
228 avr_popcount (unsigned int val)
230 int pop = 0;
232 while (val)
234 val &= val-1;
235 pop++;
238 return pop;
242 /* Constraint helper function. XVAL is a CONST_INT or a CONST_DOUBLE.
243 Return true if the least significant N_BYTES bytes of XVAL all have a
244 popcount in POP_MASK and false, otherwise. POP_MASK represents a subset
245 of integers which contains an integer N iff bit N of POP_MASK is set. */
247 bool
248 avr_popcount_each_byte (rtx xval, int n_bytes, int pop_mask)
250 int i;
252 enum machine_mode mode = GET_MODE (xval);
254 if (VOIDmode == mode)
255 mode = SImode;
257 for (i = 0; i < n_bytes; i++)
259 rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
260 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
262 if (0 == (pop_mask & (1 << avr_popcount (val8))))
263 return false;
266 return true;
270 /* Access some RTX as INT_MODE. If X is a CONST_FIXED we can get
271 the bit representation of X by "casting" it to CONST_INT. */
274 avr_to_int_mode (rtx x)
276 enum machine_mode mode = GET_MODE (x);
278 return VOIDmode == mode
280 : simplify_gen_subreg (int_mode_for_mode (mode), x, mode, 0);
284 /* Implement `TARGET_OPTION_OVERRIDE'. */
286 static void
287 avr_option_override (void)
289 flag_delete_null_pointer_checks = 0;
291 /* caller-save.c looks for call-clobbered hard registers that are assigned
292 to pseudos that cross calls and tries so save-restore them around calls
293 in order to reduce the number of stack slots needed.
295 This might lead to situations where reload is no more able to cope
296 with the challenge of AVR's very few address registers and fails to
297 perform the requested spills. */
299 if (avr_strict_X)
300 flag_caller_saves = 0;
302 /* Unwind tables currently require a frame pointer for correctness,
303 see toplev.c:process_options(). */
305 if ((flag_unwind_tables
306 || flag_non_call_exceptions
307 || flag_asynchronous_unwind_tables)
308 && !ACCUMULATE_OUTGOING_ARGS)
310 flag_omit_frame_pointer = 0;
313 avr_current_device = &avr_mcu_types[avr_mcu_index];
314 avr_current_arch = &avr_arch_types[avr_current_device->arch];
316 /* RAM addresses of some SFRs common to all devices in respective arch. */
318 /* SREG: Status Register containing flags like I (global IRQ) */
319 avr_addr.sreg = 0x3F + avr_current_arch->sfr_offset;
321 /* RAMPZ: Address' high part when loading via ELPM */
322 avr_addr.rampz = 0x3B + avr_current_arch->sfr_offset;
324 avr_addr.rampy = 0x3A + avr_current_arch->sfr_offset;
325 avr_addr.rampx = 0x39 + avr_current_arch->sfr_offset;
326 avr_addr.rampd = 0x38 + avr_current_arch->sfr_offset;
327 avr_addr.ccp = 0x34 + avr_current_arch->sfr_offset;
329 /* SP: Stack Pointer (SP_H:SP_L) */
330 avr_addr.sp_l = 0x3D + avr_current_arch->sfr_offset;
331 avr_addr.sp_h = avr_addr.sp_l + 1;
333 init_machine_status = avr_init_machine_status;
335 avr_log_set_avr_log();
338 /* Function to set up the backend function structure. */
340 static struct machine_function *
341 avr_init_machine_status (void)
343 return ggc_alloc_cleared_machine_function ();
347 /* Implement `INIT_EXPANDERS'. */
348 /* The function works like a singleton. */
350 void
351 avr_init_expanders (void)
353 int regno;
355 for (regno = 0; regno < 32; regno ++)
356 all_regs_rtx[regno] = gen_rtx_REG (QImode, regno);
358 lpm_reg_rtx = all_regs_rtx[LPM_REGNO];
359 tmp_reg_rtx = all_regs_rtx[TMP_REGNO];
360 zero_reg_rtx = all_regs_rtx[ZERO_REGNO];
362 lpm_addr_reg_rtx = gen_rtx_REG (HImode, REG_Z);
364 sreg_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.sreg));
365 rampd_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampd));
366 rampx_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampx));
367 rampy_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampy));
368 rampz_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampz));
370 xstring_empty = gen_rtx_CONST_STRING (VOIDmode, "");
371 xstring_e = gen_rtx_CONST_STRING (VOIDmode, "e");
375 /* Implement `REGNO_REG_CLASS'. */
376 /* Return register class for register R. */
378 enum reg_class
379 avr_regno_reg_class (int r)
381 static const enum reg_class reg_class_tab[] =
383 R0_REG,
384 /* r1 - r15 */
385 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
386 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
387 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
388 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
389 /* r16 - r23 */
390 SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
391 SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
392 /* r24, r25 */
393 ADDW_REGS, ADDW_REGS,
394 /* X: r26, 27 */
395 POINTER_X_REGS, POINTER_X_REGS,
396 /* Y: r28, r29 */
397 POINTER_Y_REGS, POINTER_Y_REGS,
398 /* Z: r30, r31 */
399 POINTER_Z_REGS, POINTER_Z_REGS,
400 /* SP: SPL, SPH */
401 STACK_REG, STACK_REG
404 if (r <= 33)
405 return reg_class_tab[r];
407 return ALL_REGS;
411 /* Implement `TARGET_SCALAR_MODE_SUPPORTED_P'. */
413 static bool
414 avr_scalar_mode_supported_p (enum machine_mode mode)
416 if (ALL_FIXED_POINT_MODE_P (mode))
417 return true;
419 if (PSImode == mode)
420 return true;
422 return default_scalar_mode_supported_p (mode);
426 /* Return TRUE if DECL is a VAR_DECL located in flash and FALSE, otherwise. */
428 static bool
429 avr_decl_flash_p (tree decl)
431 if (TREE_CODE (decl) != VAR_DECL
432 || TREE_TYPE (decl) == error_mark_node)
434 return false;
437 return !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (decl)));
441 /* Return TRUE if DECL is a VAR_DECL located in the 24-bit flash
442 address space and FALSE, otherwise. */
444 static bool
445 avr_decl_memx_p (tree decl)
447 if (TREE_CODE (decl) != VAR_DECL
448 || TREE_TYPE (decl) == error_mark_node)
450 return false;
453 return (ADDR_SPACE_MEMX == TYPE_ADDR_SPACE (TREE_TYPE (decl)));
457 /* Return TRUE if X is a MEM rtx located in flash and FALSE, otherwise. */
459 bool
460 avr_mem_flash_p (rtx x)
462 return (MEM_P (x)
463 && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x)));
467 /* Return TRUE if X is a MEM rtx located in the 24-bit flash
468 address space and FALSE, otherwise. */
470 bool
471 avr_mem_memx_p (rtx x)
473 return (MEM_P (x)
474 && ADDR_SPACE_MEMX == MEM_ADDR_SPACE (x));
478 /* A helper for the subsequent function attribute used to dig for
479 attribute 'name' in a FUNCTION_DECL or FUNCTION_TYPE */
481 static inline int
482 avr_lookup_function_attribute1 (const_tree func, const char *name)
484 if (FUNCTION_DECL == TREE_CODE (func))
486 if (NULL_TREE != lookup_attribute (name, DECL_ATTRIBUTES (func)))
488 return true;
491 func = TREE_TYPE (func);
494 gcc_assert (TREE_CODE (func) == FUNCTION_TYPE
495 || TREE_CODE (func) == METHOD_TYPE);
497 return NULL_TREE != lookup_attribute (name, TYPE_ATTRIBUTES (func));
500 /* Return nonzero if FUNC is a naked function. */
502 static int
503 avr_naked_function_p (tree func)
505 return avr_lookup_function_attribute1 (func, "naked");
508 /* Return nonzero if FUNC is an interrupt function as specified
509 by the "interrupt" attribute. */
511 static int
512 avr_interrupt_function_p (tree func)
514 return avr_lookup_function_attribute1 (func, "interrupt");
517 /* Return nonzero if FUNC is a signal function as specified
518 by the "signal" attribute. */
520 static int
521 avr_signal_function_p (tree func)
523 return avr_lookup_function_attribute1 (func, "signal");
526 /* Return nonzero if FUNC is an OS_task function. */
528 static int
529 avr_OS_task_function_p (tree func)
531 return avr_lookup_function_attribute1 (func, "OS_task");
534 /* Return nonzero if FUNC is an OS_main function. */
536 static int
537 avr_OS_main_function_p (tree func)
539 return avr_lookup_function_attribute1 (func, "OS_main");
543 /* Implement `TARGET_SET_CURRENT_FUNCTION'. */
544 /* Sanity cheching for above function attributes. */
546 static void
547 avr_set_current_function (tree decl)
549 location_t loc;
550 const char *isr;
552 if (decl == NULL_TREE
553 || current_function_decl == NULL_TREE
554 || current_function_decl == error_mark_node
555 || ! cfun->machine
556 || cfun->machine->attributes_checked_p)
557 return;
559 loc = DECL_SOURCE_LOCATION (decl);
561 cfun->machine->is_naked = avr_naked_function_p (decl);
562 cfun->machine->is_signal = avr_signal_function_p (decl);
563 cfun->machine->is_interrupt = avr_interrupt_function_p (decl);
564 cfun->machine->is_OS_task = avr_OS_task_function_p (decl);
565 cfun->machine->is_OS_main = avr_OS_main_function_p (decl);
567 isr = cfun->machine->is_interrupt ? "interrupt" : "signal";
569 /* Too much attributes make no sense as they request conflicting features. */
571 if (cfun->machine->is_OS_task + cfun->machine->is_OS_main
572 + (cfun->machine->is_signal || cfun->machine->is_interrupt) > 1)
573 error_at (loc, "function attributes %qs, %qs and %qs are mutually"
574 " exclusive", "OS_task", "OS_main", isr);
576 /* 'naked' will hide effects of 'OS_task' and 'OS_main'. */
578 if (cfun->machine->is_naked
579 && (cfun->machine->is_OS_task || cfun->machine->is_OS_main))
580 warning_at (loc, OPT_Wattributes, "function attributes %qs and %qs have"
581 " no effect on %qs function", "OS_task", "OS_main", "naked");
583 if (cfun->machine->is_interrupt || cfun->machine->is_signal)
585 tree args = TYPE_ARG_TYPES (TREE_TYPE (decl));
586 tree ret = TREE_TYPE (TREE_TYPE (decl));
587 const char *name;
589 name = DECL_ASSEMBLER_NAME_SET_P (decl)
590 ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))
591 : IDENTIFIER_POINTER (DECL_NAME (decl));
593 /* Skip a leading '*' that might still prefix the assembler name,
594 e.g. in non-LTO runs. */
596 name = default_strip_name_encoding (name);
598 /* Silently ignore 'signal' if 'interrupt' is present. AVR-LibC startet
599 using this when it switched from SIGNAL and INTERRUPT to ISR. */
601 if (cfun->machine->is_interrupt)
602 cfun->machine->is_signal = 0;
604 /* Interrupt handlers must be void __vector (void) functions. */
606 if (args && TREE_CODE (TREE_VALUE (args)) != VOID_TYPE)
607 error_at (loc, "%qs function cannot have arguments", isr);
609 if (TREE_CODE (ret) != VOID_TYPE)
610 error_at (loc, "%qs function cannot return a value", isr);
612 /* If the function has the 'signal' or 'interrupt' attribute, ensure
613 that the name of the function is "__vector_NN" so as to catch
614 when the user misspells the vector name. */
616 if (!STR_PREFIX_P (name, "__vector"))
617 warning_at (loc, 0, "%qs appears to be a misspelled %s handler",
618 name, isr);
621 /* Don't print the above diagnostics more than once. */
623 cfun->machine->attributes_checked_p = 1;
627 /* Implement `ACCUMULATE_OUTGOING_ARGS'. */
630 avr_accumulate_outgoing_args (void)
632 if (!cfun)
633 return TARGET_ACCUMULATE_OUTGOING_ARGS;
635 /* FIXME: For setjmp and in avr_builtin_setjmp_frame_value we don't know
636 what offset is correct. In some cases it is relative to
637 virtual_outgoing_args_rtx and in others it is relative to
638 virtual_stack_vars_rtx. For example code see
639 gcc.c-torture/execute/built-in-setjmp.c
640 gcc.c-torture/execute/builtins/sprintf-chk.c */
642 return (TARGET_ACCUMULATE_OUTGOING_ARGS
643 && !(cfun->calls_setjmp
644 || cfun->has_nonlocal_label));
648 /* Report contribution of accumulated outgoing arguments to stack size. */
650 static inline int
651 avr_outgoing_args_size (void)
653 return ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0;
657 /* Implement `STARTING_FRAME_OFFSET'. */
658 /* This is the offset from the frame pointer register to the first stack slot
659 that contains a variable living in the frame. */
662 avr_starting_frame_offset (void)
664 return 1 + avr_outgoing_args_size ();
668 /* Return the number of hard registers to push/pop in the prologue/epilogue
669 of the current function, and optionally store these registers in SET. */
671 static int
672 avr_regs_to_save (HARD_REG_SET *set)
674 int reg, count;
675 int int_or_sig_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
677 if (set)
678 CLEAR_HARD_REG_SET (*set);
679 count = 0;
681 /* No need to save any registers if the function never returns or
682 has the "OS_task" or "OS_main" attribute. */
684 if (TREE_THIS_VOLATILE (current_function_decl)
685 || cfun->machine->is_OS_task
686 || cfun->machine->is_OS_main)
687 return 0;
689 for (reg = 0; reg < 32; reg++)
691 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
692 any global register variables. */
694 if (fixed_regs[reg])
695 continue;
697 if ((int_or_sig_p && !crtl->is_leaf && call_used_regs[reg])
698 || (df_regs_ever_live_p (reg)
699 && (int_or_sig_p || !call_used_regs[reg])
700 /* Don't record frame pointer registers here. They are treated
701 indivitually in prologue. */
702 && !(frame_pointer_needed
703 && (reg == REG_Y || reg == (REG_Y+1)))))
705 if (set)
706 SET_HARD_REG_BIT (*set, reg);
707 count++;
710 return count;
714 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
716 static bool
717 avr_allocate_stack_slots_for_args (void)
719 return !cfun->machine->is_naked;
723 /* Return true if register FROM can be eliminated via register TO. */
725 static bool
726 avr_can_eliminate (const int from, const int to)
728 return ((from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
729 || (frame_pointer_needed && to == FRAME_POINTER_REGNUM)
730 || ((from == FRAME_POINTER_REGNUM
731 || from == FRAME_POINTER_REGNUM + 1)
732 && !frame_pointer_needed));
736 /* Implement `TARGET_WARN_FUNC_RETURN'. */
738 static bool
739 avr_warn_func_return (tree decl)
741 /* Naked functions are implemented entirely in assembly, including the
742 return sequence, so suppress warnings about this. */
744 return !avr_naked_function_p (decl);
747 /* Compute offset between arg_pointer and frame_pointer. */
750 avr_initial_elimination_offset (int from, int to)
752 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
753 return 0;
754 else
756 int offset = frame_pointer_needed ? 2 : 0;
757 int avr_pc_size = AVR_HAVE_EIJMP_EICALL ? 3 : 2;
759 offset += avr_regs_to_save (NULL);
760 return (get_frame_size () + avr_outgoing_args_size()
761 + avr_pc_size + 1 + offset);
766 /* Helper for the function below. */
768 static void
769 avr_adjust_type_node (tree *node, enum machine_mode mode, int sat_p)
771 *node = make_node (FIXED_POINT_TYPE);
772 TYPE_SATURATING (*node) = sat_p;
773 TYPE_UNSIGNED (*node) = UNSIGNED_FIXED_POINT_MODE_P (mode);
774 TYPE_IBIT (*node) = GET_MODE_IBIT (mode);
775 TYPE_FBIT (*node) = GET_MODE_FBIT (mode);
776 TYPE_PRECISION (*node) = GET_MODE_BITSIZE (mode);
777 TYPE_ALIGN (*node) = 8;
778 SET_TYPE_MODE (*node, mode);
780 layout_type (*node);
784 /* Implement `TARGET_BUILD_BUILTIN_VA_LIST'. */
786 static tree
787 avr_build_builtin_va_list (void)
789 /* avr-modes.def adjusts [U]TA to be 64-bit modes with 48 fractional bits.
790 This is more appropriate for the 8-bit machine AVR than 128-bit modes.
791 The ADJUST_IBIT/FBIT are handled in toplev:init_adjust_machine_modes()
792 which is auto-generated by genmodes, but the compiler assigns [U]DAmode
793 to the long long accum modes instead of the desired [U]TAmode.
795 Fix this now, right after node setup in tree.c:build_common_tree_nodes().
796 This must run before c-cppbuiltin.c:builtin_define_fixed_point_constants()
797 which built-in defines macros like __ULLACCUM_FBIT__ that are used by
798 libgcc to detect IBIT and FBIT. */
800 avr_adjust_type_node (&ta_type_node, TAmode, 0);
801 avr_adjust_type_node (&uta_type_node, UTAmode, 0);
802 avr_adjust_type_node (&sat_ta_type_node, TAmode, 1);
803 avr_adjust_type_node (&sat_uta_type_node, UTAmode, 1);
805 unsigned_long_long_accum_type_node = uta_type_node;
806 long_long_accum_type_node = ta_type_node;
807 sat_unsigned_long_long_accum_type_node = sat_uta_type_node;
808 sat_long_long_accum_type_node = sat_ta_type_node;
810 /* Dispatch to the default handler. */
812 return std_build_builtin_va_list ();
816 /* Implement `TARGET_BUILTIN_SETJMP_FRAME_VALUE'. */
817 /* Actual start of frame is virtual_stack_vars_rtx this is offset from
818 frame pointer by +STARTING_FRAME_OFFSET.
819 Using saved frame = virtual_stack_vars_rtx - STARTING_FRAME_OFFSET
820 avoids creating add/sub of offset in nonlocal goto and setjmp. */
822 static rtx
823 avr_builtin_setjmp_frame_value (void)
825 rtx xval = gen_reg_rtx (Pmode);
826 emit_insn (gen_subhi3 (xval, virtual_stack_vars_rtx,
827 gen_int_mode (STARTING_FRAME_OFFSET, Pmode)));
828 return xval;
832 /* Return contents of MEM at frame pointer + stack size + 1 (+2 if 3-byte PC).
833 This is return address of function. */
836 avr_return_addr_rtx (int count, rtx tem)
838 rtx r;
840 /* Can only return this function's return address. Others not supported. */
841 if (count)
842 return NULL;
844 if (AVR_3_BYTE_PC)
846 r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+2");
847 warning (0, "%<builtin_return_address%> contains only 2 bytes"
848 " of address");
850 else
851 r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+1");
853 r = gen_rtx_PLUS (Pmode, tem, r);
854 r = gen_frame_mem (Pmode, memory_address (Pmode, r));
855 r = gen_rtx_ROTATE (HImode, r, GEN_INT (8));
856 return r;
859 /* Return 1 if the function epilogue is just a single "ret". */
862 avr_simple_epilogue (void)
864 return (! frame_pointer_needed
865 && get_frame_size () == 0
866 && avr_outgoing_args_size() == 0
867 && avr_regs_to_save (NULL) == 0
868 && ! cfun->machine->is_interrupt
869 && ! cfun->machine->is_signal
870 && ! cfun->machine->is_naked
871 && ! TREE_THIS_VOLATILE (current_function_decl));
874 /* This function checks sequence of live registers. */
876 static int
877 sequent_regs_live (void)
879 int reg;
880 int live_seq = 0;
881 int cur_seq = 0;
883 for (reg = 0; reg < 18; ++reg)
885 if (fixed_regs[reg])
887 /* Don't recognize sequences that contain global register
888 variables. */
890 if (live_seq != 0)
891 return 0;
892 else
893 continue;
896 if (!call_used_regs[reg])
898 if (df_regs_ever_live_p (reg))
900 ++live_seq;
901 ++cur_seq;
903 else
904 cur_seq = 0;
908 if (!frame_pointer_needed)
910 if (df_regs_ever_live_p (REG_Y))
912 ++live_seq;
913 ++cur_seq;
915 else
916 cur_seq = 0;
918 if (df_regs_ever_live_p (REG_Y+1))
920 ++live_seq;
921 ++cur_seq;
923 else
924 cur_seq = 0;
926 else
928 cur_seq += 2;
929 live_seq += 2;
931 return (cur_seq == live_seq) ? live_seq : 0;
934 /* Obtain the length sequence of insns. */
937 get_sequence_length (rtx insns)
939 rtx insn;
940 int length;
942 for (insn = insns, length = 0; insn; insn = NEXT_INSN (insn))
943 length += get_attr_length (insn);
945 return length;
949 /* Implement `INCOMING_RETURN_ADDR_RTX'. */
952 avr_incoming_return_addr_rtx (void)
954 /* The return address is at the top of the stack. Note that the push
955 was via post-decrement, which means the actual address is off by one. */
956 return gen_frame_mem (HImode, plus_constant (Pmode, stack_pointer_rtx, 1));
959 /* Helper for expand_prologue. Emit a push of a byte register. */
961 static void
962 emit_push_byte (unsigned regno, bool frame_related_p)
964 rtx mem, reg, insn;
966 mem = gen_rtx_POST_DEC (HImode, stack_pointer_rtx);
967 mem = gen_frame_mem (QImode, mem);
968 reg = gen_rtx_REG (QImode, regno);
970 insn = emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
971 if (frame_related_p)
972 RTX_FRAME_RELATED_P (insn) = 1;
974 cfun->machine->stack_usage++;
978 /* Helper for expand_prologue. Emit a push of a SFR via tmp_reg.
979 SFR is a MEM representing the memory location of the SFR.
980 If CLR_P then clear the SFR after the push using zero_reg. */
982 static void
983 emit_push_sfr (rtx sfr, bool frame_related_p, bool clr_p)
985 rtx insn;
987 gcc_assert (MEM_P (sfr));
989 /* IN __tmp_reg__, IO(SFR) */
990 insn = emit_move_insn (tmp_reg_rtx, sfr);
991 if (frame_related_p)
992 RTX_FRAME_RELATED_P (insn) = 1;
994 /* PUSH __tmp_reg__ */
995 emit_push_byte (TMP_REGNO, frame_related_p);
997 if (clr_p)
999 /* OUT IO(SFR), __zero_reg__ */
1000 insn = emit_move_insn (sfr, const0_rtx);
1001 if (frame_related_p)
1002 RTX_FRAME_RELATED_P (insn) = 1;
1006 static void
1007 avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set)
1009 rtx insn;
1010 bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
1011 int live_seq = sequent_regs_live ();
1013 HOST_WIDE_INT size_max
1014 = (HOST_WIDE_INT) GET_MODE_MASK (AVR_HAVE_8BIT_SP ? QImode : Pmode);
1016 bool minimize = (TARGET_CALL_PROLOGUES
1017 && size < size_max
1018 && live_seq
1019 && !isr_p
1020 && !cfun->machine->is_OS_task
1021 && !cfun->machine->is_OS_main);
1023 if (minimize
1024 && (frame_pointer_needed
1025 || avr_outgoing_args_size() > 8
1026 || (AVR_2_BYTE_PC && live_seq > 6)
1027 || live_seq > 7))
1029 rtx pattern;
1030 int first_reg, reg, offset;
1032 emit_move_insn (gen_rtx_REG (HImode, REG_X),
1033 gen_int_mode (size, HImode));
1035 pattern = gen_call_prologue_saves (gen_int_mode (live_seq, HImode),
1036 gen_int_mode (live_seq+size, HImode));
1037 insn = emit_insn (pattern);
1038 RTX_FRAME_RELATED_P (insn) = 1;
1040 /* Describe the effect of the unspec_volatile call to prologue_saves.
1041 Note that this formulation assumes that add_reg_note pushes the
1042 notes to the front. Thus we build them in the reverse order of
1043 how we want dwarf2out to process them. */
1045 /* The function does always set frame_pointer_rtx, but whether that
1046 is going to be permanent in the function is frame_pointer_needed. */
1048 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1049 gen_rtx_SET (VOIDmode, (frame_pointer_needed
1050 ? frame_pointer_rtx
1051 : stack_pointer_rtx),
1052 plus_constant (Pmode, stack_pointer_rtx,
1053 -(size + live_seq))));
1055 /* Note that live_seq always contains r28+r29, but the other
1056 registers to be saved are all below 18. */
1058 first_reg = 18 - (live_seq - 2);
1060 for (reg = 29, offset = -live_seq + 1;
1061 reg >= first_reg;
1062 reg = (reg == 28 ? 17 : reg - 1), ++offset)
1064 rtx m, r;
1066 m = gen_rtx_MEM (QImode, plus_constant (Pmode, stack_pointer_rtx,
1067 offset));
1068 r = gen_rtx_REG (QImode, reg);
1069 add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (VOIDmode, m, r));
1072 cfun->machine->stack_usage += size + live_seq;
1074 else /* !minimize */
1076 int reg;
1078 for (reg = 0; reg < 32; ++reg)
1079 if (TEST_HARD_REG_BIT (set, reg))
1080 emit_push_byte (reg, true);
1082 if (frame_pointer_needed
1083 && (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main)))
1085 /* Push frame pointer. Always be consistent about the
1086 ordering of pushes -- epilogue_restores expects the
1087 register pair to be pushed low byte first. */
1089 emit_push_byte (REG_Y, true);
1090 emit_push_byte (REG_Y + 1, true);
1093 if (frame_pointer_needed
1094 && size == 0)
1096 insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1097 RTX_FRAME_RELATED_P (insn) = 1;
1100 if (size != 0)
1102 /* Creating a frame can be done by direct manipulation of the
1103 stack or via the frame pointer. These two methods are:
1104 fp = sp
1105 fp -= size
1106 sp = fp
1108 sp -= size
1109 fp = sp (*)
1110 the optimum method depends on function type, stack and
1111 frame size. To avoid a complex logic, both methods are
1112 tested and shortest is selected.
1114 There is also the case where SIZE != 0 and no frame pointer is
1115 needed; this can occur if ACCUMULATE_OUTGOING_ARGS is on.
1116 In that case, insn (*) is not needed in that case.
1117 We use the X register as scratch. This is save because in X
1118 is call-clobbered.
1119 In an interrupt routine, the case of SIZE != 0 together with
1120 !frame_pointer_needed can only occur if the function is not a
1121 leaf function and thus X has already been saved. */
1123 int irq_state = -1;
1124 HOST_WIDE_INT size_cfa = size, neg_size;
1125 rtx fp_plus_insns, fp, my_fp;
1127 gcc_assert (frame_pointer_needed
1128 || !isr_p
1129 || !crtl->is_leaf);
1131 fp = my_fp = (frame_pointer_needed
1132 ? frame_pointer_rtx
1133 : gen_rtx_REG (Pmode, REG_X));
1135 if (AVR_HAVE_8BIT_SP)
1137 /* The high byte (r29) does not change:
1138 Prefer SUBI (1 cycle) over SBIW (2 cycles, same size). */
1140 my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
1143 /* Cut down size and avoid size = 0 so that we don't run
1144 into ICE like PR52488 in the remainder. */
1146 if (size > size_max)
1148 /* Don't error so that insane code from newlib still compiles
1149 and does not break building newlib. As PR51345 is implemented
1150 now, there are multilib variants with -msp8.
1152 If user wants sanity checks he can use -Wstack-usage=
1153 or similar options.
1155 For CFA we emit the original, non-saturated size so that
1156 the generic machinery is aware of the real stack usage and
1157 will print the above diagnostic as expected. */
1159 size = size_max;
1162 size = trunc_int_for_mode (size, GET_MODE (my_fp));
1163 neg_size = trunc_int_for_mode (-size, GET_MODE (my_fp));
1165 /************ Method 1: Adjust frame pointer ************/
1167 start_sequence ();
1169 /* Normally, the dwarf2out frame-related-expr interpreter does
1170 not expect to have the CFA change once the frame pointer is
1171 set up. Thus, we avoid marking the move insn below and
1172 instead indicate that the entire operation is complete after
1173 the frame pointer subtraction is done. */
1175 insn = emit_move_insn (fp, stack_pointer_rtx);
1176 if (frame_pointer_needed)
1178 RTX_FRAME_RELATED_P (insn) = 1;
1179 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1180 gen_rtx_SET (VOIDmode, fp, stack_pointer_rtx));
1183 insn = emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp),
1184 my_fp, neg_size));
1186 if (frame_pointer_needed)
1188 RTX_FRAME_RELATED_P (insn) = 1;
1189 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1190 gen_rtx_SET (VOIDmode, fp,
1191 plus_constant (Pmode, fp,
1192 -size_cfa)));
1195 /* Copy to stack pointer. Note that since we've already
1196 changed the CFA to the frame pointer this operation
1197 need not be annotated if frame pointer is needed.
1198 Always move through unspec, see PR50063.
1199 For meaning of irq_state see movhi_sp_r insn. */
1201 if (cfun->machine->is_interrupt)
1202 irq_state = 1;
1204 if (TARGET_NO_INTERRUPTS
1205 || cfun->machine->is_signal
1206 || cfun->machine->is_OS_main)
1207 irq_state = 0;
1209 if (AVR_HAVE_8BIT_SP)
1210 irq_state = 2;
1212 insn = emit_insn (gen_movhi_sp_r (stack_pointer_rtx,
1213 fp, GEN_INT (irq_state)));
1214 if (!frame_pointer_needed)
1216 RTX_FRAME_RELATED_P (insn) = 1;
1217 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1218 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
1219 plus_constant (Pmode,
1220 stack_pointer_rtx,
1221 -size_cfa)));
1224 fp_plus_insns = get_insns ();
1225 end_sequence ();
1227 /************ Method 2: Adjust Stack pointer ************/
1229 /* Stack adjustment by means of RCALL . and/or PUSH __TMP_REG__
1230 can only handle specific offsets. */
1232 if (avr_sp_immediate_operand (gen_int_mode (-size, HImode), HImode))
1234 rtx sp_plus_insns;
1236 start_sequence ();
1238 insn = emit_move_insn (stack_pointer_rtx,
1239 plus_constant (Pmode, stack_pointer_rtx,
1240 -size));
1241 RTX_FRAME_RELATED_P (insn) = 1;
1242 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1243 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
1244 plus_constant (Pmode,
1245 stack_pointer_rtx,
1246 -size_cfa)));
1247 if (frame_pointer_needed)
1249 insn = emit_move_insn (fp, stack_pointer_rtx);
1250 RTX_FRAME_RELATED_P (insn) = 1;
1253 sp_plus_insns = get_insns ();
1254 end_sequence ();
1256 /************ Use shortest method ************/
1258 emit_insn (get_sequence_length (sp_plus_insns)
1259 < get_sequence_length (fp_plus_insns)
1260 ? sp_plus_insns
1261 : fp_plus_insns);
1263 else
1265 emit_insn (fp_plus_insns);
1268 cfun->machine->stack_usage += size_cfa;
1269 } /* !minimize && size != 0 */
1270 } /* !minimize */
1274 /* Output function prologue. */
1276 void
1277 avr_expand_prologue (void)
1279 HARD_REG_SET set;
1280 HOST_WIDE_INT size;
1282 size = get_frame_size() + avr_outgoing_args_size();
1284 cfun->machine->stack_usage = 0;
1286 /* Prologue: naked. */
1287 if (cfun->machine->is_naked)
1289 return;
1292 avr_regs_to_save (&set);
1294 if (cfun->machine->is_interrupt || cfun->machine->is_signal)
1296 /* Enable interrupts. */
1297 if (cfun->machine->is_interrupt)
1298 emit_insn (gen_enable_interrupt ());
1300 /* Push zero reg. */
1301 emit_push_byte (ZERO_REGNO, true);
1303 /* Push tmp reg. */
1304 emit_push_byte (TMP_REGNO, true);
1306 /* Push SREG. */
1307 /* ??? There's no dwarf2 column reserved for SREG. */
1308 emit_push_sfr (sreg_rtx, false, false /* clr */);
1310 /* Clear zero reg. */
1311 emit_move_insn (zero_reg_rtx, const0_rtx);
1313 /* Prevent any attempt to delete the setting of ZERO_REG! */
1314 emit_use (zero_reg_rtx);
1316 /* Push and clear RAMPD/X/Y/Z if present and low-part register is used.
1317 ??? There are no dwarf2 columns reserved for RAMPD/X/Y/Z. */
1319 if (AVR_HAVE_RAMPD)
1320 emit_push_sfr (rampd_rtx, false /* frame-related */, true /* clr */);
1322 if (AVR_HAVE_RAMPX
1323 && TEST_HARD_REG_BIT (set, REG_X)
1324 && TEST_HARD_REG_BIT (set, REG_X + 1))
1326 emit_push_sfr (rampx_rtx, false /* frame-related */, true /* clr */);
1329 if (AVR_HAVE_RAMPY
1330 && (frame_pointer_needed
1331 || (TEST_HARD_REG_BIT (set, REG_Y)
1332 && TEST_HARD_REG_BIT (set, REG_Y + 1))))
1334 emit_push_sfr (rampy_rtx, false /* frame-related */, true /* clr */);
1337 if (AVR_HAVE_RAMPZ
1338 && TEST_HARD_REG_BIT (set, REG_Z)
1339 && TEST_HARD_REG_BIT (set, REG_Z + 1))
1341 emit_push_sfr (rampz_rtx, false /* frame-related */, AVR_HAVE_RAMPD);
1343 } /* is_interrupt is_signal */
1345 avr_prologue_setup_frame (size, set);
1347 if (flag_stack_usage_info)
1348 current_function_static_stack_size = cfun->machine->stack_usage;
1352 /* Implement `TARGET_ASM_FUNCTION_END_PROLOGUE'. */
1353 /* Output summary at end of function prologue. */
1355 static void
1356 avr_asm_function_end_prologue (FILE *file)
1358 if (cfun->machine->is_naked)
1360 fputs ("/* prologue: naked */\n", file);
1362 else
1364 if (cfun->machine->is_interrupt)
1366 fputs ("/* prologue: Interrupt */\n", file);
1368 else if (cfun->machine->is_signal)
1370 fputs ("/* prologue: Signal */\n", file);
1372 else
1373 fputs ("/* prologue: function */\n", file);
1376 if (ACCUMULATE_OUTGOING_ARGS)
1377 fprintf (file, "/* outgoing args size = %d */\n",
1378 avr_outgoing_args_size());
1380 fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n",
1381 get_frame_size());
1382 fprintf (file, "/* stack size = %d */\n",
1383 cfun->machine->stack_usage);
1384 /* Create symbol stack offset here so all functions have it. Add 1 to stack
1385 usage for offset so that SP + .L__stack_offset = return address. */
1386 fprintf (file, ".L__stack_usage = %d\n", cfun->machine->stack_usage);
1390 /* Implement `EPILOGUE_USES'. */
1393 avr_epilogue_uses (int regno ATTRIBUTE_UNUSED)
1395 if (reload_completed
1396 && cfun->machine
1397 && (cfun->machine->is_interrupt || cfun->machine->is_signal))
1398 return 1;
1399 return 0;
1402 /* Helper for avr_expand_epilogue. Emit a pop of a byte register. */
1404 static void
1405 emit_pop_byte (unsigned regno)
1407 rtx mem, reg;
1409 mem = gen_rtx_PRE_INC (HImode, stack_pointer_rtx);
1410 mem = gen_frame_mem (QImode, mem);
1411 reg = gen_rtx_REG (QImode, regno);
1413 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
1416 /* Output RTL epilogue. */
1418 void
1419 avr_expand_epilogue (bool sibcall_p)
1421 int reg;
1422 int live_seq;
1423 HARD_REG_SET set;
1424 int minimize;
1425 HOST_WIDE_INT size;
1426 bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
1428 size = get_frame_size() + avr_outgoing_args_size();
1430 /* epilogue: naked */
1431 if (cfun->machine->is_naked)
1433 gcc_assert (!sibcall_p);
1435 emit_jump_insn (gen_return ());
1436 return;
1439 avr_regs_to_save (&set);
1440 live_seq = sequent_regs_live ();
1442 minimize = (TARGET_CALL_PROLOGUES
1443 && live_seq
1444 && !isr_p
1445 && !cfun->machine->is_OS_task
1446 && !cfun->machine->is_OS_main);
1448 if (minimize
1449 && (live_seq > 4
1450 || frame_pointer_needed
1451 || size))
1453 /* Get rid of frame. */
1455 if (!frame_pointer_needed)
1457 emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1460 if (size)
1462 emit_move_insn (frame_pointer_rtx,
1463 plus_constant (Pmode, frame_pointer_rtx, size));
1466 emit_insn (gen_epilogue_restores (gen_int_mode (live_seq, HImode)));
1467 return;
1470 if (size)
1472 /* Try two methods to adjust stack and select shortest. */
1474 int irq_state = -1;
1475 rtx fp, my_fp;
1476 rtx fp_plus_insns;
1477 HOST_WIDE_INT size_max;
1479 gcc_assert (frame_pointer_needed
1480 || !isr_p
1481 || !crtl->is_leaf);
1483 fp = my_fp = (frame_pointer_needed
1484 ? frame_pointer_rtx
1485 : gen_rtx_REG (Pmode, REG_X));
1487 if (AVR_HAVE_8BIT_SP)
1489 /* The high byte (r29) does not change:
1490 Prefer SUBI (1 cycle) over SBIW (2 cycles). */
1492 my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
1495 /* For rationale see comment in prologue generation. */
1497 size_max = (HOST_WIDE_INT) GET_MODE_MASK (GET_MODE (my_fp));
1498 if (size > size_max)
1499 size = size_max;
1500 size = trunc_int_for_mode (size, GET_MODE (my_fp));
1502 /********** Method 1: Adjust fp register **********/
1504 start_sequence ();
1506 if (!frame_pointer_needed)
1507 emit_move_insn (fp, stack_pointer_rtx);
1509 emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp), my_fp, size));
1511 /* Copy to stack pointer. */
1513 if (TARGET_NO_INTERRUPTS)
1514 irq_state = 0;
1516 if (AVR_HAVE_8BIT_SP)
1517 irq_state = 2;
1519 emit_insn (gen_movhi_sp_r (stack_pointer_rtx, fp,
1520 GEN_INT (irq_state)));
1522 fp_plus_insns = get_insns ();
1523 end_sequence ();
1525 /********** Method 2: Adjust Stack pointer **********/
1527 if (avr_sp_immediate_operand (gen_int_mode (size, HImode), HImode))
1529 rtx sp_plus_insns;
1531 start_sequence ();
1533 emit_move_insn (stack_pointer_rtx,
1534 plus_constant (Pmode, stack_pointer_rtx, size));
1536 sp_plus_insns = get_insns ();
1537 end_sequence ();
1539 /************ Use shortest method ************/
1541 emit_insn (get_sequence_length (sp_plus_insns)
1542 < get_sequence_length (fp_plus_insns)
1543 ? sp_plus_insns
1544 : fp_plus_insns);
1546 else
1547 emit_insn (fp_plus_insns);
1548 } /* size != 0 */
1550 if (frame_pointer_needed
1551 && !(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
1553 /* Restore previous frame_pointer. See avr_expand_prologue for
1554 rationale for not using pophi. */
1556 emit_pop_byte (REG_Y + 1);
1557 emit_pop_byte (REG_Y);
1560 /* Restore used registers. */
1562 for (reg = 31; reg >= 0; --reg)
1563 if (TEST_HARD_REG_BIT (set, reg))
1564 emit_pop_byte (reg);
1566 if (isr_p)
1568 /* Restore RAMPZ/Y/X/D using tmp_reg as scratch.
1569 The conditions to restore them must be tha same as in prologue. */
1571 if (AVR_HAVE_RAMPZ
1572 && TEST_HARD_REG_BIT (set, REG_Z)
1573 && TEST_HARD_REG_BIT (set, REG_Z + 1))
1575 emit_pop_byte (TMP_REGNO);
1576 emit_move_insn (rampz_rtx, tmp_reg_rtx);
1579 if (AVR_HAVE_RAMPY
1580 && (frame_pointer_needed
1581 || (TEST_HARD_REG_BIT (set, REG_Y)
1582 && TEST_HARD_REG_BIT (set, REG_Y + 1))))
1584 emit_pop_byte (TMP_REGNO);
1585 emit_move_insn (rampy_rtx, tmp_reg_rtx);
1588 if (AVR_HAVE_RAMPX
1589 && TEST_HARD_REG_BIT (set, REG_X)
1590 && TEST_HARD_REG_BIT (set, REG_X + 1))
1592 emit_pop_byte (TMP_REGNO);
1593 emit_move_insn (rampx_rtx, tmp_reg_rtx);
1596 if (AVR_HAVE_RAMPD)
1598 emit_pop_byte (TMP_REGNO);
1599 emit_move_insn (rampd_rtx, tmp_reg_rtx);
1602 /* Restore SREG using tmp_reg as scratch. */
1604 emit_pop_byte (TMP_REGNO);
1605 emit_move_insn (sreg_rtx, tmp_reg_rtx);
1607 /* Restore tmp REG. */
1608 emit_pop_byte (TMP_REGNO);
1610 /* Restore zero REG. */
1611 emit_pop_byte (ZERO_REGNO);
1614 if (!sibcall_p)
1615 emit_jump_insn (gen_return ());
1619 /* Implement `TARGET_ASM_FUNCTION_BEGIN_EPILOGUE'. */
1621 static void
1622 avr_asm_function_begin_epilogue (FILE *file)
1624 fprintf (file, "/* epilogue start */\n");
1628 /* Implement `TARGET_CANNOT_MODITY_JUMPS_P'. */
1630 static bool
1631 avr_cannot_modify_jumps_p (void)
1634 /* Naked Functions must not have any instructions after
1635 their epilogue, see PR42240 */
1637 if (reload_completed
1638 && cfun->machine
1639 && cfun->machine->is_naked)
1641 return true;
1644 return false;
1648 /* Implement `TARGET_MODE_DEPENDENT_ADDRESS_P'. */
1650 static bool
1651 avr_mode_dependent_address_p (const_rtx addr ATTRIBUTE_UNUSED, addr_space_t as)
1653 /* FIXME: Non-generic addresses are not mode-dependent in themselves.
1654 This hook just serves to hack around PR rtl-optimization/52543 by
1655 claiming that non-generic addresses were mode-dependent so that
1656 lower-subreg.c will skip these addresses. lower-subreg.c sets up fake
1657 RTXes to probe SET and MEM costs and assumes that MEM is always in the
1658 generic address space which is not true. */
1660 return !ADDR_SPACE_GENERIC_P (as);
1664 /* Helper function for `avr_legitimate_address_p'. */
1666 static inline bool
1667 avr_reg_ok_for_addr_p (rtx reg, addr_space_t as,
1668 RTX_CODE outer_code, bool strict)
1670 return (REG_P (reg)
1671 && (avr_regno_mode_code_ok_for_base_p (REGNO (reg), QImode,
1672 as, outer_code, UNKNOWN)
1673 || (!strict
1674 && REGNO (reg) >= FIRST_PSEUDO_REGISTER)));
1678 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
1679 machine for a memory operand of mode MODE. */
1681 static bool
1682 avr_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
1684 bool ok = CONSTANT_ADDRESS_P (x);
1686 switch (GET_CODE (x))
1688 case REG:
1689 ok = avr_reg_ok_for_addr_p (x, ADDR_SPACE_GENERIC,
1690 MEM, strict);
1692 if (strict
1693 && GET_MODE_SIZE (mode) > 4
1694 && REG_X == REGNO (x))
1696 ok = false;
1698 break;
1700 case POST_INC:
1701 case PRE_DEC:
1702 ok = avr_reg_ok_for_addr_p (XEXP (x, 0), ADDR_SPACE_GENERIC,
1703 GET_CODE (x), strict);
1704 break;
1706 case PLUS:
1708 rtx reg = XEXP (x, 0);
1709 rtx op1 = XEXP (x, 1);
1711 if (REG_P (reg)
1712 && CONST_INT_P (op1)
1713 && INTVAL (op1) >= 0)
1715 bool fit = IN_RANGE (INTVAL (op1), 0, MAX_LD_OFFSET (mode));
1717 if (fit)
1719 ok = (! strict
1720 || avr_reg_ok_for_addr_p (reg, ADDR_SPACE_GENERIC,
1721 PLUS, strict));
1723 if (reg == frame_pointer_rtx
1724 || reg == arg_pointer_rtx)
1726 ok = true;
1729 else if (frame_pointer_needed
1730 && reg == frame_pointer_rtx)
1732 ok = true;
1736 break;
1738 default:
1739 break;
1742 if (avr_log.legitimate_address_p)
1744 avr_edump ("\n%?: ret=%d, mode=%m strict=%d "
1745 "reload_completed=%d reload_in_progress=%d %s:",
1746 ok, mode, strict, reload_completed, reload_in_progress,
1747 reg_renumber ? "(reg_renumber)" : "");
1749 if (GET_CODE (x) == PLUS
1750 && REG_P (XEXP (x, 0))
1751 && CONST_INT_P (XEXP (x, 1))
1752 && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
1753 && reg_renumber)
1755 avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
1756 true_regnum (XEXP (x, 0)));
1759 avr_edump ("\n%r\n", x);
1762 return ok;
1766 /* Former implementation of TARGET_LEGITIMIZE_ADDRESS,
1767 now only a helper for avr_addr_space_legitimize_address. */
1768 /* Attempts to replace X with a valid
1769 memory address for an operand of mode MODE */
1771 static rtx
1772 avr_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
1774 bool big_offset_p = false;
1776 x = oldx;
1778 if (GET_CODE (oldx) == PLUS
1779 && REG_P (XEXP (oldx, 0)))
1781 if (REG_P (XEXP (oldx, 1)))
1782 x = force_reg (GET_MODE (oldx), oldx);
1783 else if (CONST_INT_P (XEXP (oldx, 1)))
1785 int offs = INTVAL (XEXP (oldx, 1));
1786 if (frame_pointer_rtx != XEXP (oldx, 0)
1787 && offs > MAX_LD_OFFSET (mode))
1789 big_offset_p = true;
1790 x = force_reg (GET_MODE (oldx), oldx);
1795 if (avr_log.legitimize_address)
1797 avr_edump ("\n%?: mode=%m\n %r\n", mode, oldx);
1799 if (x != oldx)
1800 avr_edump (" %s --> %r\n", big_offset_p ? "(big offset)" : "", x);
1803 return x;
1807 /* Implement `LEGITIMIZE_RELOAD_ADDRESS'. */
1808 /* This will allow register R26/27 to be used where it is no worse than normal
1809 base pointers R28/29 or R30/31. For example, if base offset is greater
1810 than 63 bytes or for R++ or --R addressing. */
1813 avr_legitimize_reload_address (rtx *px, enum machine_mode mode,
1814 int opnum, int type, int addr_type,
1815 int ind_levels ATTRIBUTE_UNUSED,
1816 rtx (*mk_memloc)(rtx,int))
1818 rtx x = *px;
1820 if (avr_log.legitimize_reload_address)
1821 avr_edump ("\n%?:%m %r\n", mode, x);
1823 if (1 && (GET_CODE (x) == POST_INC
1824 || GET_CODE (x) == PRE_DEC))
1826 push_reload (XEXP (x, 0), XEXP (x, 0), &XEXP (x, 0), &XEXP (x, 0),
1827 POINTER_REGS, GET_MODE (x), GET_MODE (x), 0, 0,
1828 opnum, RELOAD_OTHER);
1830 if (avr_log.legitimize_reload_address)
1831 avr_edump (" RCLASS.1 = %R\n IN = %r\n OUT = %r\n",
1832 POINTER_REGS, XEXP (x, 0), XEXP (x, 0));
1834 return x;
1837 if (GET_CODE (x) == PLUS
1838 && REG_P (XEXP (x, 0))
1839 && 0 == reg_equiv_constant (REGNO (XEXP (x, 0)))
1840 && CONST_INT_P (XEXP (x, 1))
1841 && INTVAL (XEXP (x, 1)) >= 1)
1843 bool fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
1845 if (fit)
1847 if (reg_equiv_address (REGNO (XEXP (x, 0))) != 0)
1849 int regno = REGNO (XEXP (x, 0));
1850 rtx mem = mk_memloc (x, regno);
1852 push_reload (XEXP (mem, 0), NULL_RTX, &XEXP (mem, 0), NULL,
1853 POINTER_REGS, Pmode, VOIDmode, 0, 0,
1854 1, (enum reload_type) addr_type);
1856 if (avr_log.legitimize_reload_address)
1857 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
1858 POINTER_REGS, XEXP (mem, 0), NULL_RTX);
1860 push_reload (mem, NULL_RTX, &XEXP (x, 0), NULL,
1861 BASE_POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
1862 opnum, (enum reload_type) type);
1864 if (avr_log.legitimize_reload_address)
1865 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
1866 BASE_POINTER_REGS, mem, NULL_RTX);
1868 return x;
1871 else if (! (frame_pointer_needed
1872 && XEXP (x, 0) == frame_pointer_rtx))
1874 push_reload (x, NULL_RTX, px, NULL,
1875 POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
1876 opnum, (enum reload_type) type);
1878 if (avr_log.legitimize_reload_address)
1879 avr_edump (" RCLASS.3 = %R\n IN = %r\n OUT = %r\n",
1880 POINTER_REGS, x, NULL_RTX);
1882 return x;
1886 return NULL_RTX;
1890 /* Implement `TARGET_SECONDARY_RELOAD' */
1892 static reg_class_t
1893 avr_secondary_reload (bool in_p, rtx x,
1894 reg_class_t reload_class ATTRIBUTE_UNUSED,
1895 enum machine_mode mode, secondary_reload_info *sri)
1897 if (in_p
1898 && MEM_P (x)
1899 && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x))
1900 && ADDR_SPACE_MEMX != MEM_ADDR_SPACE (x))
1902 /* For the non-generic 16-bit spaces we need a d-class scratch. */
1904 switch (mode)
1906 default:
1907 gcc_unreachable();
1909 case QImode: sri->icode = CODE_FOR_reload_inqi; break;
1910 case QQmode: sri->icode = CODE_FOR_reload_inqq; break;
1911 case UQQmode: sri->icode = CODE_FOR_reload_inuqq; break;
1913 case HImode: sri->icode = CODE_FOR_reload_inhi; break;
1914 case HQmode: sri->icode = CODE_FOR_reload_inhq; break;
1915 case HAmode: sri->icode = CODE_FOR_reload_inha; break;
1916 case UHQmode: sri->icode = CODE_FOR_reload_inuhq; break;
1917 case UHAmode: sri->icode = CODE_FOR_reload_inuha; break;
1919 case PSImode: sri->icode = CODE_FOR_reload_inpsi; break;
1921 case SImode: sri->icode = CODE_FOR_reload_insi; break;
1922 case SFmode: sri->icode = CODE_FOR_reload_insf; break;
1923 case SQmode: sri->icode = CODE_FOR_reload_insq; break;
1924 case SAmode: sri->icode = CODE_FOR_reload_insa; break;
1925 case USQmode: sri->icode = CODE_FOR_reload_inusq; break;
1926 case USAmode: sri->icode = CODE_FOR_reload_inusa; break;
1930 return NO_REGS;
1934 /* Helper function to print assembler resp. track instruction
1935 sequence lengths. Always return "".
1937 If PLEN == NULL:
1938 Output assembler code from template TPL with operands supplied
1939 by OPERANDS. This is just forwarding to output_asm_insn.
1941 If PLEN != NULL:
1942 If N_WORDS >= 0 Add N_WORDS to *PLEN.
1943 If N_WORDS < 0 Set *PLEN to -N_WORDS.
1944 Don't output anything.
1947 static const char*
1948 avr_asm_len (const char* tpl, rtx* operands, int* plen, int n_words)
1950 if (NULL == plen)
1952 output_asm_insn (tpl, operands);
1954 else
1956 if (n_words < 0)
1957 *plen = -n_words;
1958 else
1959 *plen += n_words;
1962 return "";
1966 /* Return a pointer register name as a string. */
1968 static const char*
1969 ptrreg_to_str (int regno)
1971 switch (regno)
1973 case REG_X: return "X";
1974 case REG_Y: return "Y";
1975 case REG_Z: return "Z";
1976 default:
1977 output_operand_lossage ("address operand requires constraint for"
1978 " X, Y, or Z register");
1980 return NULL;
1983 /* Return the condition name as a string.
1984 Used in conditional jump constructing */
1986 static const char*
1987 cond_string (enum rtx_code code)
1989 switch (code)
1991 case NE:
1992 return "ne";
1993 case EQ:
1994 return "eq";
1995 case GE:
1996 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1997 return "pl";
1998 else
1999 return "ge";
2000 case LT:
2001 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2002 return "mi";
2003 else
2004 return "lt";
2005 case GEU:
2006 return "sh";
2007 case LTU:
2008 return "lo";
2009 default:
2010 gcc_unreachable ();
2013 return "";
2017 /* Implement `TARGET_PRINT_OPERAND_ADDRESS'. */
2018 /* Output ADDR to FILE as address. */
2020 static void
2021 avr_print_operand_address (FILE *file, rtx addr)
2023 switch (GET_CODE (addr))
2025 case REG:
2026 fprintf (file, ptrreg_to_str (REGNO (addr)));
2027 break;
2029 case PRE_DEC:
2030 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
2031 break;
2033 case POST_INC:
2034 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
2035 break;
2037 default:
2038 if (CONSTANT_ADDRESS_P (addr)
2039 && text_segment_operand (addr, VOIDmode))
2041 rtx x = addr;
2042 if (GET_CODE (x) == CONST)
2043 x = XEXP (x, 0);
2044 if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x,1)) == CONST_INT)
2046 /* Assembler gs() will implant word address. Make offset
2047 a byte offset inside gs() for assembler. This is
2048 needed because the more logical (constant+gs(sym)) is not
2049 accepted by gas. For 128K and smaller devices this is ok.
2050 For large devices it will create a trampoline to offset
2051 from symbol which may not be what the user really wanted. */
2053 fprintf (file, "gs(");
2054 output_addr_const (file, XEXP (x,0));
2055 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC ")",
2056 2 * INTVAL (XEXP (x, 1)));
2057 if (AVR_3_BYTE_PC)
2058 if (warning (0, "pointer offset from symbol maybe incorrect"))
2060 output_addr_const (stderr, addr);
2061 fprintf(stderr,"\n");
2064 else
2066 fprintf (file, "gs(");
2067 output_addr_const (file, addr);
2068 fprintf (file, ")");
2071 else
2072 output_addr_const (file, addr);
2077 /* Implement `TARGET_PRINT_OPERAND_PUNCT_VALID_P'. */
2079 static bool
2080 avr_print_operand_punct_valid_p (unsigned char code)
2082 return code == '~' || code == '!';
2086 /* Implement `TARGET_PRINT_OPERAND'. */
2087 /* Output X as assembler operand to file FILE.
2088 For a description of supported %-codes, see top of avr.md. */
2090 static void
2091 avr_print_operand (FILE *file, rtx x, int code)
2093 int abcd = 0;
2095 if (code >= 'A' && code <= 'D')
2096 abcd = code - 'A';
2098 if (code == '~')
2100 if (!AVR_HAVE_JMP_CALL)
2101 fputc ('r', file);
2103 else if (code == '!')
2105 if (AVR_HAVE_EIJMP_EICALL)
2106 fputc ('e', file);
2108 else if (code == 't'
2109 || code == 'T')
2111 static int t_regno = -1;
2112 static int t_nbits = -1;
2114 if (REG_P (x) && t_regno < 0 && code == 'T')
2116 t_regno = REGNO (x);
2117 t_nbits = GET_MODE_BITSIZE (GET_MODE (x));
2119 else if (CONST_INT_P (x) && t_regno >= 0
2120 && IN_RANGE (INTVAL (x), 0, t_nbits - 1))
2122 int bpos = INTVAL (x);
2124 fprintf (file, "%s", reg_names[t_regno + bpos / 8]);
2125 if (code == 'T')
2126 fprintf (file, ",%d", bpos % 8);
2128 t_regno = -1;
2130 else
2131 fatal_insn ("operands to %T/%t must be reg + const_int:", x);
2133 else if (REG_P (x))
2135 if (x == zero_reg_rtx)
2136 fprintf (file, "__zero_reg__");
2137 else if (code == 'r' && REGNO (x) < 32)
2138 fprintf (file, "%d", (int) REGNO (x));
2139 else
2140 fprintf (file, reg_names[REGNO (x) + abcd]);
2142 else if (CONST_INT_P (x))
2144 HOST_WIDE_INT ival = INTVAL (x);
2146 if ('i' != code)
2147 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival + abcd);
2148 else if (low_io_address_operand (x, VOIDmode)
2149 || high_io_address_operand (x, VOIDmode))
2151 if (AVR_HAVE_RAMPZ && ival == avr_addr.rampz)
2152 fprintf (file, "__RAMPZ__");
2153 else if (AVR_HAVE_RAMPY && ival == avr_addr.rampy)
2154 fprintf (file, "__RAMPY__");
2155 else if (AVR_HAVE_RAMPX && ival == avr_addr.rampx)
2156 fprintf (file, "__RAMPX__");
2157 else if (AVR_HAVE_RAMPD && ival == avr_addr.rampd)
2158 fprintf (file, "__RAMPD__");
2159 else if (AVR_XMEGA && ival == avr_addr.ccp)
2160 fprintf (file, "__CCP__");
2161 else if (ival == avr_addr.sreg) fprintf (file, "__SREG__");
2162 else if (ival == avr_addr.sp_l) fprintf (file, "__SP_L__");
2163 else if (ival == avr_addr.sp_h) fprintf (file, "__SP_H__");
2164 else
2166 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
2167 ival - avr_current_arch->sfr_offset);
2170 else
2171 fatal_insn ("bad address, not an I/O address:", x);
2173 else if (MEM_P (x))
2175 rtx addr = XEXP (x, 0);
2177 if (code == 'm')
2179 if (!CONSTANT_P (addr))
2180 fatal_insn ("bad address, not a constant:", addr);
2181 /* Assembler template with m-code is data - not progmem section */
2182 if (text_segment_operand (addr, VOIDmode))
2183 if (warning (0, "accessing data memory with"
2184 " program memory address"))
2186 output_addr_const (stderr, addr);
2187 fprintf(stderr,"\n");
2189 output_addr_const (file, addr);
2191 else if (code == 'i')
2193 avr_print_operand (file, addr, 'i');
2195 else if (code == 'o')
2197 if (GET_CODE (addr) != PLUS)
2198 fatal_insn ("bad address, not (reg+disp):", addr);
2200 avr_print_operand (file, XEXP (addr, 1), 0);
2202 else if (code == 'p' || code == 'r')
2204 if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
2205 fatal_insn ("bad address, not post_inc or pre_dec:", addr);
2207 if (code == 'p')
2208 avr_print_operand_address (file, XEXP (addr, 0)); /* X, Y, Z */
2209 else
2210 avr_print_operand (file, XEXP (addr, 0), 0); /* r26, r28, r30 */
2212 else if (GET_CODE (addr) == PLUS)
2214 avr_print_operand_address (file, XEXP (addr,0));
2215 if (REGNO (XEXP (addr, 0)) == REG_X)
2216 fatal_insn ("internal compiler error. Bad address:"
2217 ,addr);
2218 fputc ('+', file);
2219 avr_print_operand (file, XEXP (addr,1), code);
2221 else
2222 avr_print_operand_address (file, addr);
2224 else if (code == 'i')
2226 fatal_insn ("bad address, not an I/O address:", x);
2228 else if (code == 'x')
2230 /* Constant progmem address - like used in jmp or call */
2231 if (0 == text_segment_operand (x, VOIDmode))
2232 if (warning (0, "accessing program memory"
2233 " with data memory address"))
2235 output_addr_const (stderr, x);
2236 fprintf(stderr,"\n");
2238 /* Use normal symbol for direct address no linker trampoline needed */
2239 output_addr_const (file, x);
2241 else if (CONST_FIXED_P (x))
2243 HOST_WIDE_INT ival = INTVAL (avr_to_int_mode (x));
2244 if (code != 0)
2245 output_operand_lossage ("Unsupported code '%c' for fixed-point:",
2246 code);
2247 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival);
2249 else if (GET_CODE (x) == CONST_DOUBLE)
2251 long val;
2252 REAL_VALUE_TYPE rv;
2253 if (GET_MODE (x) != SFmode)
2254 fatal_insn ("internal compiler error. Unknown mode:", x);
2255 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
2256 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
2257 fprintf (file, "0x%lx", val);
2259 else if (GET_CODE (x) == CONST_STRING)
2260 fputs (XSTR (x, 0), file);
2261 else if (code == 'j')
2262 fputs (cond_string (GET_CODE (x)), file);
2263 else if (code == 'k')
2264 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
2265 else
2266 avr_print_operand_address (file, x);
2270 /* Worker function for `NOTICE_UPDATE_CC'. */
2271 /* Update the condition code in the INSN. */
2273 void
2274 avr_notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
2276 rtx set;
2277 enum attr_cc cc = get_attr_cc (insn);
2279 switch (cc)
2281 default:
2282 break;
2284 case CC_PLUS:
2285 case CC_LDI:
2287 rtx *op = recog_data.operand;
2288 int len_dummy, icc;
2290 /* Extract insn's operands. */
2291 extract_constrain_insn_cached (insn);
2293 switch (cc)
2295 default:
2296 gcc_unreachable();
2298 case CC_PLUS:
2299 avr_out_plus (insn, op, &len_dummy, &icc);
2300 cc = (enum attr_cc) icc;
2301 break;
2303 case CC_LDI:
2305 cc = (op[1] == CONST0_RTX (GET_MODE (op[0]))
2306 && reg_overlap_mentioned_p (op[0], zero_reg_rtx))
2307 /* Loading zero-reg with 0 uses CLR and thus clobbers cc0. */
2308 ? CC_CLOBBER
2309 /* Any other "r,rL" combination does not alter cc0. */
2310 : CC_NONE;
2312 break;
2313 } /* inner switch */
2315 break;
2317 } /* outer swicth */
2319 switch (cc)
2321 default:
2322 /* Special values like CC_OUT_PLUS from above have been
2323 mapped to "standard" CC_* values so we never come here. */
2325 gcc_unreachable();
2326 break;
2328 case CC_NONE:
2329 /* Insn does not affect CC at all. */
2330 break;
2332 case CC_SET_N:
2333 CC_STATUS_INIT;
2334 break;
2336 case CC_SET_ZN:
2337 set = single_set (insn);
2338 CC_STATUS_INIT;
2339 if (set)
2341 cc_status.flags |= CC_NO_OVERFLOW;
2342 cc_status.value1 = SET_DEST (set);
2344 break;
2346 case CC_SET_CZN:
2347 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
2348 The V flag may or may not be known but that's ok because
2349 alter_cond will change tests to use EQ/NE. */
2350 set = single_set (insn);
2351 CC_STATUS_INIT;
2352 if (set)
2354 cc_status.value1 = SET_DEST (set);
2355 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
2357 break;
2359 case CC_COMPARE:
2360 set = single_set (insn);
2361 CC_STATUS_INIT;
2362 if (set)
2363 cc_status.value1 = SET_SRC (set);
2364 break;
2366 case CC_CLOBBER:
2367 /* Insn doesn't leave CC in a usable state. */
2368 CC_STATUS_INIT;
2369 break;
2373 /* Choose mode for jump insn:
2374 1 - relative jump in range -63 <= x <= 62 ;
2375 2 - relative jump in range -2046 <= x <= 2045 ;
2376 3 - absolute jump (only for ATmega[16]03). */
2379 avr_jump_mode (rtx x, rtx insn)
2381 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_CODE (x) == LABEL_REF
2382 ? XEXP (x, 0) : x));
2383 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
2384 int jump_distance = cur_addr - dest_addr;
2386 if (-63 <= jump_distance && jump_distance <= 62)
2387 return 1;
2388 else if (-2046 <= jump_distance && jump_distance <= 2045)
2389 return 2;
2390 else if (AVR_HAVE_JMP_CALL)
2391 return 3;
2393 return 2;
2396 /* Return an AVR condition jump commands.
2397 X is a comparison RTX.
2398 LEN is a number returned by avr_jump_mode function.
2399 If REVERSE nonzero then condition code in X must be reversed. */
2401 const char*
2402 ret_cond_branch (rtx x, int len, int reverse)
2404 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
2406 switch (cond)
2408 case GT:
2409 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2410 return (len == 1 ? ("breq .+2" CR_TAB
2411 "brpl %0") :
2412 len == 2 ? ("breq .+4" CR_TAB
2413 "brmi .+2" CR_TAB
2414 "rjmp %0") :
2415 ("breq .+6" CR_TAB
2416 "brmi .+4" CR_TAB
2417 "jmp %0"));
2419 else
2420 return (len == 1 ? ("breq .+2" CR_TAB
2421 "brge %0") :
2422 len == 2 ? ("breq .+4" CR_TAB
2423 "brlt .+2" CR_TAB
2424 "rjmp %0") :
2425 ("breq .+6" CR_TAB
2426 "brlt .+4" CR_TAB
2427 "jmp %0"));
2428 case GTU:
2429 return (len == 1 ? ("breq .+2" CR_TAB
2430 "brsh %0") :
2431 len == 2 ? ("breq .+4" CR_TAB
2432 "brlo .+2" CR_TAB
2433 "rjmp %0") :
2434 ("breq .+6" CR_TAB
2435 "brlo .+4" CR_TAB
2436 "jmp %0"));
2437 case LE:
2438 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2439 return (len == 1 ? ("breq %0" CR_TAB
2440 "brmi %0") :
2441 len == 2 ? ("breq .+2" CR_TAB
2442 "brpl .+2" CR_TAB
2443 "rjmp %0") :
2444 ("breq .+2" CR_TAB
2445 "brpl .+4" CR_TAB
2446 "jmp %0"));
2447 else
2448 return (len == 1 ? ("breq %0" CR_TAB
2449 "brlt %0") :
2450 len == 2 ? ("breq .+2" CR_TAB
2451 "brge .+2" CR_TAB
2452 "rjmp %0") :
2453 ("breq .+2" CR_TAB
2454 "brge .+4" CR_TAB
2455 "jmp %0"));
2456 case LEU:
2457 return (len == 1 ? ("breq %0" CR_TAB
2458 "brlo %0") :
2459 len == 2 ? ("breq .+2" CR_TAB
2460 "brsh .+2" CR_TAB
2461 "rjmp %0") :
2462 ("breq .+2" CR_TAB
2463 "brsh .+4" CR_TAB
2464 "jmp %0"));
2465 default:
2466 if (reverse)
2468 switch (len)
2470 case 1:
2471 return "br%k1 %0";
2472 case 2:
2473 return ("br%j1 .+2" CR_TAB
2474 "rjmp %0");
2475 default:
2476 return ("br%j1 .+4" CR_TAB
2477 "jmp %0");
2480 else
2482 switch (len)
2484 case 1:
2485 return "br%j1 %0";
2486 case 2:
2487 return ("br%k1 .+2" CR_TAB
2488 "rjmp %0");
2489 default:
2490 return ("br%k1 .+4" CR_TAB
2491 "jmp %0");
2495 return "";
2499 /* Worker function for `FINAL_PRESCAN_INSN'. */
2500 /* Output insn cost for next insn. */
2502 void
2503 avr_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
2504 int num_operands ATTRIBUTE_UNUSED)
2506 if (avr_log.rtx_costs)
2508 rtx set = single_set (insn);
2510 if (set)
2511 fprintf (asm_out_file, "/* DEBUG: cost = %d. */\n",
2512 set_src_cost (SET_SRC (set), optimize_insn_for_speed_p ()));
2513 else
2514 fprintf (asm_out_file, "/* DEBUG: pattern-cost = %d. */\n",
2515 rtx_cost (PATTERN (insn), INSN, 0,
2516 optimize_insn_for_speed_p()));
2520 /* Return 0 if undefined, 1 if always true or always false. */
2523 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE op, rtx x)
2525 unsigned int max = (mode == QImode ? 0xff :
2526 mode == HImode ? 0xffff :
2527 mode == PSImode ? 0xffffff :
2528 mode == SImode ? 0xffffffff : 0);
2529 if (max && op && CONST_INT_P (x))
2531 if (unsigned_condition (op) != op)
2532 max >>= 1;
2534 if (max != (INTVAL (x) & max)
2535 && INTVAL (x) != 0xff)
2536 return 1;
2538 return 0;
2542 /* Worker function for `FUNCTION_ARG_REGNO_P'. */
2543 /* Returns nonzero if REGNO is the number of a hard
2544 register in which function arguments are sometimes passed. */
2547 avr_function_arg_regno_p(int r)
2549 return (r >= 8 && r <= 25);
2553 /* Worker function for `INIT_CUMULATIVE_ARGS'. */
2554 /* Initializing the variable cum for the state at the beginning
2555 of the argument list. */
2557 void
2558 avr_init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
2559 tree fndecl ATTRIBUTE_UNUSED)
2561 cum->nregs = 18;
2562 cum->regno = FIRST_CUM_REG;
2563 if (!libname && stdarg_p (fntype))
2564 cum->nregs = 0;
2566 /* Assume the calle may be tail called */
2568 cfun->machine->sibcall_fails = 0;
2571 /* Returns the number of registers to allocate for a function argument. */
2573 static int
2574 avr_num_arg_regs (enum machine_mode mode, const_tree type)
2576 int size;
2578 if (mode == BLKmode)
2579 size = int_size_in_bytes (type);
2580 else
2581 size = GET_MODE_SIZE (mode);
2583 /* Align all function arguments to start in even-numbered registers.
2584 Odd-sized arguments leave holes above them. */
2586 return (size + 1) & ~1;
2590 /* Implement `TARGET_FUNCTION_ARG'. */
2591 /* Controls whether a function argument is passed
2592 in a register, and which register. */
2594 static rtx
2595 avr_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
2596 const_tree type, bool named ATTRIBUTE_UNUSED)
2598 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2599 int bytes = avr_num_arg_regs (mode, type);
2601 if (cum->nregs && bytes <= cum->nregs)
2602 return gen_rtx_REG (mode, cum->regno - bytes);
2604 return NULL_RTX;
2608 /* Implement `TARGET_FUNCTION_ARG_ADVANCE'. */
2609 /* Update the summarizer variable CUM to advance past an argument
2610 in the argument list. */
2612 static void
2613 avr_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
2614 const_tree type, bool named ATTRIBUTE_UNUSED)
2616 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2617 int bytes = avr_num_arg_regs (mode, type);
2619 cum->nregs -= bytes;
2620 cum->regno -= bytes;
2622 /* A parameter is being passed in a call-saved register. As the original
2623 contents of these regs has to be restored before leaving the function,
2624 a function must not pass arguments in call-saved regs in order to get
2625 tail-called. */
2627 if (cum->regno >= 8
2628 && cum->nregs >= 0
2629 && !call_used_regs[cum->regno])
2631 /* FIXME: We ship info on failing tail-call in struct machine_function.
2632 This uses internals of calls.c:expand_call() and the way args_so_far
2633 is used. targetm.function_ok_for_sibcall() needs to be extended to
2634 pass &args_so_far, too. At present, CUMULATIVE_ARGS is target
2635 dependent so that such an extension is not wanted. */
2637 cfun->machine->sibcall_fails = 1;
2640 /* Test if all registers needed by the ABI are actually available. If the
2641 user has fixed a GPR needed to pass an argument, an (implicit) function
2642 call will clobber that fixed register. See PR45099 for an example. */
2644 if (cum->regno >= 8
2645 && cum->nregs >= 0)
2647 int regno;
2649 for (regno = cum->regno; regno < cum->regno + bytes; regno++)
2650 if (fixed_regs[regno])
2651 warning (0, "fixed register %s used to pass parameter to function",
2652 reg_names[regno]);
2655 if (cum->nregs <= 0)
2657 cum->nregs = 0;
2658 cum->regno = FIRST_CUM_REG;
2662 /* Implement `TARGET_FUNCTION_OK_FOR_SIBCALL' */
2663 /* Decide whether we can make a sibling call to a function. DECL is the
2664 declaration of the function being targeted by the call and EXP is the
2665 CALL_EXPR representing the call. */
2667 static bool
2668 avr_function_ok_for_sibcall (tree decl_callee, tree exp_callee)
2670 tree fntype_callee;
2672 /* Tail-calling must fail if callee-saved regs are used to pass
2673 function args. We must not tail-call when `epilogue_restores'
2674 is used. Unfortunately, we cannot tell at this point if that
2675 actually will happen or not, and we cannot step back from
2676 tail-calling. Thus, we inhibit tail-calling with -mcall-prologues. */
2678 if (cfun->machine->sibcall_fails
2679 || TARGET_CALL_PROLOGUES)
2681 return false;
2684 fntype_callee = TREE_TYPE (CALL_EXPR_FN (exp_callee));
2686 if (decl_callee)
2688 decl_callee = TREE_TYPE (decl_callee);
2690 else
2692 decl_callee = fntype_callee;
2694 while (FUNCTION_TYPE != TREE_CODE (decl_callee)
2695 && METHOD_TYPE != TREE_CODE (decl_callee))
2697 decl_callee = TREE_TYPE (decl_callee);
2701 /* Ensure that caller and callee have compatible epilogues */
2703 if (cfun->machine->is_interrupt
2704 || cfun->machine->is_signal
2705 || cfun->machine->is_naked
2706 || avr_naked_function_p (decl_callee)
2707 /* FIXME: For OS_task and OS_main, this might be over-conservative. */
2708 || (avr_OS_task_function_p (decl_callee)
2709 != cfun->machine->is_OS_task)
2710 || (avr_OS_main_function_p (decl_callee)
2711 != cfun->machine->is_OS_main))
2713 return false;
2716 return true;
2719 /***********************************************************************
2720 Functions for outputting various mov's for a various modes
2721 ************************************************************************/
2723 /* Return true if a value of mode MODE is read from flash by
2724 __load_* function from libgcc. */
2726 bool
2727 avr_load_libgcc_p (rtx op)
2729 enum machine_mode mode = GET_MODE (op);
2730 int n_bytes = GET_MODE_SIZE (mode);
2732 return (n_bytes > 2
2733 && !AVR_HAVE_LPMX
2734 && avr_mem_flash_p (op));
2737 /* Return true if a value of mode MODE is read by __xload_* function. */
2739 bool
2740 avr_xload_libgcc_p (enum machine_mode mode)
2742 int n_bytes = GET_MODE_SIZE (mode);
2744 return (n_bytes > 1
2745 || avr_current_device->n_flash > 1);
2749 /* Fixme: This is a hack because secondary reloads don't works as expected.
2751 Find an unused d-register to be used as scratch in INSN.
2752 EXCLUDE is either NULL_RTX or some register. In the case where EXCLUDE
2753 is a register, skip all possible return values that overlap EXCLUDE.
2754 The policy for the returned register is similar to that of
2755 `reg_unused_after', i.e. the returned register may overlap the SET_DEST
2756 of INSN.
2758 Return a QImode d-register or NULL_RTX if nothing found. */
2760 static rtx
2761 avr_find_unused_d_reg (rtx insn, rtx exclude)
2763 int regno;
2764 bool isr_p = (avr_interrupt_function_p (current_function_decl)
2765 || avr_signal_function_p (current_function_decl));
2767 for (regno = 16; regno < 32; regno++)
2769 rtx reg = all_regs_rtx[regno];
2771 if ((exclude
2772 && reg_overlap_mentioned_p (exclude, reg))
2773 || fixed_regs[regno])
2775 continue;
2778 /* Try non-live register */
2780 if (!df_regs_ever_live_p (regno)
2781 && (TREE_THIS_VOLATILE (current_function_decl)
2782 || cfun->machine->is_OS_task
2783 || cfun->machine->is_OS_main
2784 || (!isr_p && call_used_regs[regno])))
2786 return reg;
2789 /* Any live register can be used if it is unused after.
2790 Prologue/epilogue will care for it as needed. */
2792 if (df_regs_ever_live_p (regno)
2793 && reg_unused_after (insn, reg))
2795 return reg;
2799 return NULL_RTX;
2803 /* Helper function for the next function in the case where only restricted
2804 version of LPM instruction is available. */
2806 static const char*
2807 avr_out_lpm_no_lpmx (rtx insn, rtx *xop, int *plen)
2809 rtx dest = xop[0];
2810 rtx addr = xop[1];
2811 int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
2812 int regno_dest;
2814 regno_dest = REGNO (dest);
2816 /* The implicit target register of LPM. */
2817 xop[3] = lpm_reg_rtx;
2819 switch (GET_CODE (addr))
2821 default:
2822 gcc_unreachable();
2824 case REG:
2826 gcc_assert (REG_Z == REGNO (addr));
2828 switch (n_bytes)
2830 default:
2831 gcc_unreachable();
2833 case 1:
2834 avr_asm_len ("%4lpm", xop, plen, 1);
2836 if (regno_dest != LPM_REGNO)
2837 avr_asm_len ("mov %0,%3", xop, plen, 1);
2839 return "";
2841 case 2:
2842 if (REGNO (dest) == REG_Z)
2843 return avr_asm_len ("%4lpm" CR_TAB
2844 "push %3" CR_TAB
2845 "adiw %2,1" CR_TAB
2846 "%4lpm" CR_TAB
2847 "mov %B0,%3" CR_TAB
2848 "pop %A0", xop, plen, 6);
2850 avr_asm_len ("%4lpm" CR_TAB
2851 "mov %A0,%3" CR_TAB
2852 "adiw %2,1" CR_TAB
2853 "%4lpm" CR_TAB
2854 "mov %B0,%3", xop, plen, 5);
2856 if (!reg_unused_after (insn, addr))
2857 avr_asm_len ("sbiw %2,1", xop, plen, 1);
2859 break; /* 2 */
2862 break; /* REG */
2864 case POST_INC:
2866 gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
2867 && n_bytes <= 4);
2869 if (regno_dest == LPM_REGNO)
2870 avr_asm_len ("%4lpm" CR_TAB
2871 "adiw %2,1", xop, plen, 2);
2872 else
2873 avr_asm_len ("%4lpm" CR_TAB
2874 "mov %A0,%3" CR_TAB
2875 "adiw %2,1", xop, plen, 3);
2877 if (n_bytes >= 2)
2878 avr_asm_len ("%4lpm" CR_TAB
2879 "mov %B0,%3" CR_TAB
2880 "adiw %2,1", xop, plen, 3);
2882 if (n_bytes >= 3)
2883 avr_asm_len ("%4lpm" CR_TAB
2884 "mov %C0,%3" CR_TAB
2885 "adiw %2,1", xop, plen, 3);
2887 if (n_bytes >= 4)
2888 avr_asm_len ("%4lpm" CR_TAB
2889 "mov %D0,%3" CR_TAB
2890 "adiw %2,1", xop, plen, 3);
2892 break; /* POST_INC */
2894 } /* switch CODE (addr) */
2896 return "";
2900 /* If PLEN == NULL: Ouput instructions to load a value from a memory location
2901 OP[1] in AS1 to register OP[0].
2902 If PLEN != 0 set *PLEN to the length in words of the instruction sequence.
2903 Return "". */
2905 const char*
2906 avr_out_lpm (rtx insn, rtx *op, int *plen)
2908 rtx xop[7];
2909 rtx dest = op[0];
2910 rtx src = SET_SRC (single_set (insn));
2911 rtx addr;
2912 int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
2913 int segment;
2914 RTX_CODE code;
2915 addr_space_t as = MEM_ADDR_SPACE (src);
2917 if (plen)
2918 *plen = 0;
2920 if (MEM_P (dest))
2922 warning (0, "writing to address space %qs not supported",
2923 avr_addrspace[MEM_ADDR_SPACE (dest)].name);
2925 return "";
2928 addr = XEXP (src, 0);
2929 code = GET_CODE (addr);
2931 gcc_assert (REG_P (dest));
2932 gcc_assert (REG == code || POST_INC == code);
2934 xop[0] = dest;
2935 xop[1] = addr;
2936 xop[2] = lpm_addr_reg_rtx;
2937 xop[4] = xstring_empty;
2938 xop[5] = tmp_reg_rtx;
2939 xop[6] = XEXP (rampz_rtx, 0);
2941 segment = avr_addrspace[as].segment;
2943 /* Set RAMPZ as needed. */
2945 if (segment)
2947 xop[4] = GEN_INT (segment);
2948 xop[3] = avr_find_unused_d_reg (insn, lpm_addr_reg_rtx);
2950 if (xop[3] != NULL_RTX)
2952 avr_asm_len ("ldi %3,%4" CR_TAB
2953 "out %i6,%3", xop, plen, 2);
2955 else if (segment == 1)
2957 avr_asm_len ("clr %5" CR_TAB
2958 "inc %5" CR_TAB
2959 "out %i6,%5", xop, plen, 3);
2961 else
2963 avr_asm_len ("mov %5,%2" CR_TAB
2964 "ldi %2,%4" CR_TAB
2965 "out %i6,%2" CR_TAB
2966 "mov %2,%5", xop, plen, 4);
2969 xop[4] = xstring_e;
2971 if (!AVR_HAVE_ELPMX)
2972 return avr_out_lpm_no_lpmx (insn, xop, plen);
2974 else if (!AVR_HAVE_LPMX)
2976 return avr_out_lpm_no_lpmx (insn, xop, plen);
2979 /* We have [E]LPMX: Output reading from Flash the comfortable way. */
2981 switch (GET_CODE (addr))
2983 default:
2984 gcc_unreachable();
2986 case REG:
2988 gcc_assert (REG_Z == REGNO (addr));
2990 switch (n_bytes)
2992 default:
2993 gcc_unreachable();
2995 case 1:
2996 return avr_asm_len ("%4lpm %0,%a2", xop, plen, 1);
2998 case 2:
2999 if (REGNO (dest) == REG_Z)
3000 return avr_asm_len ("%4lpm %5,%a2+" CR_TAB
3001 "%4lpm %B0,%a2" CR_TAB
3002 "mov %A0,%5", xop, plen, 3);
3003 else
3005 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3006 "%4lpm %B0,%a2", xop, plen, 2);
3008 if (!reg_unused_after (insn, addr))
3009 avr_asm_len ("sbiw %2,1", xop, plen, 1);
3012 break; /* 2 */
3014 case 3:
3016 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3017 "%4lpm %B0,%a2+" CR_TAB
3018 "%4lpm %C0,%a2", xop, plen, 3);
3020 if (!reg_unused_after (insn, addr))
3021 avr_asm_len ("sbiw %2,2", xop, plen, 1);
3023 break; /* 3 */
3025 case 4:
3027 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3028 "%4lpm %B0,%a2+", xop, plen, 2);
3030 if (REGNO (dest) == REG_Z - 2)
3031 return avr_asm_len ("%4lpm %5,%a2+" CR_TAB
3032 "%4lpm %C0,%a2" CR_TAB
3033 "mov %D0,%5", xop, plen, 3);
3034 else
3036 avr_asm_len ("%4lpm %C0,%a2+" CR_TAB
3037 "%4lpm %D0,%a2", xop, plen, 2);
3039 if (!reg_unused_after (insn, addr))
3040 avr_asm_len ("sbiw %2,3", xop, plen, 1);
3043 break; /* 4 */
3044 } /* n_bytes */
3046 break; /* REG */
3048 case POST_INC:
3050 gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
3051 && n_bytes <= 4);
3053 avr_asm_len ("%4lpm %A0,%a2+", xop, plen, 1);
3054 if (n_bytes >= 2) avr_asm_len ("%4lpm %B0,%a2+", xop, plen, 1);
3055 if (n_bytes >= 3) avr_asm_len ("%4lpm %C0,%a2+", xop, plen, 1);
3056 if (n_bytes >= 4) avr_asm_len ("%4lpm %D0,%a2+", xop, plen, 1);
3058 break; /* POST_INC */
3060 } /* switch CODE (addr) */
3062 if (xop[4] == xstring_e && AVR_HAVE_RAMPD)
3064 /* Reset RAMPZ to 0 so that EBI devices don't read garbage from RAM. */
3066 xop[0] = zero_reg_rtx;
3067 avr_asm_len ("out %i6,%0", xop, plen, 1);
3070 return "";
3074 /* Worker function for xload_8 insn. */
3076 const char*
3077 avr_out_xload (rtx insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
3079 rtx xop[4];
3081 xop[0] = op[0];
3082 xop[1] = op[1];
3083 xop[2] = lpm_addr_reg_rtx;
3084 xop[3] = AVR_HAVE_LPMX ? op[0] : lpm_reg_rtx;
3086 if (plen)
3087 *plen = 0;
3089 avr_asm_len ("sbrc %1,7" CR_TAB
3090 "ld %3,%a2" CR_TAB
3091 "sbrs %1,7", xop, plen, 3);
3093 avr_asm_len (AVR_HAVE_LPMX ? "lpm %3,%a2" : "lpm", xop, plen, 1);
3095 if (REGNO (xop[0]) != REGNO (xop[3]))
3096 avr_asm_len ("mov %0,%3", xop, plen, 1);
3098 return "";
3102 const char*
3103 output_movqi (rtx insn, rtx operands[], int *plen)
3105 rtx dest = operands[0];
3106 rtx src = operands[1];
3108 if (avr_mem_flash_p (src)
3109 || avr_mem_flash_p (dest))
3111 return avr_out_lpm (insn, operands, plen);
3114 gcc_assert (1 == GET_MODE_SIZE (GET_MODE (dest)));
3116 if (REG_P (dest))
3118 if (REG_P (src)) /* mov r,r */
3120 if (test_hard_reg_class (STACK_REG, dest))
3121 return avr_asm_len ("out %0,%1", operands, plen, -1);
3122 else if (test_hard_reg_class (STACK_REG, src))
3123 return avr_asm_len ("in %0,%1", operands, plen, -1);
3125 return avr_asm_len ("mov %0,%1", operands, plen, -1);
3127 else if (CONSTANT_P (src))
3129 output_reload_in_const (operands, NULL_RTX, plen, false);
3130 return "";
3132 else if (MEM_P (src))
3133 return out_movqi_r_mr (insn, operands, plen); /* mov r,m */
3135 else if (MEM_P (dest))
3137 rtx xop[2];
3139 xop[0] = dest;
3140 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
3142 return out_movqi_mr_r (insn, xop, plen);
3145 return "";
3149 const char *
3150 output_movhi (rtx insn, rtx xop[], int *plen)
3152 rtx dest = xop[0];
3153 rtx src = xop[1];
3155 gcc_assert (GET_MODE_SIZE (GET_MODE (dest)) == 2);
3157 if (avr_mem_flash_p (src)
3158 || avr_mem_flash_p (dest))
3160 return avr_out_lpm (insn, xop, plen);
3163 gcc_assert (2 == GET_MODE_SIZE (GET_MODE (dest)));
3165 if (REG_P (dest))
3167 if (REG_P (src)) /* mov r,r */
3169 if (test_hard_reg_class (STACK_REG, dest))
3171 if (AVR_HAVE_8BIT_SP)
3172 return avr_asm_len ("out __SP_L__,%A1", xop, plen, -1);
3174 if (AVR_XMEGA)
3175 return avr_asm_len ("out __SP_L__,%A1" CR_TAB
3176 "out __SP_H__,%B1", xop, plen, -2);
3178 /* Use simple load of SP if no interrupts are used. */
3180 return TARGET_NO_INTERRUPTS
3181 ? avr_asm_len ("out __SP_H__,%B1" CR_TAB
3182 "out __SP_L__,%A1", xop, plen, -2)
3183 : avr_asm_len ("in __tmp_reg__,__SREG__" CR_TAB
3184 "cli" CR_TAB
3185 "out __SP_H__,%B1" CR_TAB
3186 "out __SREG__,__tmp_reg__" CR_TAB
3187 "out __SP_L__,%A1", xop, plen, -5);
3189 else if (test_hard_reg_class (STACK_REG, src))
3191 return !AVR_HAVE_SPH
3192 ? avr_asm_len ("in %A0,__SP_L__" CR_TAB
3193 "clr %B0", xop, plen, -2)
3195 : avr_asm_len ("in %A0,__SP_L__" CR_TAB
3196 "in %B0,__SP_H__", xop, plen, -2);
3199 return AVR_HAVE_MOVW
3200 ? avr_asm_len ("movw %0,%1", xop, plen, -1)
3202 : avr_asm_len ("mov %A0,%A1" CR_TAB
3203 "mov %B0,%B1", xop, plen, -2);
3204 } /* REG_P (src) */
3205 else if (CONSTANT_P (src))
3207 return output_reload_inhi (xop, NULL, plen);
3209 else if (MEM_P (src))
3211 return out_movhi_r_mr (insn, xop, plen); /* mov r,m */
3214 else if (MEM_P (dest))
3216 rtx xop[2];
3218 xop[0] = dest;
3219 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
3221 return out_movhi_mr_r (insn, xop, plen);
3224 fatal_insn ("invalid insn:", insn);
3226 return "";
3229 static const char*
3230 out_movqi_r_mr (rtx insn, rtx op[], int *plen)
3232 rtx dest = op[0];
3233 rtx src = op[1];
3234 rtx x = XEXP (src, 0);
3236 if (CONSTANT_ADDRESS_P (x))
3238 return optimize > 0 && io_address_operand (x, QImode)
3239 ? avr_asm_len ("in %0,%i1", op, plen, -1)
3240 : avr_asm_len ("lds %0,%m1", op, plen, -2);
3242 else if (GET_CODE (x) == PLUS
3243 && REG_P (XEXP (x, 0))
3244 && CONST_INT_P (XEXP (x, 1)))
3246 /* memory access by reg+disp */
3248 int disp = INTVAL (XEXP (x, 1));
3250 if (disp - GET_MODE_SIZE (GET_MODE (src)) >= 63)
3252 if (REGNO (XEXP (x, 0)) != REG_Y)
3253 fatal_insn ("incorrect insn:",insn);
3255 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
3256 return avr_asm_len ("adiw r28,%o1-63" CR_TAB
3257 "ldd %0,Y+63" CR_TAB
3258 "sbiw r28,%o1-63", op, plen, -3);
3260 return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
3261 "sbci r29,hi8(-%o1)" CR_TAB
3262 "ld %0,Y" CR_TAB
3263 "subi r28,lo8(%o1)" CR_TAB
3264 "sbci r29,hi8(%o1)", op, plen, -5);
3266 else if (REGNO (XEXP (x, 0)) == REG_X)
3268 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
3269 it but I have this situation with extremal optimizing options. */
3271 avr_asm_len ("adiw r26,%o1" CR_TAB
3272 "ld %0,X", op, plen, -2);
3274 if (!reg_overlap_mentioned_p (dest, XEXP (x,0))
3275 && !reg_unused_after (insn, XEXP (x,0)))
3277 avr_asm_len ("sbiw r26,%o1", op, plen, 1);
3280 return "";
3283 return avr_asm_len ("ldd %0,%1", op, plen, -1);
3286 return avr_asm_len ("ld %0,%1", op, plen, -1);
3289 static const char*
3290 out_movhi_r_mr (rtx insn, rtx op[], int *plen)
3292 rtx dest = op[0];
3293 rtx src = op[1];
3294 rtx base = XEXP (src, 0);
3295 int reg_dest = true_regnum (dest);
3296 int reg_base = true_regnum (base);
3297 /* "volatile" forces reading low byte first, even if less efficient,
3298 for correct operation with 16-bit I/O registers. */
3299 int mem_volatile_p = MEM_VOLATILE_P (src);
3301 if (reg_base > 0)
3303 if (reg_dest == reg_base) /* R = (R) */
3304 return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
3305 "ld %B0,%1" CR_TAB
3306 "mov %A0,__tmp_reg__", op, plen, -3);
3308 if (reg_base != REG_X)
3309 return avr_asm_len ("ld %A0,%1" CR_TAB
3310 "ldd %B0,%1+1", op, plen, -2);
3312 avr_asm_len ("ld %A0,X+" CR_TAB
3313 "ld %B0,X", op, plen, -2);
3315 if (!reg_unused_after (insn, base))
3316 avr_asm_len ("sbiw r26,1", op, plen, 1);
3318 return "";
3320 else if (GET_CODE (base) == PLUS) /* (R + i) */
3322 int disp = INTVAL (XEXP (base, 1));
3323 int reg_base = true_regnum (XEXP (base, 0));
3325 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3327 if (REGNO (XEXP (base, 0)) != REG_Y)
3328 fatal_insn ("incorrect insn:",insn);
3330 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (src))
3331 ? avr_asm_len ("adiw r28,%o1-62" CR_TAB
3332 "ldd %A0,Y+62" CR_TAB
3333 "ldd %B0,Y+63" CR_TAB
3334 "sbiw r28,%o1-62", op, plen, -4)
3336 : avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
3337 "sbci r29,hi8(-%o1)" CR_TAB
3338 "ld %A0,Y" CR_TAB
3339 "ldd %B0,Y+1" CR_TAB
3340 "subi r28,lo8(%o1)" CR_TAB
3341 "sbci r29,hi8(%o1)", op, plen, -6);
3344 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
3345 it but I have this situation with extremal
3346 optimization options. */
3348 if (reg_base == REG_X)
3349 return reg_base == reg_dest
3350 ? avr_asm_len ("adiw r26,%o1" CR_TAB
3351 "ld __tmp_reg__,X+" CR_TAB
3352 "ld %B0,X" CR_TAB
3353 "mov %A0,__tmp_reg__", op, plen, -4)
3355 : avr_asm_len ("adiw r26,%o1" CR_TAB
3356 "ld %A0,X+" CR_TAB
3357 "ld %B0,X" CR_TAB
3358 "sbiw r26,%o1+1", op, plen, -4);
3360 return reg_base == reg_dest
3361 ? avr_asm_len ("ldd __tmp_reg__,%A1" CR_TAB
3362 "ldd %B0,%B1" CR_TAB
3363 "mov %A0,__tmp_reg__", op, plen, -3)
3365 : avr_asm_len ("ldd %A0,%A1" CR_TAB
3366 "ldd %B0,%B1", op, plen, -2);
3368 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3370 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3371 fatal_insn ("incorrect insn:", insn);
3373 if (!mem_volatile_p)
3374 return avr_asm_len ("ld %B0,%1" CR_TAB
3375 "ld %A0,%1", op, plen, -2);
3377 return REGNO (XEXP (base, 0)) == REG_X
3378 ? avr_asm_len ("sbiw r26,2" CR_TAB
3379 "ld %A0,X+" CR_TAB
3380 "ld %B0,X" CR_TAB
3381 "sbiw r26,1", op, plen, -4)
3383 : avr_asm_len ("sbiw %r1,2" CR_TAB
3384 "ld %A0,%p1" CR_TAB
3385 "ldd %B0,%p1+1", op, plen, -3);
3387 else if (GET_CODE (base) == POST_INC) /* (R++) */
3389 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3390 fatal_insn ("incorrect insn:", insn);
3392 return avr_asm_len ("ld %A0,%1" CR_TAB
3393 "ld %B0,%1", op, plen, -2);
3395 else if (CONSTANT_ADDRESS_P (base))
3397 return optimize > 0 && io_address_operand (base, HImode)
3398 ? avr_asm_len ("in %A0,%i1" CR_TAB
3399 "in %B0,%i1+1", op, plen, -2)
3401 : avr_asm_len ("lds %A0,%m1" CR_TAB
3402 "lds %B0,%m1+1", op, plen, -4);
3405 fatal_insn ("unknown move insn:",insn);
3406 return "";
3409 static const char*
3410 out_movsi_r_mr (rtx insn, rtx op[], int *l)
3412 rtx dest = op[0];
3413 rtx src = op[1];
3414 rtx base = XEXP (src, 0);
3415 int reg_dest = true_regnum (dest);
3416 int reg_base = true_regnum (base);
3417 int tmp;
3419 if (!l)
3420 l = &tmp;
3422 if (reg_base > 0)
3424 if (reg_base == REG_X) /* (R26) */
3426 if (reg_dest == REG_X)
3427 /* "ld r26,-X" is undefined */
3428 return *l=7, ("adiw r26,3" CR_TAB
3429 "ld r29,X" CR_TAB
3430 "ld r28,-X" CR_TAB
3431 "ld __tmp_reg__,-X" CR_TAB
3432 "sbiw r26,1" CR_TAB
3433 "ld r26,X" CR_TAB
3434 "mov r27,__tmp_reg__");
3435 else if (reg_dest == REG_X - 2)
3436 return *l=5, ("ld %A0,X+" CR_TAB
3437 "ld %B0,X+" CR_TAB
3438 "ld __tmp_reg__,X+" CR_TAB
3439 "ld %D0,X" CR_TAB
3440 "mov %C0,__tmp_reg__");
3441 else if (reg_unused_after (insn, base))
3442 return *l=4, ("ld %A0,X+" CR_TAB
3443 "ld %B0,X+" CR_TAB
3444 "ld %C0,X+" CR_TAB
3445 "ld %D0,X");
3446 else
3447 return *l=5, ("ld %A0,X+" CR_TAB
3448 "ld %B0,X+" CR_TAB
3449 "ld %C0,X+" CR_TAB
3450 "ld %D0,X" CR_TAB
3451 "sbiw r26,3");
3453 else
3455 if (reg_dest == reg_base)
3456 return *l=5, ("ldd %D0,%1+3" CR_TAB
3457 "ldd %C0,%1+2" CR_TAB
3458 "ldd __tmp_reg__,%1+1" CR_TAB
3459 "ld %A0,%1" CR_TAB
3460 "mov %B0,__tmp_reg__");
3461 else if (reg_base == reg_dest + 2)
3462 return *l=5, ("ld %A0,%1" CR_TAB
3463 "ldd %B0,%1+1" CR_TAB
3464 "ldd __tmp_reg__,%1+2" CR_TAB
3465 "ldd %D0,%1+3" CR_TAB
3466 "mov %C0,__tmp_reg__");
3467 else
3468 return *l=4, ("ld %A0,%1" CR_TAB
3469 "ldd %B0,%1+1" CR_TAB
3470 "ldd %C0,%1+2" CR_TAB
3471 "ldd %D0,%1+3");
3474 else if (GET_CODE (base) == PLUS) /* (R + i) */
3476 int disp = INTVAL (XEXP (base, 1));
3478 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3480 if (REGNO (XEXP (base, 0)) != REG_Y)
3481 fatal_insn ("incorrect insn:",insn);
3483 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
3484 return *l = 6, ("adiw r28,%o1-60" CR_TAB
3485 "ldd %A0,Y+60" CR_TAB
3486 "ldd %B0,Y+61" CR_TAB
3487 "ldd %C0,Y+62" CR_TAB
3488 "ldd %D0,Y+63" CR_TAB
3489 "sbiw r28,%o1-60");
3491 return *l = 8, ("subi r28,lo8(-%o1)" CR_TAB
3492 "sbci r29,hi8(-%o1)" CR_TAB
3493 "ld %A0,Y" CR_TAB
3494 "ldd %B0,Y+1" CR_TAB
3495 "ldd %C0,Y+2" CR_TAB
3496 "ldd %D0,Y+3" CR_TAB
3497 "subi r28,lo8(%o1)" CR_TAB
3498 "sbci r29,hi8(%o1)");
3501 reg_base = true_regnum (XEXP (base, 0));
3502 if (reg_base == REG_X)
3504 /* R = (X + d) */
3505 if (reg_dest == REG_X)
3507 *l = 7;
3508 /* "ld r26,-X" is undefined */
3509 return ("adiw r26,%o1+3" CR_TAB
3510 "ld r29,X" CR_TAB
3511 "ld r28,-X" CR_TAB
3512 "ld __tmp_reg__,-X" CR_TAB
3513 "sbiw r26,1" CR_TAB
3514 "ld r26,X" CR_TAB
3515 "mov r27,__tmp_reg__");
3517 *l = 6;
3518 if (reg_dest == REG_X - 2)
3519 return ("adiw r26,%o1" CR_TAB
3520 "ld r24,X+" CR_TAB
3521 "ld r25,X+" CR_TAB
3522 "ld __tmp_reg__,X+" CR_TAB
3523 "ld r27,X" CR_TAB
3524 "mov r26,__tmp_reg__");
3526 return ("adiw r26,%o1" CR_TAB
3527 "ld %A0,X+" CR_TAB
3528 "ld %B0,X+" CR_TAB
3529 "ld %C0,X+" CR_TAB
3530 "ld %D0,X" CR_TAB
3531 "sbiw r26,%o1+3");
3533 if (reg_dest == reg_base)
3534 return *l=5, ("ldd %D0,%D1" CR_TAB
3535 "ldd %C0,%C1" CR_TAB
3536 "ldd __tmp_reg__,%B1" CR_TAB
3537 "ldd %A0,%A1" CR_TAB
3538 "mov %B0,__tmp_reg__");
3539 else if (reg_dest == reg_base - 2)
3540 return *l=5, ("ldd %A0,%A1" CR_TAB
3541 "ldd %B0,%B1" CR_TAB
3542 "ldd __tmp_reg__,%C1" CR_TAB
3543 "ldd %D0,%D1" CR_TAB
3544 "mov %C0,__tmp_reg__");
3545 return *l=4, ("ldd %A0,%A1" CR_TAB
3546 "ldd %B0,%B1" CR_TAB
3547 "ldd %C0,%C1" CR_TAB
3548 "ldd %D0,%D1");
3550 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3551 return *l=4, ("ld %D0,%1" CR_TAB
3552 "ld %C0,%1" CR_TAB
3553 "ld %B0,%1" CR_TAB
3554 "ld %A0,%1");
3555 else if (GET_CODE (base) == POST_INC) /* (R++) */
3556 return *l=4, ("ld %A0,%1" CR_TAB
3557 "ld %B0,%1" CR_TAB
3558 "ld %C0,%1" CR_TAB
3559 "ld %D0,%1");
3560 else if (CONSTANT_ADDRESS_P (base))
3561 return *l=8, ("lds %A0,%m1" CR_TAB
3562 "lds %B0,%m1+1" CR_TAB
3563 "lds %C0,%m1+2" CR_TAB
3564 "lds %D0,%m1+3");
3566 fatal_insn ("unknown move insn:",insn);
3567 return "";
3570 static const char*
3571 out_movsi_mr_r (rtx insn, rtx op[], int *l)
3573 rtx dest = op[0];
3574 rtx src = op[1];
3575 rtx base = XEXP (dest, 0);
3576 int reg_base = true_regnum (base);
3577 int reg_src = true_regnum (src);
3578 int tmp;
3580 if (!l)
3581 l = &tmp;
3583 if (CONSTANT_ADDRESS_P (base))
3584 return *l=8,("sts %m0,%A1" CR_TAB
3585 "sts %m0+1,%B1" CR_TAB
3586 "sts %m0+2,%C1" CR_TAB
3587 "sts %m0+3,%D1");
3588 if (reg_base > 0) /* (r) */
3590 if (reg_base == REG_X) /* (R26) */
3592 if (reg_src == REG_X)
3594 /* "st X+,r26" is undefined */
3595 if (reg_unused_after (insn, base))
3596 return *l=6, ("mov __tmp_reg__,r27" CR_TAB
3597 "st X,r26" CR_TAB
3598 "adiw r26,1" CR_TAB
3599 "st X+,__tmp_reg__" CR_TAB
3600 "st X+,r28" CR_TAB
3601 "st X,r29");
3602 else
3603 return *l=7, ("mov __tmp_reg__,r27" CR_TAB
3604 "st X,r26" CR_TAB
3605 "adiw r26,1" CR_TAB
3606 "st X+,__tmp_reg__" CR_TAB
3607 "st X+,r28" CR_TAB
3608 "st X,r29" CR_TAB
3609 "sbiw r26,3");
3611 else if (reg_base == reg_src + 2)
3613 if (reg_unused_after (insn, base))
3614 return *l=7, ("mov __zero_reg__,%C1" CR_TAB
3615 "mov __tmp_reg__,%D1" CR_TAB
3616 "st %0+,%A1" CR_TAB
3617 "st %0+,%B1" CR_TAB
3618 "st %0+,__zero_reg__" CR_TAB
3619 "st %0,__tmp_reg__" CR_TAB
3620 "clr __zero_reg__");
3621 else
3622 return *l=8, ("mov __zero_reg__,%C1" CR_TAB
3623 "mov __tmp_reg__,%D1" CR_TAB
3624 "st %0+,%A1" CR_TAB
3625 "st %0+,%B1" CR_TAB
3626 "st %0+,__zero_reg__" CR_TAB
3627 "st %0,__tmp_reg__" CR_TAB
3628 "clr __zero_reg__" CR_TAB
3629 "sbiw r26,3");
3631 return *l=5, ("st %0+,%A1" CR_TAB
3632 "st %0+,%B1" CR_TAB
3633 "st %0+,%C1" CR_TAB
3634 "st %0,%D1" CR_TAB
3635 "sbiw r26,3");
3637 else
3638 return *l=4, ("st %0,%A1" CR_TAB
3639 "std %0+1,%B1" CR_TAB
3640 "std %0+2,%C1" CR_TAB
3641 "std %0+3,%D1");
3643 else if (GET_CODE (base) == PLUS) /* (R + i) */
3645 int disp = INTVAL (XEXP (base, 1));
3646 reg_base = REGNO (XEXP (base, 0));
3647 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
3649 if (reg_base != REG_Y)
3650 fatal_insn ("incorrect insn:",insn);
3652 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
3653 return *l = 6, ("adiw r28,%o0-60" CR_TAB
3654 "std Y+60,%A1" CR_TAB
3655 "std Y+61,%B1" CR_TAB
3656 "std Y+62,%C1" CR_TAB
3657 "std Y+63,%D1" CR_TAB
3658 "sbiw r28,%o0-60");
3660 return *l = 8, ("subi r28,lo8(-%o0)" CR_TAB
3661 "sbci r29,hi8(-%o0)" CR_TAB
3662 "st Y,%A1" CR_TAB
3663 "std Y+1,%B1" CR_TAB
3664 "std Y+2,%C1" CR_TAB
3665 "std Y+3,%D1" CR_TAB
3666 "subi r28,lo8(%o0)" CR_TAB
3667 "sbci r29,hi8(%o0)");
3669 if (reg_base == REG_X)
3671 /* (X + d) = R */
3672 if (reg_src == REG_X)
3674 *l = 9;
3675 return ("mov __tmp_reg__,r26" CR_TAB
3676 "mov __zero_reg__,r27" CR_TAB
3677 "adiw r26,%o0" CR_TAB
3678 "st X+,__tmp_reg__" CR_TAB
3679 "st X+,__zero_reg__" CR_TAB
3680 "st X+,r28" CR_TAB
3681 "st X,r29" CR_TAB
3682 "clr __zero_reg__" CR_TAB
3683 "sbiw r26,%o0+3");
3685 else if (reg_src == REG_X - 2)
3687 *l = 9;
3688 return ("mov __tmp_reg__,r26" CR_TAB
3689 "mov __zero_reg__,r27" CR_TAB
3690 "adiw r26,%o0" CR_TAB
3691 "st X+,r24" CR_TAB
3692 "st X+,r25" CR_TAB
3693 "st X+,__tmp_reg__" CR_TAB
3694 "st X,__zero_reg__" CR_TAB
3695 "clr __zero_reg__" CR_TAB
3696 "sbiw r26,%o0+3");
3698 *l = 6;
3699 return ("adiw r26,%o0" CR_TAB
3700 "st X+,%A1" CR_TAB
3701 "st X+,%B1" CR_TAB
3702 "st X+,%C1" CR_TAB
3703 "st X,%D1" CR_TAB
3704 "sbiw r26,%o0+3");
3706 return *l=4, ("std %A0,%A1" CR_TAB
3707 "std %B0,%B1" CR_TAB
3708 "std %C0,%C1" CR_TAB
3709 "std %D0,%D1");
3711 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3712 return *l=4, ("st %0,%D1" CR_TAB
3713 "st %0,%C1" CR_TAB
3714 "st %0,%B1" CR_TAB
3715 "st %0,%A1");
3716 else if (GET_CODE (base) == POST_INC) /* (R++) */
3717 return *l=4, ("st %0,%A1" CR_TAB
3718 "st %0,%B1" CR_TAB
3719 "st %0,%C1" CR_TAB
3720 "st %0,%D1");
3721 fatal_insn ("unknown move insn:",insn);
3722 return "";
3725 const char *
3726 output_movsisf (rtx insn, rtx operands[], int *l)
3728 int dummy;
3729 rtx dest = operands[0];
3730 rtx src = operands[1];
3731 int *real_l = l;
3733 if (avr_mem_flash_p (src)
3734 || avr_mem_flash_p (dest))
3736 return avr_out_lpm (insn, operands, real_l);
3739 if (!l)
3740 l = &dummy;
3742 gcc_assert (4 == GET_MODE_SIZE (GET_MODE (dest)));
3743 if (REG_P (dest))
3745 if (REG_P (src)) /* mov r,r */
3747 if (true_regnum (dest) > true_regnum (src))
3749 if (AVR_HAVE_MOVW)
3751 *l = 2;
3752 return ("movw %C0,%C1" CR_TAB
3753 "movw %A0,%A1");
3755 *l = 4;
3756 return ("mov %D0,%D1" CR_TAB
3757 "mov %C0,%C1" CR_TAB
3758 "mov %B0,%B1" CR_TAB
3759 "mov %A0,%A1");
3761 else
3763 if (AVR_HAVE_MOVW)
3765 *l = 2;
3766 return ("movw %A0,%A1" CR_TAB
3767 "movw %C0,%C1");
3769 *l = 4;
3770 return ("mov %A0,%A1" CR_TAB
3771 "mov %B0,%B1" CR_TAB
3772 "mov %C0,%C1" CR_TAB
3773 "mov %D0,%D1");
3776 else if (CONSTANT_P (src))
3778 return output_reload_insisf (operands, NULL_RTX, real_l);
3780 else if (MEM_P (src))
3781 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
3783 else if (MEM_P (dest))
3785 const char *templ;
3787 if (src == CONST0_RTX (GET_MODE (dest)))
3788 operands[1] = zero_reg_rtx;
3790 templ = out_movsi_mr_r (insn, operands, real_l);
3792 if (!real_l)
3793 output_asm_insn (templ, operands);
3795 operands[1] = src;
3796 return "";
3798 fatal_insn ("invalid insn:", insn);
3799 return "";
3803 /* Handle loads of 24-bit types from memory to register. */
3805 static const char*
3806 avr_out_load_psi (rtx insn, rtx *op, int *plen)
3808 rtx dest = op[0];
3809 rtx src = op[1];
3810 rtx base = XEXP (src, 0);
3811 int reg_dest = true_regnum (dest);
3812 int reg_base = true_regnum (base);
3814 if (reg_base > 0)
3816 if (reg_base == REG_X) /* (R26) */
3818 if (reg_dest == REG_X)
3819 /* "ld r26,-X" is undefined */
3820 return avr_asm_len ("adiw r26,2" CR_TAB
3821 "ld r28,X" CR_TAB
3822 "ld __tmp_reg__,-X" CR_TAB
3823 "sbiw r26,1" CR_TAB
3824 "ld r26,X" CR_TAB
3825 "mov r27,__tmp_reg__", op, plen, -6);
3826 else
3828 avr_asm_len ("ld %A0,X+" CR_TAB
3829 "ld %B0,X+" CR_TAB
3830 "ld %C0,X", op, plen, -3);
3832 if (reg_dest != REG_X - 2
3833 && !reg_unused_after (insn, base))
3835 avr_asm_len ("sbiw r26,2", op, plen, 1);
3838 return "";
3841 else /* reg_base != REG_X */
3843 if (reg_dest == reg_base)
3844 return avr_asm_len ("ldd %C0,%1+2" CR_TAB
3845 "ldd __tmp_reg__,%1+1" CR_TAB
3846 "ld %A0,%1" CR_TAB
3847 "mov %B0,__tmp_reg__", op, plen, -4);
3848 else
3849 return avr_asm_len ("ld %A0,%1" CR_TAB
3850 "ldd %B0,%1+1" CR_TAB
3851 "ldd %C0,%1+2", op, plen, -3);
3854 else if (GET_CODE (base) == PLUS) /* (R + i) */
3856 int disp = INTVAL (XEXP (base, 1));
3858 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3860 if (REGNO (XEXP (base, 0)) != REG_Y)
3861 fatal_insn ("incorrect insn:",insn);
3863 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
3864 return avr_asm_len ("adiw r28,%o1-61" CR_TAB
3865 "ldd %A0,Y+61" CR_TAB
3866 "ldd %B0,Y+62" CR_TAB
3867 "ldd %C0,Y+63" CR_TAB
3868 "sbiw r28,%o1-61", op, plen, -5);
3870 return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
3871 "sbci r29,hi8(-%o1)" CR_TAB
3872 "ld %A0,Y" CR_TAB
3873 "ldd %B0,Y+1" CR_TAB
3874 "ldd %C0,Y+2" CR_TAB
3875 "subi r28,lo8(%o1)" CR_TAB
3876 "sbci r29,hi8(%o1)", op, plen, -7);
3879 reg_base = true_regnum (XEXP (base, 0));
3880 if (reg_base == REG_X)
3882 /* R = (X + d) */
3883 if (reg_dest == REG_X)
3885 /* "ld r26,-X" is undefined */
3886 return avr_asm_len ("adiw r26,%o1+2" CR_TAB
3887 "ld r28,X" CR_TAB
3888 "ld __tmp_reg__,-X" CR_TAB
3889 "sbiw r26,1" CR_TAB
3890 "ld r26,X" CR_TAB
3891 "mov r27,__tmp_reg__", op, plen, -6);
3894 avr_asm_len ("adiw r26,%o1" CR_TAB
3895 "ld %A0,X+" CR_TAB
3896 "ld %B0,X+" CR_TAB
3897 "ld %C0,X", op, plen, -4);
3899 if (reg_dest != REG_W
3900 && !reg_unused_after (insn, XEXP (base, 0)))
3901 avr_asm_len ("sbiw r26,%o1+2", op, plen, 1);
3903 return "";
3906 if (reg_dest == reg_base)
3907 return avr_asm_len ("ldd %C0,%C1" CR_TAB
3908 "ldd __tmp_reg__,%B1" CR_TAB
3909 "ldd %A0,%A1" CR_TAB
3910 "mov %B0,__tmp_reg__", op, plen, -4);
3912 return avr_asm_len ("ldd %A0,%A1" CR_TAB
3913 "ldd %B0,%B1" CR_TAB
3914 "ldd %C0,%C1", op, plen, -3);
3916 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3917 return avr_asm_len ("ld %C0,%1" CR_TAB
3918 "ld %B0,%1" CR_TAB
3919 "ld %A0,%1", op, plen, -3);
3920 else if (GET_CODE (base) == POST_INC) /* (R++) */
3921 return avr_asm_len ("ld %A0,%1" CR_TAB
3922 "ld %B0,%1" CR_TAB
3923 "ld %C0,%1", op, plen, -3);
3925 else if (CONSTANT_ADDRESS_P (base))
3926 return avr_asm_len ("lds %A0,%m1" CR_TAB
3927 "lds %B0,%m1+1" CR_TAB
3928 "lds %C0,%m1+2", op, plen , -6);
3930 fatal_insn ("unknown move insn:",insn);
3931 return "";
3934 /* Handle store of 24-bit type from register or zero to memory. */
3936 static const char*
3937 avr_out_store_psi (rtx insn, rtx *op, int *plen)
3939 rtx dest = op[0];
3940 rtx src = op[1];
3941 rtx base = XEXP (dest, 0);
3942 int reg_base = true_regnum (base);
3944 if (CONSTANT_ADDRESS_P (base))
3945 return avr_asm_len ("sts %m0,%A1" CR_TAB
3946 "sts %m0+1,%B1" CR_TAB
3947 "sts %m0+2,%C1", op, plen, -6);
3949 if (reg_base > 0) /* (r) */
3951 if (reg_base == REG_X) /* (R26) */
3953 gcc_assert (!reg_overlap_mentioned_p (base, src));
3955 avr_asm_len ("st %0+,%A1" CR_TAB
3956 "st %0+,%B1" CR_TAB
3957 "st %0,%C1", op, plen, -3);
3959 if (!reg_unused_after (insn, base))
3960 avr_asm_len ("sbiw r26,2", op, plen, 1);
3962 return "";
3964 else
3965 return avr_asm_len ("st %0,%A1" CR_TAB
3966 "std %0+1,%B1" CR_TAB
3967 "std %0+2,%C1", op, plen, -3);
3969 else if (GET_CODE (base) == PLUS) /* (R + i) */
3971 int disp = INTVAL (XEXP (base, 1));
3972 reg_base = REGNO (XEXP (base, 0));
3974 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
3976 if (reg_base != REG_Y)
3977 fatal_insn ("incorrect insn:",insn);
3979 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
3980 return avr_asm_len ("adiw r28,%o0-61" CR_TAB
3981 "std Y+61,%A1" CR_TAB
3982 "std Y+62,%B1" CR_TAB
3983 "std Y+63,%C1" CR_TAB
3984 "sbiw r28,%o0-60", op, plen, -5);
3986 return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
3987 "sbci r29,hi8(-%o0)" CR_TAB
3988 "st Y,%A1" CR_TAB
3989 "std Y+1,%B1" CR_TAB
3990 "std Y+2,%C1" CR_TAB
3991 "subi r28,lo8(%o0)" CR_TAB
3992 "sbci r29,hi8(%o0)", op, plen, -7);
3994 if (reg_base == REG_X)
3996 /* (X + d) = R */
3997 gcc_assert (!reg_overlap_mentioned_p (XEXP (base, 0), src));
3999 avr_asm_len ("adiw r26,%o0" CR_TAB
4000 "st X+,%A1" CR_TAB
4001 "st X+,%B1" CR_TAB
4002 "st X,%C1", op, plen, -4);
4004 if (!reg_unused_after (insn, XEXP (base, 0)))
4005 avr_asm_len ("sbiw r26,%o0+2", op, plen, 1);
4007 return "";
4010 return avr_asm_len ("std %A0,%A1" CR_TAB
4011 "std %B0,%B1" CR_TAB
4012 "std %C0,%C1", op, plen, -3);
4014 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4015 return avr_asm_len ("st %0,%C1" CR_TAB
4016 "st %0,%B1" CR_TAB
4017 "st %0,%A1", op, plen, -3);
4018 else if (GET_CODE (base) == POST_INC) /* (R++) */
4019 return avr_asm_len ("st %0,%A1" CR_TAB
4020 "st %0,%B1" CR_TAB
4021 "st %0,%C1", op, plen, -3);
4023 fatal_insn ("unknown move insn:",insn);
4024 return "";
4028 /* Move around 24-bit stuff. */
4030 const char *
4031 avr_out_movpsi (rtx insn, rtx *op, int *plen)
4033 rtx dest = op[0];
4034 rtx src = op[1];
4036 if (avr_mem_flash_p (src)
4037 || avr_mem_flash_p (dest))
4039 return avr_out_lpm (insn, op, plen);
4042 if (register_operand (dest, VOIDmode))
4044 if (register_operand (src, VOIDmode)) /* mov r,r */
4046 if (true_regnum (dest) > true_regnum (src))
4048 avr_asm_len ("mov %C0,%C1", op, plen, -1);
4050 if (AVR_HAVE_MOVW)
4051 return avr_asm_len ("movw %A0,%A1", op, plen, 1);
4052 else
4053 return avr_asm_len ("mov %B0,%B1" CR_TAB
4054 "mov %A0,%A1", op, plen, 2);
4056 else
4058 if (AVR_HAVE_MOVW)
4059 avr_asm_len ("movw %A0,%A1", op, plen, -1);
4060 else
4061 avr_asm_len ("mov %A0,%A1" CR_TAB
4062 "mov %B0,%B1", op, plen, -2);
4064 return avr_asm_len ("mov %C0,%C1", op, plen, 1);
4067 else if (CONSTANT_P (src))
4069 return avr_out_reload_inpsi (op, NULL_RTX, plen);
4071 else if (MEM_P (src))
4072 return avr_out_load_psi (insn, op, plen); /* mov r,m */
4074 else if (MEM_P (dest))
4076 rtx xop[2];
4078 xop[0] = dest;
4079 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
4081 return avr_out_store_psi (insn, xop, plen);
4084 fatal_insn ("invalid insn:", insn);
4085 return "";
4089 static const char*
4090 out_movqi_mr_r (rtx insn, rtx op[], int *plen)
4092 rtx dest = op[0];
4093 rtx src = op[1];
4094 rtx x = XEXP (dest, 0);
4096 if (CONSTANT_ADDRESS_P (x))
4098 return optimize > 0 && io_address_operand (x, QImode)
4099 ? avr_asm_len ("out %i0,%1", op, plen, -1)
4100 : avr_asm_len ("sts %m0,%1", op, plen, -2);
4102 else if (GET_CODE (x) == PLUS
4103 && REG_P (XEXP (x, 0))
4104 && CONST_INT_P (XEXP (x, 1)))
4106 /* memory access by reg+disp */
4108 int disp = INTVAL (XEXP (x, 1));
4110 if (disp - GET_MODE_SIZE (GET_MODE (dest)) >= 63)
4112 if (REGNO (XEXP (x, 0)) != REG_Y)
4113 fatal_insn ("incorrect insn:",insn);
4115 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
4116 return avr_asm_len ("adiw r28,%o0-63" CR_TAB
4117 "std Y+63,%1" CR_TAB
4118 "sbiw r28,%o0-63", op, plen, -3);
4120 return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
4121 "sbci r29,hi8(-%o0)" CR_TAB
4122 "st Y,%1" CR_TAB
4123 "subi r28,lo8(%o0)" CR_TAB
4124 "sbci r29,hi8(%o0)", op, plen, -5);
4126 else if (REGNO (XEXP (x,0)) == REG_X)
4128 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
4130 avr_asm_len ("mov __tmp_reg__,%1" CR_TAB
4131 "adiw r26,%o0" CR_TAB
4132 "st X,__tmp_reg__", op, plen, -3);
4134 else
4136 avr_asm_len ("adiw r26,%o0" CR_TAB
4137 "st X,%1", op, plen, -2);
4140 if (!reg_unused_after (insn, XEXP (x,0)))
4141 avr_asm_len ("sbiw r26,%o0", op, plen, 1);
4143 return "";
4146 return avr_asm_len ("std %0,%1", op, plen, -1);
4149 return avr_asm_len ("st %0,%1", op, plen, -1);
4153 /* Helper for the next function for XMEGA. It does the same
4154 but with low byte first. */
4156 static const char*
4157 avr_out_movhi_mr_r_xmega (rtx insn, rtx op[], int *plen)
4159 rtx dest = op[0];
4160 rtx src = op[1];
4161 rtx base = XEXP (dest, 0);
4162 int reg_base = true_regnum (base);
4163 int reg_src = true_regnum (src);
4165 /* "volatile" forces writing low byte first, even if less efficient,
4166 for correct operation with 16-bit I/O registers like SP. */
4167 int mem_volatile_p = MEM_VOLATILE_P (dest);
4169 if (CONSTANT_ADDRESS_P (base))
4170 return optimize > 0 && io_address_operand (base, HImode)
4171 ? avr_asm_len ("out %i0,%A1" CR_TAB
4172 "out %i0+1,%B1", op, plen, -2)
4174 : avr_asm_len ("sts %m0,%A1" CR_TAB
4175 "sts %m0+1,%B1", op, plen, -4);
4177 if (reg_base > 0)
4179 if (reg_base != REG_X)
4180 return avr_asm_len ("st %0,%A1" CR_TAB
4181 "std %0+1,%B1", op, plen, -2);
4183 if (reg_src == REG_X)
4184 /* "st X+,r26" and "st -X,r26" are undefined. */
4185 avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
4186 "st X,r26" CR_TAB
4187 "adiw r26,1" CR_TAB
4188 "st X,__tmp_reg__", op, plen, -4);
4189 else
4190 avr_asm_len ("st X+,%A1" CR_TAB
4191 "st X,%B1", op, plen, -2);
4193 return reg_unused_after (insn, base)
4194 ? ""
4195 : avr_asm_len ("sbiw r26,1", op, plen, 1);
4197 else if (GET_CODE (base) == PLUS)
4199 int disp = INTVAL (XEXP (base, 1));
4200 reg_base = REGNO (XEXP (base, 0));
4201 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
4203 if (reg_base != REG_Y)
4204 fatal_insn ("incorrect insn:",insn);
4206 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))
4207 ? avr_asm_len ("adiw r28,%o0-62" CR_TAB
4208 "std Y+62,%A1" CR_TAB
4209 "std Y+63,%B1" CR_TAB
4210 "sbiw r28,%o0-62", op, plen, -4)
4212 : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
4213 "sbci r29,hi8(-%o0)" CR_TAB
4214 "st Y,%A1" CR_TAB
4215 "std Y+1,%B1" CR_TAB
4216 "subi r28,lo8(%o0)" CR_TAB
4217 "sbci r29,hi8(%o0)", op, plen, -6);
4220 if (reg_base != REG_X)
4221 return avr_asm_len ("std %A0,%A1" CR_TAB
4222 "std %B0,%B1", op, plen, -2);
4223 /* (X + d) = R */
4224 return reg_src == REG_X
4225 ? avr_asm_len ("mov __tmp_reg__,r26" CR_TAB
4226 "mov __zero_reg__,r27" CR_TAB
4227 "adiw r26,%o0" CR_TAB
4228 "st X+,__tmp_reg__" CR_TAB
4229 "st X,__zero_reg__" CR_TAB
4230 "clr __zero_reg__" CR_TAB
4231 "sbiw r26,%o0+1", op, plen, -7)
4233 : avr_asm_len ("adiw r26,%o0" CR_TAB
4234 "st X+,%A1" CR_TAB
4235 "st X,%B1" CR_TAB
4236 "sbiw r26,%o0+1", op, plen, -4);
4238 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4240 if (!mem_volatile_p)
4241 return avr_asm_len ("st %0,%B1" CR_TAB
4242 "st %0,%A1", op, plen, -2);
4244 return REGNO (XEXP (base, 0)) == REG_X
4245 ? avr_asm_len ("sbiw r26,2" CR_TAB
4246 "st X+,%A1" CR_TAB
4247 "st X,%B1" CR_TAB
4248 "sbiw r26,1", op, plen, -4)
4250 : avr_asm_len ("sbiw %r0,2" CR_TAB
4251 "st %p0,%A1" CR_TAB
4252 "std %p0+1,%B1", op, plen, -3);
4254 else if (GET_CODE (base) == POST_INC) /* (R++) */
4256 return avr_asm_len ("st %0,%A1" CR_TAB
4257 "st %0,%B1", op, plen, -2);
4260 fatal_insn ("unknown move insn:",insn);
4261 return "";
4265 static const char*
4266 out_movhi_mr_r (rtx insn, rtx op[], int *plen)
4268 rtx dest = op[0];
4269 rtx src = op[1];
4270 rtx base = XEXP (dest, 0);
4271 int reg_base = true_regnum (base);
4272 int reg_src = true_regnum (src);
4273 int mem_volatile_p;
4275 /* "volatile" forces writing high-byte first (no-xmega) resp.
4276 low-byte first (xmega) even if less efficient, for correct
4277 operation with 16-bit I/O registers like. */
4279 if (AVR_XMEGA)
4280 return avr_out_movhi_mr_r_xmega (insn, op, plen);
4282 mem_volatile_p = MEM_VOLATILE_P (dest);
4284 if (CONSTANT_ADDRESS_P (base))
4285 return optimize > 0 && io_address_operand (base, HImode)
4286 ? avr_asm_len ("out %i0+1,%B1" CR_TAB
4287 "out %i0,%A1", op, plen, -2)
4289 : avr_asm_len ("sts %m0+1,%B1" CR_TAB
4290 "sts %m0,%A1", op, plen, -4);
4292 if (reg_base > 0)
4294 if (reg_base != REG_X)
4295 return avr_asm_len ("std %0+1,%B1" CR_TAB
4296 "st %0,%A1", op, plen, -2);
4298 if (reg_src == REG_X)
4299 /* "st X+,r26" and "st -X,r26" are undefined. */
4300 return !mem_volatile_p && reg_unused_after (insn, src)
4301 ? avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
4302 "st X,r26" CR_TAB
4303 "adiw r26,1" CR_TAB
4304 "st X,__tmp_reg__", op, plen, -4)
4306 : avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
4307 "adiw r26,1" CR_TAB
4308 "st X,__tmp_reg__" CR_TAB
4309 "sbiw r26,1" CR_TAB
4310 "st X,r26", op, plen, -5);
4312 return !mem_volatile_p && reg_unused_after (insn, base)
4313 ? avr_asm_len ("st X+,%A1" CR_TAB
4314 "st X,%B1", op, plen, -2)
4315 : avr_asm_len ("adiw r26,1" CR_TAB
4316 "st X,%B1" CR_TAB
4317 "st -X,%A1", op, plen, -3);
4319 else if (GET_CODE (base) == PLUS)
4321 int disp = INTVAL (XEXP (base, 1));
4322 reg_base = REGNO (XEXP (base, 0));
4323 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
4325 if (reg_base != REG_Y)
4326 fatal_insn ("incorrect insn:",insn);
4328 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))
4329 ? avr_asm_len ("adiw r28,%o0-62" CR_TAB
4330 "std Y+63,%B1" CR_TAB
4331 "std Y+62,%A1" CR_TAB
4332 "sbiw r28,%o0-62", op, plen, -4)
4334 : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
4335 "sbci r29,hi8(-%o0)" CR_TAB
4336 "std Y+1,%B1" CR_TAB
4337 "st Y,%A1" CR_TAB
4338 "subi r28,lo8(%o0)" CR_TAB
4339 "sbci r29,hi8(%o0)", op, plen, -6);
4342 if (reg_base != REG_X)
4343 return avr_asm_len ("std %B0,%B1" CR_TAB
4344 "std %A0,%A1", op, plen, -2);
4345 /* (X + d) = R */
4346 return reg_src == REG_X
4347 ? avr_asm_len ("mov __tmp_reg__,r26" CR_TAB
4348 "mov __zero_reg__,r27" CR_TAB
4349 "adiw r26,%o0+1" CR_TAB
4350 "st X,__zero_reg__" CR_TAB
4351 "st -X,__tmp_reg__" CR_TAB
4352 "clr __zero_reg__" CR_TAB
4353 "sbiw r26,%o0", op, plen, -7)
4355 : avr_asm_len ("adiw r26,%o0+1" CR_TAB
4356 "st X,%B1" CR_TAB
4357 "st -X,%A1" CR_TAB
4358 "sbiw r26,%o0", op, plen, -4);
4360 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4362 return avr_asm_len ("st %0,%B1" CR_TAB
4363 "st %0,%A1", op, plen, -2);
4365 else if (GET_CODE (base) == POST_INC) /* (R++) */
4367 if (!mem_volatile_p)
4368 return avr_asm_len ("st %0,%A1" CR_TAB
4369 "st %0,%B1", op, plen, -2);
4371 return REGNO (XEXP (base, 0)) == REG_X
4372 ? avr_asm_len ("adiw r26,1" CR_TAB
4373 "st X,%B1" CR_TAB
4374 "st -X,%A1" CR_TAB
4375 "adiw r26,2", op, plen, -4)
4377 : avr_asm_len ("std %p0+1,%B1" CR_TAB
4378 "st %p0,%A1" CR_TAB
4379 "adiw %r0,2", op, plen, -3);
4381 fatal_insn ("unknown move insn:",insn);
4382 return "";
4385 /* Return 1 if frame pointer for current function required. */
4387 static bool
4388 avr_frame_pointer_required_p (void)
4390 return (cfun->calls_alloca
4391 || cfun->calls_setjmp
4392 || cfun->has_nonlocal_label
4393 || crtl->args.info.nregs == 0
4394 || get_frame_size () > 0);
4397 /* Returns the condition of compare insn INSN, or UNKNOWN. */
4399 static RTX_CODE
4400 compare_condition (rtx insn)
4402 rtx next = next_real_insn (insn);
4404 if (next && JUMP_P (next))
4406 rtx pat = PATTERN (next);
4407 rtx src = SET_SRC (pat);
4409 if (IF_THEN_ELSE == GET_CODE (src))
4410 return GET_CODE (XEXP (src, 0));
4413 return UNKNOWN;
4417 /* Returns true iff INSN is a tst insn that only tests the sign. */
4419 static bool
4420 compare_sign_p (rtx insn)
4422 RTX_CODE cond = compare_condition (insn);
4423 return (cond == GE || cond == LT);
4427 /* Returns true iff the next insn is a JUMP_INSN with a condition
4428 that needs to be swapped (GT, GTU, LE, LEU). */
4430 static bool
4431 compare_diff_p (rtx insn)
4433 RTX_CODE cond = compare_condition (insn);
4434 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
4437 /* Returns true iff INSN is a compare insn with the EQ or NE condition. */
4439 static bool
4440 compare_eq_p (rtx insn)
4442 RTX_CODE cond = compare_condition (insn);
4443 return (cond == EQ || cond == NE);
4447 /* Output compare instruction
4449 compare (XOP[0], XOP[1])
4451 for a register XOP[0] and a compile-time constant XOP[1]. Return "".
4452 XOP[2] is an 8-bit scratch register as needed.
4454 PLEN == NULL: Output instructions.
4455 PLEN != NULL: Set *PLEN to the length (in words) of the sequence.
4456 Don't output anything. */
4458 const char*
4459 avr_out_compare (rtx insn, rtx *xop, int *plen)
4461 /* Register to compare and value to compare against. */
4462 rtx xreg = xop[0];
4463 rtx xval = xop[1];
4465 /* MODE of the comparison. */
4466 enum machine_mode mode;
4468 /* Number of bytes to operate on. */
4469 int i, n_bytes = GET_MODE_SIZE (GET_MODE (xreg));
4471 /* Value (0..0xff) held in clobber register xop[2] or -1 if unknown. */
4472 int clobber_val = -1;
4474 /* Map fixed mode operands to integer operands with the same binary
4475 representation. They are easier to handle in the remainder. */
4477 if (CONST_FIXED_P (xval))
4479 xreg = avr_to_int_mode (xop[0]);
4480 xval = avr_to_int_mode (xop[1]);
4483 mode = GET_MODE (xreg);
4485 gcc_assert (REG_P (xreg));
4486 gcc_assert ((CONST_INT_P (xval) && n_bytes <= 4)
4487 || (const_double_operand (xval, VOIDmode) && n_bytes == 8));
4489 if (plen)
4490 *plen = 0;
4492 /* Comparisons == +/-1 and != +/-1 can be done similar to camparing
4493 against 0 by ORing the bytes. This is one instruction shorter.
4494 Notice that 64-bit comparisons are always against reg:ALL8 18 (ACC_A)
4495 and therefore don't use this. */
4497 if (!test_hard_reg_class (LD_REGS, xreg)
4498 && compare_eq_p (insn)
4499 && reg_unused_after (insn, xreg))
4501 if (xval == const1_rtx)
4503 avr_asm_len ("dec %A0" CR_TAB
4504 "or %A0,%B0", xop, plen, 2);
4506 if (n_bytes >= 3)
4507 avr_asm_len ("or %A0,%C0", xop, plen, 1);
4509 if (n_bytes >= 4)
4510 avr_asm_len ("or %A0,%D0", xop, plen, 1);
4512 return "";
4514 else if (xval == constm1_rtx)
4516 if (n_bytes >= 4)
4517 avr_asm_len ("and %A0,%D0", xop, plen, 1);
4519 if (n_bytes >= 3)
4520 avr_asm_len ("and %A0,%C0", xop, plen, 1);
4522 return avr_asm_len ("and %A0,%B0" CR_TAB
4523 "com %A0", xop, plen, 2);
4527 for (i = 0; i < n_bytes; i++)
4529 /* We compare byte-wise. */
4530 rtx reg8 = simplify_gen_subreg (QImode, xreg, mode, i);
4531 rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
4533 /* 8-bit value to compare with this byte. */
4534 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
4536 /* Registers R16..R31 can operate with immediate. */
4537 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
4539 xop[0] = reg8;
4540 xop[1] = gen_int_mode (val8, QImode);
4542 /* Word registers >= R24 can use SBIW/ADIW with 0..63. */
4544 if (i == 0
4545 && test_hard_reg_class (ADDW_REGS, reg8))
4547 int val16 = trunc_int_for_mode (INTVAL (xval), HImode);
4549 if (IN_RANGE (val16, 0, 63)
4550 && (val8 == 0
4551 || reg_unused_after (insn, xreg)))
4553 avr_asm_len ("sbiw %0,%1", xop, plen, 1);
4554 i++;
4555 continue;
4558 if (n_bytes == 2
4559 && IN_RANGE (val16, -63, -1)
4560 && compare_eq_p (insn)
4561 && reg_unused_after (insn, xreg))
4563 return avr_asm_len ("adiw %0,%n1", xop, plen, 1);
4567 /* Comparing against 0 is easy. */
4569 if (val8 == 0)
4571 avr_asm_len (i == 0
4572 ? "cp %0,__zero_reg__"
4573 : "cpc %0,__zero_reg__", xop, plen, 1);
4574 continue;
4577 /* Upper registers can compare and subtract-with-carry immediates.
4578 Notice that compare instructions do the same as respective subtract
4579 instruction; the only difference is that comparisons don't write
4580 the result back to the target register. */
4582 if (ld_reg_p)
4584 if (i == 0)
4586 avr_asm_len ("cpi %0,%1", xop, plen, 1);
4587 continue;
4589 else if (reg_unused_after (insn, xreg))
4591 avr_asm_len ("sbci %0,%1", xop, plen, 1);
4592 continue;
4596 /* Must load the value into the scratch register. */
4598 gcc_assert (REG_P (xop[2]));
4600 if (clobber_val != (int) val8)
4601 avr_asm_len ("ldi %2,%1", xop, plen, 1);
4602 clobber_val = (int) val8;
4604 avr_asm_len (i == 0
4605 ? "cp %0,%2"
4606 : "cpc %0,%2", xop, plen, 1);
4609 return "";
4613 /* Prepare operands of compare_const_di2 to be used with avr_out_compare. */
4615 const char*
4616 avr_out_compare64 (rtx insn, rtx *op, int *plen)
4618 rtx xop[3];
4620 xop[0] = gen_rtx_REG (DImode, 18);
4621 xop[1] = op[0];
4622 xop[2] = op[1];
4624 return avr_out_compare (insn, xop, plen);
4627 /* Output test instruction for HImode. */
4629 const char*
4630 avr_out_tsthi (rtx insn, rtx *op, int *plen)
4632 if (compare_sign_p (insn))
4634 avr_asm_len ("tst %B0", op, plen, -1);
4636 else if (reg_unused_after (insn, op[0])
4637 && compare_eq_p (insn))
4639 /* Faster than sbiw if we can clobber the operand. */
4640 avr_asm_len ("or %A0,%B0", op, plen, -1);
4642 else
4644 avr_out_compare (insn, op, plen);
4647 return "";
4651 /* Output test instruction for PSImode. */
4653 const char*
4654 avr_out_tstpsi (rtx insn, rtx *op, int *plen)
4656 if (compare_sign_p (insn))
4658 avr_asm_len ("tst %C0", op, plen, -1);
4660 else if (reg_unused_after (insn, op[0])
4661 && compare_eq_p (insn))
4663 /* Faster than sbiw if we can clobber the operand. */
4664 avr_asm_len ("or %A0,%B0" CR_TAB
4665 "or %A0,%C0", op, plen, -2);
4667 else
4669 avr_out_compare (insn, op, plen);
4672 return "";
4676 /* Output test instruction for SImode. */
4678 const char*
4679 avr_out_tstsi (rtx insn, rtx *op, int *plen)
4681 if (compare_sign_p (insn))
4683 avr_asm_len ("tst %D0", op, plen, -1);
4685 else if (reg_unused_after (insn, op[0])
4686 && compare_eq_p (insn))
4688 /* Faster than sbiw if we can clobber the operand. */
4689 avr_asm_len ("or %A0,%B0" CR_TAB
4690 "or %A0,%C0" CR_TAB
4691 "or %A0,%D0", op, plen, -3);
4693 else
4695 avr_out_compare (insn, op, plen);
4698 return "";
4702 /* Generate asm equivalent for various shifts. This only handles cases
4703 that are not already carefully hand-optimized in ?sh??i3_out.
4705 OPERANDS[0] resp. %0 in TEMPL is the operand to be shifted.
4706 OPERANDS[2] is the shift count as CONST_INT, MEM or REG.
4707 OPERANDS[3] is a QImode scratch register from LD regs if
4708 available and SCRATCH, otherwise (no scratch available)
4710 TEMPL is an assembler template that shifts by one position.
4711 T_LEN is the length of this template. */
4713 void
4714 out_shift_with_cnt (const char *templ, rtx insn, rtx operands[],
4715 int *plen, int t_len)
4717 bool second_label = true;
4718 bool saved_in_tmp = false;
4719 bool use_zero_reg = false;
4720 rtx op[5];
4722 op[0] = operands[0];
4723 op[1] = operands[1];
4724 op[2] = operands[2];
4725 op[3] = operands[3];
4727 if (plen)
4728 *plen = 0;
4730 if (CONST_INT_P (operands[2]))
4732 bool scratch = (GET_CODE (PATTERN (insn)) == PARALLEL
4733 && REG_P (operands[3]));
4734 int count = INTVAL (operands[2]);
4735 int max_len = 10; /* If larger than this, always use a loop. */
4737 if (count <= 0)
4738 return;
4740 if (count < 8 && !scratch)
4741 use_zero_reg = true;
4743 if (optimize_size)
4744 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
4746 if (t_len * count <= max_len)
4748 /* Output shifts inline with no loop - faster. */
4750 while (count-- > 0)
4751 avr_asm_len (templ, op, plen, t_len);
4753 return;
4756 if (scratch)
4758 avr_asm_len ("ldi %3,%2", op, plen, 1);
4760 else if (use_zero_reg)
4762 /* Hack to save one word: use __zero_reg__ as loop counter.
4763 Set one bit, then shift in a loop until it is 0 again. */
4765 op[3] = zero_reg_rtx;
4767 avr_asm_len ("set" CR_TAB
4768 "bld %3,%2-1", op, plen, 2);
4770 else
4772 /* No scratch register available, use one from LD_REGS (saved in
4773 __tmp_reg__) that doesn't overlap with registers to shift. */
4775 op[3] = all_regs_rtx[((REGNO (op[0]) - 1) & 15) + 16];
4776 op[4] = tmp_reg_rtx;
4777 saved_in_tmp = true;
4779 avr_asm_len ("mov %4,%3" CR_TAB
4780 "ldi %3,%2", op, plen, 2);
4783 second_label = false;
4785 else if (MEM_P (op[2]))
4787 rtx op_mov[2];
4789 op_mov[0] = op[3] = tmp_reg_rtx;
4790 op_mov[1] = op[2];
4792 out_movqi_r_mr (insn, op_mov, plen);
4794 else if (register_operand (op[2], QImode))
4796 op[3] = op[2];
4798 if (!reg_unused_after (insn, op[2])
4799 || reg_overlap_mentioned_p (op[0], op[2]))
4801 op[3] = tmp_reg_rtx;
4802 avr_asm_len ("mov %3,%2", op, plen, 1);
4805 else
4806 fatal_insn ("bad shift insn:", insn);
4808 if (second_label)
4809 avr_asm_len ("rjmp 2f", op, plen, 1);
4811 avr_asm_len ("1:", op, plen, 0);
4812 avr_asm_len (templ, op, plen, t_len);
4814 if (second_label)
4815 avr_asm_len ("2:", op, plen, 0);
4817 avr_asm_len (use_zero_reg ? "lsr %3" : "dec %3", op, plen, 1);
4818 avr_asm_len (second_label ? "brpl 1b" : "brne 1b", op, plen, 1);
4820 if (saved_in_tmp)
4821 avr_asm_len ("mov %3,%4", op, plen, 1);
4825 /* 8bit shift left ((char)x << i) */
4827 const char *
4828 ashlqi3_out (rtx insn, rtx operands[], int *len)
4830 if (GET_CODE (operands[2]) == CONST_INT)
4832 int k;
4834 if (!len)
4835 len = &k;
4837 switch (INTVAL (operands[2]))
4839 default:
4840 if (INTVAL (operands[2]) < 8)
4841 break;
4843 *len = 1;
4844 return "clr %0";
4846 case 1:
4847 *len = 1;
4848 return "lsl %0";
4850 case 2:
4851 *len = 2;
4852 return ("lsl %0" CR_TAB
4853 "lsl %0");
4855 case 3:
4856 *len = 3;
4857 return ("lsl %0" CR_TAB
4858 "lsl %0" CR_TAB
4859 "lsl %0");
4861 case 4:
4862 if (test_hard_reg_class (LD_REGS, operands[0]))
4864 *len = 2;
4865 return ("swap %0" CR_TAB
4866 "andi %0,0xf0");
4868 *len = 4;
4869 return ("lsl %0" CR_TAB
4870 "lsl %0" CR_TAB
4871 "lsl %0" CR_TAB
4872 "lsl %0");
4874 case 5:
4875 if (test_hard_reg_class (LD_REGS, operands[0]))
4877 *len = 3;
4878 return ("swap %0" CR_TAB
4879 "lsl %0" CR_TAB
4880 "andi %0,0xe0");
4882 *len = 5;
4883 return ("lsl %0" CR_TAB
4884 "lsl %0" CR_TAB
4885 "lsl %0" CR_TAB
4886 "lsl %0" CR_TAB
4887 "lsl %0");
4889 case 6:
4890 if (test_hard_reg_class (LD_REGS, operands[0]))
4892 *len = 4;
4893 return ("swap %0" CR_TAB
4894 "lsl %0" CR_TAB
4895 "lsl %0" CR_TAB
4896 "andi %0,0xc0");
4898 *len = 6;
4899 return ("lsl %0" CR_TAB
4900 "lsl %0" CR_TAB
4901 "lsl %0" CR_TAB
4902 "lsl %0" CR_TAB
4903 "lsl %0" CR_TAB
4904 "lsl %0");
4906 case 7:
4907 *len = 3;
4908 return ("ror %0" CR_TAB
4909 "clr %0" CR_TAB
4910 "ror %0");
4913 else if (CONSTANT_P (operands[2]))
4914 fatal_insn ("internal compiler error. Incorrect shift:", insn);
4916 out_shift_with_cnt ("lsl %0",
4917 insn, operands, len, 1);
4918 return "";
4922 /* 16bit shift left ((short)x << i) */
4924 const char *
4925 ashlhi3_out (rtx insn, rtx operands[], int *len)
4927 if (GET_CODE (operands[2]) == CONST_INT)
4929 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
4930 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
4931 int k;
4932 int *t = len;
4934 if (!len)
4935 len = &k;
4937 switch (INTVAL (operands[2]))
4939 default:
4940 if (INTVAL (operands[2]) < 16)
4941 break;
4943 *len = 2;
4944 return ("clr %B0" CR_TAB
4945 "clr %A0");
4947 case 4:
4948 if (optimize_size && scratch)
4949 break; /* 5 */
4950 if (ldi_ok)
4952 *len = 6;
4953 return ("swap %A0" CR_TAB
4954 "swap %B0" CR_TAB
4955 "andi %B0,0xf0" CR_TAB
4956 "eor %B0,%A0" CR_TAB
4957 "andi %A0,0xf0" CR_TAB
4958 "eor %B0,%A0");
4960 if (scratch)
4962 *len = 7;
4963 return ("swap %A0" CR_TAB
4964 "swap %B0" CR_TAB
4965 "ldi %3,0xf0" CR_TAB
4966 "and %B0,%3" CR_TAB
4967 "eor %B0,%A0" CR_TAB
4968 "and %A0,%3" CR_TAB
4969 "eor %B0,%A0");
4971 break; /* optimize_size ? 6 : 8 */
4973 case 5:
4974 if (optimize_size)
4975 break; /* scratch ? 5 : 6 */
4976 if (ldi_ok)
4978 *len = 8;
4979 return ("lsl %A0" CR_TAB
4980 "rol %B0" CR_TAB
4981 "swap %A0" CR_TAB
4982 "swap %B0" CR_TAB
4983 "andi %B0,0xf0" CR_TAB
4984 "eor %B0,%A0" CR_TAB
4985 "andi %A0,0xf0" CR_TAB
4986 "eor %B0,%A0");
4988 if (scratch)
4990 *len = 9;
4991 return ("lsl %A0" CR_TAB
4992 "rol %B0" CR_TAB
4993 "swap %A0" CR_TAB
4994 "swap %B0" CR_TAB
4995 "ldi %3,0xf0" CR_TAB
4996 "and %B0,%3" CR_TAB
4997 "eor %B0,%A0" CR_TAB
4998 "and %A0,%3" CR_TAB
4999 "eor %B0,%A0");
5001 break; /* 10 */
5003 case 6:
5004 if (optimize_size)
5005 break; /* scratch ? 5 : 6 */
5006 *len = 9;
5007 return ("clr __tmp_reg__" CR_TAB
5008 "lsr %B0" CR_TAB
5009 "ror %A0" CR_TAB
5010 "ror __tmp_reg__" CR_TAB
5011 "lsr %B0" CR_TAB
5012 "ror %A0" CR_TAB
5013 "ror __tmp_reg__" CR_TAB
5014 "mov %B0,%A0" CR_TAB
5015 "mov %A0,__tmp_reg__");
5017 case 7:
5018 *len = 5;
5019 return ("lsr %B0" CR_TAB
5020 "mov %B0,%A0" CR_TAB
5021 "clr %A0" CR_TAB
5022 "ror %B0" CR_TAB
5023 "ror %A0");
5025 case 8:
5026 return *len = 2, ("mov %B0,%A1" CR_TAB
5027 "clr %A0");
5029 case 9:
5030 *len = 3;
5031 return ("mov %B0,%A0" CR_TAB
5032 "clr %A0" CR_TAB
5033 "lsl %B0");
5035 case 10:
5036 *len = 4;
5037 return ("mov %B0,%A0" CR_TAB
5038 "clr %A0" CR_TAB
5039 "lsl %B0" CR_TAB
5040 "lsl %B0");
5042 case 11:
5043 *len = 5;
5044 return ("mov %B0,%A0" CR_TAB
5045 "clr %A0" CR_TAB
5046 "lsl %B0" CR_TAB
5047 "lsl %B0" CR_TAB
5048 "lsl %B0");
5050 case 12:
5051 if (ldi_ok)
5053 *len = 4;
5054 return ("mov %B0,%A0" CR_TAB
5055 "clr %A0" CR_TAB
5056 "swap %B0" CR_TAB
5057 "andi %B0,0xf0");
5059 if (scratch)
5061 *len = 5;
5062 return ("mov %B0,%A0" CR_TAB
5063 "clr %A0" CR_TAB
5064 "swap %B0" CR_TAB
5065 "ldi %3,0xf0" CR_TAB
5066 "and %B0,%3");
5068 *len = 6;
5069 return ("mov %B0,%A0" CR_TAB
5070 "clr %A0" CR_TAB
5071 "lsl %B0" CR_TAB
5072 "lsl %B0" CR_TAB
5073 "lsl %B0" CR_TAB
5074 "lsl %B0");
5076 case 13:
5077 if (ldi_ok)
5079 *len = 5;
5080 return ("mov %B0,%A0" CR_TAB
5081 "clr %A0" CR_TAB
5082 "swap %B0" CR_TAB
5083 "lsl %B0" CR_TAB
5084 "andi %B0,0xe0");
5086 if (AVR_HAVE_MUL && scratch)
5088 *len = 5;
5089 return ("ldi %3,0x20" CR_TAB
5090 "mul %A0,%3" CR_TAB
5091 "mov %B0,r0" CR_TAB
5092 "clr %A0" CR_TAB
5093 "clr __zero_reg__");
5095 if (optimize_size && scratch)
5096 break; /* 5 */
5097 if (scratch)
5099 *len = 6;
5100 return ("mov %B0,%A0" CR_TAB
5101 "clr %A0" CR_TAB
5102 "swap %B0" CR_TAB
5103 "lsl %B0" CR_TAB
5104 "ldi %3,0xe0" CR_TAB
5105 "and %B0,%3");
5107 if (AVR_HAVE_MUL)
5109 *len = 6;
5110 return ("set" CR_TAB
5111 "bld r1,5" CR_TAB
5112 "mul %A0,r1" CR_TAB
5113 "mov %B0,r0" CR_TAB
5114 "clr %A0" CR_TAB
5115 "clr __zero_reg__");
5117 *len = 7;
5118 return ("mov %B0,%A0" CR_TAB
5119 "clr %A0" CR_TAB
5120 "lsl %B0" CR_TAB
5121 "lsl %B0" CR_TAB
5122 "lsl %B0" CR_TAB
5123 "lsl %B0" CR_TAB
5124 "lsl %B0");
5126 case 14:
5127 if (AVR_HAVE_MUL && ldi_ok)
5129 *len = 5;
5130 return ("ldi %B0,0x40" CR_TAB
5131 "mul %A0,%B0" CR_TAB
5132 "mov %B0,r0" CR_TAB
5133 "clr %A0" CR_TAB
5134 "clr __zero_reg__");
5136 if (AVR_HAVE_MUL && scratch)
5138 *len = 5;
5139 return ("ldi %3,0x40" CR_TAB
5140 "mul %A0,%3" CR_TAB
5141 "mov %B0,r0" CR_TAB
5142 "clr %A0" CR_TAB
5143 "clr __zero_reg__");
5145 if (optimize_size && ldi_ok)
5147 *len = 5;
5148 return ("mov %B0,%A0" CR_TAB
5149 "ldi %A0,6" "\n1:\t"
5150 "lsl %B0" CR_TAB
5151 "dec %A0" CR_TAB
5152 "brne 1b");
5154 if (optimize_size && scratch)
5155 break; /* 5 */
5156 *len = 6;
5157 return ("clr %B0" CR_TAB
5158 "lsr %A0" CR_TAB
5159 "ror %B0" CR_TAB
5160 "lsr %A0" CR_TAB
5161 "ror %B0" CR_TAB
5162 "clr %A0");
5164 case 15:
5165 *len = 4;
5166 return ("clr %B0" CR_TAB
5167 "lsr %A0" CR_TAB
5168 "ror %B0" CR_TAB
5169 "clr %A0");
5171 len = t;
5173 out_shift_with_cnt ("lsl %A0" CR_TAB
5174 "rol %B0", insn, operands, len, 2);
5175 return "";
5179 /* 24-bit shift left */
5181 const char*
5182 avr_out_ashlpsi3 (rtx insn, rtx *op, int *plen)
5184 if (plen)
5185 *plen = 0;
5187 if (CONST_INT_P (op[2]))
5189 switch (INTVAL (op[2]))
5191 default:
5192 if (INTVAL (op[2]) < 24)
5193 break;
5195 return avr_asm_len ("clr %A0" CR_TAB
5196 "clr %B0" CR_TAB
5197 "clr %C0", op, plen, 3);
5199 case 8:
5201 int reg0 = REGNO (op[0]);
5202 int reg1 = REGNO (op[1]);
5204 if (reg0 >= reg1)
5205 return avr_asm_len ("mov %C0,%B1" CR_TAB
5206 "mov %B0,%A1" CR_TAB
5207 "clr %A0", op, plen, 3);
5208 else
5209 return avr_asm_len ("clr %A0" CR_TAB
5210 "mov %B0,%A1" CR_TAB
5211 "mov %C0,%B1", op, plen, 3);
5214 case 16:
5216 int reg0 = REGNO (op[0]);
5217 int reg1 = REGNO (op[1]);
5219 if (reg0 + 2 != reg1)
5220 avr_asm_len ("mov %C0,%A0", op, plen, 1);
5222 return avr_asm_len ("clr %B0" CR_TAB
5223 "clr %A0", op, plen, 2);
5226 case 23:
5227 return avr_asm_len ("clr %C0" CR_TAB
5228 "lsr %A0" CR_TAB
5229 "ror %C0" CR_TAB
5230 "clr %B0" CR_TAB
5231 "clr %A0", op, plen, 5);
5235 out_shift_with_cnt ("lsl %A0" CR_TAB
5236 "rol %B0" CR_TAB
5237 "rol %C0", insn, op, plen, 3);
5238 return "";
5242 /* 32bit shift left ((long)x << i) */
5244 const char *
5245 ashlsi3_out (rtx insn, rtx operands[], int *len)
5247 if (GET_CODE (operands[2]) == CONST_INT)
5249 int k;
5250 int *t = len;
5252 if (!len)
5253 len = &k;
5255 switch (INTVAL (operands[2]))
5257 default:
5258 if (INTVAL (operands[2]) < 32)
5259 break;
5261 if (AVR_HAVE_MOVW)
5262 return *len = 3, ("clr %D0" CR_TAB
5263 "clr %C0" CR_TAB
5264 "movw %A0,%C0");
5265 *len = 4;
5266 return ("clr %D0" CR_TAB
5267 "clr %C0" CR_TAB
5268 "clr %B0" CR_TAB
5269 "clr %A0");
5271 case 8:
5273 int reg0 = true_regnum (operands[0]);
5274 int reg1 = true_regnum (operands[1]);
5275 *len = 4;
5276 if (reg0 >= reg1)
5277 return ("mov %D0,%C1" CR_TAB
5278 "mov %C0,%B1" CR_TAB
5279 "mov %B0,%A1" CR_TAB
5280 "clr %A0");
5281 else
5282 return ("clr %A0" CR_TAB
5283 "mov %B0,%A1" CR_TAB
5284 "mov %C0,%B1" CR_TAB
5285 "mov %D0,%C1");
5288 case 16:
5290 int reg0 = true_regnum (operands[0]);
5291 int reg1 = true_regnum (operands[1]);
5292 if (reg0 + 2 == reg1)
5293 return *len = 2, ("clr %B0" CR_TAB
5294 "clr %A0");
5295 if (AVR_HAVE_MOVW)
5296 return *len = 3, ("movw %C0,%A1" CR_TAB
5297 "clr %B0" CR_TAB
5298 "clr %A0");
5299 else
5300 return *len = 4, ("mov %C0,%A1" CR_TAB
5301 "mov %D0,%B1" CR_TAB
5302 "clr %B0" CR_TAB
5303 "clr %A0");
5306 case 24:
5307 *len = 4;
5308 return ("mov %D0,%A1" CR_TAB
5309 "clr %C0" CR_TAB
5310 "clr %B0" CR_TAB
5311 "clr %A0");
5313 case 31:
5314 *len = 6;
5315 return ("clr %D0" CR_TAB
5316 "lsr %A0" CR_TAB
5317 "ror %D0" CR_TAB
5318 "clr %C0" CR_TAB
5319 "clr %B0" CR_TAB
5320 "clr %A0");
5322 len = t;
5324 out_shift_with_cnt ("lsl %A0" CR_TAB
5325 "rol %B0" CR_TAB
5326 "rol %C0" CR_TAB
5327 "rol %D0", insn, operands, len, 4);
5328 return "";
5331 /* 8bit arithmetic shift right ((signed char)x >> i) */
5333 const char *
5334 ashrqi3_out (rtx insn, rtx operands[], int *len)
5336 if (GET_CODE (operands[2]) == CONST_INT)
5338 int k;
5340 if (!len)
5341 len = &k;
5343 switch (INTVAL (operands[2]))
5345 case 1:
5346 *len = 1;
5347 return "asr %0";
5349 case 2:
5350 *len = 2;
5351 return ("asr %0" CR_TAB
5352 "asr %0");
5354 case 3:
5355 *len = 3;
5356 return ("asr %0" CR_TAB
5357 "asr %0" CR_TAB
5358 "asr %0");
5360 case 4:
5361 *len = 4;
5362 return ("asr %0" CR_TAB
5363 "asr %0" CR_TAB
5364 "asr %0" CR_TAB
5365 "asr %0");
5367 case 5:
5368 *len = 5;
5369 return ("asr %0" CR_TAB
5370 "asr %0" CR_TAB
5371 "asr %0" CR_TAB
5372 "asr %0" CR_TAB
5373 "asr %0");
5375 case 6:
5376 *len = 4;
5377 return ("bst %0,6" CR_TAB
5378 "lsl %0" CR_TAB
5379 "sbc %0,%0" CR_TAB
5380 "bld %0,0");
5382 default:
5383 if (INTVAL (operands[2]) < 8)
5384 break;
5386 /* fall through */
5388 case 7:
5389 *len = 2;
5390 return ("lsl %0" CR_TAB
5391 "sbc %0,%0");
5394 else if (CONSTANT_P (operands[2]))
5395 fatal_insn ("internal compiler error. Incorrect shift:", insn);
5397 out_shift_with_cnt ("asr %0",
5398 insn, operands, len, 1);
5399 return "";
5403 /* 16bit arithmetic shift right ((signed short)x >> i) */
5405 const char *
5406 ashrhi3_out (rtx insn, rtx operands[], int *len)
5408 if (GET_CODE (operands[2]) == CONST_INT)
5410 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
5411 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
5412 int k;
5413 int *t = len;
5415 if (!len)
5416 len = &k;
5418 switch (INTVAL (operands[2]))
5420 case 4:
5421 case 5:
5422 /* XXX try to optimize this too? */
5423 break;
5425 case 6:
5426 if (optimize_size)
5427 break; /* scratch ? 5 : 6 */
5428 *len = 8;
5429 return ("mov __tmp_reg__,%A0" CR_TAB
5430 "mov %A0,%B0" CR_TAB
5431 "lsl __tmp_reg__" CR_TAB
5432 "rol %A0" CR_TAB
5433 "sbc %B0,%B0" CR_TAB
5434 "lsl __tmp_reg__" CR_TAB
5435 "rol %A0" CR_TAB
5436 "rol %B0");
5438 case 7:
5439 *len = 4;
5440 return ("lsl %A0" CR_TAB
5441 "mov %A0,%B0" CR_TAB
5442 "rol %A0" CR_TAB
5443 "sbc %B0,%B0");
5445 case 8:
5447 int reg0 = true_regnum (operands[0]);
5448 int reg1 = true_regnum (operands[1]);
5450 if (reg0 == reg1)
5451 return *len = 3, ("mov %A0,%B0" CR_TAB
5452 "lsl %B0" CR_TAB
5453 "sbc %B0,%B0");
5454 else
5455 return *len = 4, ("mov %A0,%B1" CR_TAB
5456 "clr %B0" CR_TAB
5457 "sbrc %A0,7" CR_TAB
5458 "dec %B0");
5461 case 9:
5462 *len = 4;
5463 return ("mov %A0,%B0" CR_TAB
5464 "lsl %B0" CR_TAB
5465 "sbc %B0,%B0" CR_TAB
5466 "asr %A0");
5468 case 10:
5469 *len = 5;
5470 return ("mov %A0,%B0" CR_TAB
5471 "lsl %B0" CR_TAB
5472 "sbc %B0,%B0" CR_TAB
5473 "asr %A0" CR_TAB
5474 "asr %A0");
5476 case 11:
5477 if (AVR_HAVE_MUL && ldi_ok)
5479 *len = 5;
5480 return ("ldi %A0,0x20" CR_TAB
5481 "muls %B0,%A0" CR_TAB
5482 "mov %A0,r1" CR_TAB
5483 "sbc %B0,%B0" CR_TAB
5484 "clr __zero_reg__");
5486 if (optimize_size && scratch)
5487 break; /* 5 */
5488 *len = 6;
5489 return ("mov %A0,%B0" CR_TAB
5490 "lsl %B0" CR_TAB
5491 "sbc %B0,%B0" CR_TAB
5492 "asr %A0" CR_TAB
5493 "asr %A0" CR_TAB
5494 "asr %A0");
5496 case 12:
5497 if (AVR_HAVE_MUL && ldi_ok)
5499 *len = 5;
5500 return ("ldi %A0,0x10" CR_TAB
5501 "muls %B0,%A0" CR_TAB
5502 "mov %A0,r1" CR_TAB
5503 "sbc %B0,%B0" CR_TAB
5504 "clr __zero_reg__");
5506 if (optimize_size && scratch)
5507 break; /* 5 */
5508 *len = 7;
5509 return ("mov %A0,%B0" CR_TAB
5510 "lsl %B0" CR_TAB
5511 "sbc %B0,%B0" CR_TAB
5512 "asr %A0" CR_TAB
5513 "asr %A0" CR_TAB
5514 "asr %A0" CR_TAB
5515 "asr %A0");
5517 case 13:
5518 if (AVR_HAVE_MUL && ldi_ok)
5520 *len = 5;
5521 return ("ldi %A0,0x08" CR_TAB
5522 "muls %B0,%A0" CR_TAB
5523 "mov %A0,r1" CR_TAB
5524 "sbc %B0,%B0" CR_TAB
5525 "clr __zero_reg__");
5527 if (optimize_size)
5528 break; /* scratch ? 5 : 7 */
5529 *len = 8;
5530 return ("mov %A0,%B0" CR_TAB
5531 "lsl %B0" CR_TAB
5532 "sbc %B0,%B0" CR_TAB
5533 "asr %A0" CR_TAB
5534 "asr %A0" CR_TAB
5535 "asr %A0" CR_TAB
5536 "asr %A0" CR_TAB
5537 "asr %A0");
5539 case 14:
5540 *len = 5;
5541 return ("lsl %B0" CR_TAB
5542 "sbc %A0,%A0" CR_TAB
5543 "lsl %B0" CR_TAB
5544 "mov %B0,%A0" CR_TAB
5545 "rol %A0");
5547 default:
5548 if (INTVAL (operands[2]) < 16)
5549 break;
5551 /* fall through */
5553 case 15:
5554 return *len = 3, ("lsl %B0" CR_TAB
5555 "sbc %A0,%A0" CR_TAB
5556 "mov %B0,%A0");
5558 len = t;
5560 out_shift_with_cnt ("asr %B0" CR_TAB
5561 "ror %A0", insn, operands, len, 2);
5562 return "";
5566 /* 24-bit arithmetic shift right */
5568 const char*
5569 avr_out_ashrpsi3 (rtx insn, rtx *op, int *plen)
5571 int dest = REGNO (op[0]);
5572 int src = REGNO (op[1]);
5574 if (CONST_INT_P (op[2]))
5576 if (plen)
5577 *plen = 0;
5579 switch (INTVAL (op[2]))
5581 case 8:
5582 if (dest <= src)
5583 return avr_asm_len ("mov %A0,%B1" CR_TAB
5584 "mov %B0,%C1" CR_TAB
5585 "clr %C0" CR_TAB
5586 "sbrc %B0,7" CR_TAB
5587 "dec %C0", op, plen, 5);
5588 else
5589 return avr_asm_len ("clr %C0" CR_TAB
5590 "sbrc %C1,7" CR_TAB
5591 "dec %C0" CR_TAB
5592 "mov %B0,%C1" CR_TAB
5593 "mov %A0,%B1", op, plen, 5);
5595 case 16:
5596 if (dest != src + 2)
5597 avr_asm_len ("mov %A0,%C1", op, plen, 1);
5599 return avr_asm_len ("clr %B0" CR_TAB
5600 "sbrc %A0,7" CR_TAB
5601 "com %B0" CR_TAB
5602 "mov %C0,%B0", op, plen, 4);
5604 default:
5605 if (INTVAL (op[2]) < 24)
5606 break;
5608 /* fall through */
5610 case 23:
5611 return avr_asm_len ("lsl %C0" CR_TAB
5612 "sbc %A0,%A0" CR_TAB
5613 "mov %B0,%A0" CR_TAB
5614 "mov %C0,%A0", op, plen, 4);
5615 } /* switch */
5618 out_shift_with_cnt ("asr %C0" CR_TAB
5619 "ror %B0" CR_TAB
5620 "ror %A0", insn, op, plen, 3);
5621 return "";
5625 /* 32-bit arithmetic shift right ((signed long)x >> i) */
5627 const char *
5628 ashrsi3_out (rtx insn, rtx operands[], int *len)
5630 if (GET_CODE (operands[2]) == CONST_INT)
5632 int k;
5633 int *t = len;
5635 if (!len)
5636 len = &k;
5638 switch (INTVAL (operands[2]))
5640 case 8:
5642 int reg0 = true_regnum (operands[0]);
5643 int reg1 = true_regnum (operands[1]);
5644 *len=6;
5645 if (reg0 <= reg1)
5646 return ("mov %A0,%B1" CR_TAB
5647 "mov %B0,%C1" CR_TAB
5648 "mov %C0,%D1" CR_TAB
5649 "clr %D0" CR_TAB
5650 "sbrc %C0,7" CR_TAB
5651 "dec %D0");
5652 else
5653 return ("clr %D0" CR_TAB
5654 "sbrc %D1,7" CR_TAB
5655 "dec %D0" CR_TAB
5656 "mov %C0,%D1" CR_TAB
5657 "mov %B0,%C1" CR_TAB
5658 "mov %A0,%B1");
5661 case 16:
5663 int reg0 = true_regnum (operands[0]);
5664 int reg1 = true_regnum (operands[1]);
5666 if (reg0 == reg1 + 2)
5667 return *len = 4, ("clr %D0" CR_TAB
5668 "sbrc %B0,7" CR_TAB
5669 "com %D0" CR_TAB
5670 "mov %C0,%D0");
5671 if (AVR_HAVE_MOVW)
5672 return *len = 5, ("movw %A0,%C1" CR_TAB
5673 "clr %D0" CR_TAB
5674 "sbrc %B0,7" CR_TAB
5675 "com %D0" CR_TAB
5676 "mov %C0,%D0");
5677 else
5678 return *len = 6, ("mov %B0,%D1" CR_TAB
5679 "mov %A0,%C1" CR_TAB
5680 "clr %D0" CR_TAB
5681 "sbrc %B0,7" CR_TAB
5682 "com %D0" CR_TAB
5683 "mov %C0,%D0");
5686 case 24:
5687 return *len = 6, ("mov %A0,%D1" CR_TAB
5688 "clr %D0" CR_TAB
5689 "sbrc %A0,7" CR_TAB
5690 "com %D0" CR_TAB
5691 "mov %B0,%D0" CR_TAB
5692 "mov %C0,%D0");
5694 default:
5695 if (INTVAL (operands[2]) < 32)
5696 break;
5698 /* fall through */
5700 case 31:
5701 if (AVR_HAVE_MOVW)
5702 return *len = 4, ("lsl %D0" CR_TAB
5703 "sbc %A0,%A0" CR_TAB
5704 "mov %B0,%A0" CR_TAB
5705 "movw %C0,%A0");
5706 else
5707 return *len = 5, ("lsl %D0" CR_TAB
5708 "sbc %A0,%A0" CR_TAB
5709 "mov %B0,%A0" CR_TAB
5710 "mov %C0,%A0" CR_TAB
5711 "mov %D0,%A0");
5713 len = t;
5715 out_shift_with_cnt ("asr %D0" CR_TAB
5716 "ror %C0" CR_TAB
5717 "ror %B0" CR_TAB
5718 "ror %A0", insn, operands, len, 4);
5719 return "";
5722 /* 8-bit logic shift right ((unsigned char)x >> i) */
5724 const char *
5725 lshrqi3_out (rtx insn, rtx operands[], int *len)
5727 if (GET_CODE (operands[2]) == CONST_INT)
5729 int k;
5731 if (!len)
5732 len = &k;
5734 switch (INTVAL (operands[2]))
5736 default:
5737 if (INTVAL (operands[2]) < 8)
5738 break;
5740 *len = 1;
5741 return "clr %0";
5743 case 1:
5744 *len = 1;
5745 return "lsr %0";
5747 case 2:
5748 *len = 2;
5749 return ("lsr %0" CR_TAB
5750 "lsr %0");
5751 case 3:
5752 *len = 3;
5753 return ("lsr %0" CR_TAB
5754 "lsr %0" CR_TAB
5755 "lsr %0");
5757 case 4:
5758 if (test_hard_reg_class (LD_REGS, operands[0]))
5760 *len=2;
5761 return ("swap %0" CR_TAB
5762 "andi %0,0x0f");
5764 *len = 4;
5765 return ("lsr %0" CR_TAB
5766 "lsr %0" CR_TAB
5767 "lsr %0" CR_TAB
5768 "lsr %0");
5770 case 5:
5771 if (test_hard_reg_class (LD_REGS, operands[0]))
5773 *len = 3;
5774 return ("swap %0" CR_TAB
5775 "lsr %0" CR_TAB
5776 "andi %0,0x7");
5778 *len = 5;
5779 return ("lsr %0" CR_TAB
5780 "lsr %0" CR_TAB
5781 "lsr %0" CR_TAB
5782 "lsr %0" CR_TAB
5783 "lsr %0");
5785 case 6:
5786 if (test_hard_reg_class (LD_REGS, operands[0]))
5788 *len = 4;
5789 return ("swap %0" CR_TAB
5790 "lsr %0" CR_TAB
5791 "lsr %0" CR_TAB
5792 "andi %0,0x3");
5794 *len = 6;
5795 return ("lsr %0" CR_TAB
5796 "lsr %0" CR_TAB
5797 "lsr %0" CR_TAB
5798 "lsr %0" CR_TAB
5799 "lsr %0" CR_TAB
5800 "lsr %0");
5802 case 7:
5803 *len = 3;
5804 return ("rol %0" CR_TAB
5805 "clr %0" CR_TAB
5806 "rol %0");
5809 else if (CONSTANT_P (operands[2]))
5810 fatal_insn ("internal compiler error. Incorrect shift:", insn);
5812 out_shift_with_cnt ("lsr %0",
5813 insn, operands, len, 1);
5814 return "";
5817 /* 16-bit logic shift right ((unsigned short)x >> i) */
5819 const char *
5820 lshrhi3_out (rtx insn, rtx operands[], int *len)
5822 if (GET_CODE (operands[2]) == CONST_INT)
5824 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
5825 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
5826 int k;
5827 int *t = len;
5829 if (!len)
5830 len = &k;
5832 switch (INTVAL (operands[2]))
5834 default:
5835 if (INTVAL (operands[2]) < 16)
5836 break;
5838 *len = 2;
5839 return ("clr %B0" CR_TAB
5840 "clr %A0");
5842 case 4:
5843 if (optimize_size && scratch)
5844 break; /* 5 */
5845 if (ldi_ok)
5847 *len = 6;
5848 return ("swap %B0" CR_TAB
5849 "swap %A0" CR_TAB
5850 "andi %A0,0x0f" CR_TAB
5851 "eor %A0,%B0" CR_TAB
5852 "andi %B0,0x0f" CR_TAB
5853 "eor %A0,%B0");
5855 if (scratch)
5857 *len = 7;
5858 return ("swap %B0" CR_TAB
5859 "swap %A0" CR_TAB
5860 "ldi %3,0x0f" CR_TAB
5861 "and %A0,%3" CR_TAB
5862 "eor %A0,%B0" CR_TAB
5863 "and %B0,%3" CR_TAB
5864 "eor %A0,%B0");
5866 break; /* optimize_size ? 6 : 8 */
5868 case 5:
5869 if (optimize_size)
5870 break; /* scratch ? 5 : 6 */
5871 if (ldi_ok)
5873 *len = 8;
5874 return ("lsr %B0" CR_TAB
5875 "ror %A0" CR_TAB
5876 "swap %B0" CR_TAB
5877 "swap %A0" CR_TAB
5878 "andi %A0,0x0f" CR_TAB
5879 "eor %A0,%B0" CR_TAB
5880 "andi %B0,0x0f" CR_TAB
5881 "eor %A0,%B0");
5883 if (scratch)
5885 *len = 9;
5886 return ("lsr %B0" CR_TAB
5887 "ror %A0" CR_TAB
5888 "swap %B0" CR_TAB
5889 "swap %A0" CR_TAB
5890 "ldi %3,0x0f" CR_TAB
5891 "and %A0,%3" CR_TAB
5892 "eor %A0,%B0" CR_TAB
5893 "and %B0,%3" CR_TAB
5894 "eor %A0,%B0");
5896 break; /* 10 */
5898 case 6:
5899 if (optimize_size)
5900 break; /* scratch ? 5 : 6 */
5901 *len = 9;
5902 return ("clr __tmp_reg__" CR_TAB
5903 "lsl %A0" CR_TAB
5904 "rol %B0" CR_TAB
5905 "rol __tmp_reg__" CR_TAB
5906 "lsl %A0" CR_TAB
5907 "rol %B0" CR_TAB
5908 "rol __tmp_reg__" CR_TAB
5909 "mov %A0,%B0" CR_TAB
5910 "mov %B0,__tmp_reg__");
5912 case 7:
5913 *len = 5;
5914 return ("lsl %A0" CR_TAB
5915 "mov %A0,%B0" CR_TAB
5916 "rol %A0" CR_TAB
5917 "sbc %B0,%B0" CR_TAB
5918 "neg %B0");
5920 case 8:
5921 return *len = 2, ("mov %A0,%B1" CR_TAB
5922 "clr %B0");
5924 case 9:
5925 *len = 3;
5926 return ("mov %A0,%B0" CR_TAB
5927 "clr %B0" CR_TAB
5928 "lsr %A0");
5930 case 10:
5931 *len = 4;
5932 return ("mov %A0,%B0" CR_TAB
5933 "clr %B0" CR_TAB
5934 "lsr %A0" CR_TAB
5935 "lsr %A0");
5937 case 11:
5938 *len = 5;
5939 return ("mov %A0,%B0" CR_TAB
5940 "clr %B0" CR_TAB
5941 "lsr %A0" CR_TAB
5942 "lsr %A0" CR_TAB
5943 "lsr %A0");
5945 case 12:
5946 if (ldi_ok)
5948 *len = 4;
5949 return ("mov %A0,%B0" CR_TAB
5950 "clr %B0" CR_TAB
5951 "swap %A0" CR_TAB
5952 "andi %A0,0x0f");
5954 if (scratch)
5956 *len = 5;
5957 return ("mov %A0,%B0" CR_TAB
5958 "clr %B0" CR_TAB
5959 "swap %A0" CR_TAB
5960 "ldi %3,0x0f" CR_TAB
5961 "and %A0,%3");
5963 *len = 6;
5964 return ("mov %A0,%B0" CR_TAB
5965 "clr %B0" CR_TAB
5966 "lsr %A0" CR_TAB
5967 "lsr %A0" CR_TAB
5968 "lsr %A0" CR_TAB
5969 "lsr %A0");
5971 case 13:
5972 if (ldi_ok)
5974 *len = 5;
5975 return ("mov %A0,%B0" CR_TAB
5976 "clr %B0" CR_TAB
5977 "swap %A0" CR_TAB
5978 "lsr %A0" CR_TAB
5979 "andi %A0,0x07");
5981 if (AVR_HAVE_MUL && scratch)
5983 *len = 5;
5984 return ("ldi %3,0x08" CR_TAB
5985 "mul %B0,%3" CR_TAB
5986 "mov %A0,r1" CR_TAB
5987 "clr %B0" CR_TAB
5988 "clr __zero_reg__");
5990 if (optimize_size && scratch)
5991 break; /* 5 */
5992 if (scratch)
5994 *len = 6;
5995 return ("mov %A0,%B0" CR_TAB
5996 "clr %B0" CR_TAB
5997 "swap %A0" CR_TAB
5998 "lsr %A0" CR_TAB
5999 "ldi %3,0x07" CR_TAB
6000 "and %A0,%3");
6002 if (AVR_HAVE_MUL)
6004 *len = 6;
6005 return ("set" CR_TAB
6006 "bld r1,3" CR_TAB
6007 "mul %B0,r1" CR_TAB
6008 "mov %A0,r1" CR_TAB
6009 "clr %B0" CR_TAB
6010 "clr __zero_reg__");
6012 *len = 7;
6013 return ("mov %A0,%B0" CR_TAB
6014 "clr %B0" CR_TAB
6015 "lsr %A0" CR_TAB
6016 "lsr %A0" CR_TAB
6017 "lsr %A0" CR_TAB
6018 "lsr %A0" CR_TAB
6019 "lsr %A0");
6021 case 14:
6022 if (AVR_HAVE_MUL && ldi_ok)
6024 *len = 5;
6025 return ("ldi %A0,0x04" CR_TAB
6026 "mul %B0,%A0" CR_TAB
6027 "mov %A0,r1" CR_TAB
6028 "clr %B0" CR_TAB
6029 "clr __zero_reg__");
6031 if (AVR_HAVE_MUL && scratch)
6033 *len = 5;
6034 return ("ldi %3,0x04" CR_TAB
6035 "mul %B0,%3" CR_TAB
6036 "mov %A0,r1" CR_TAB
6037 "clr %B0" CR_TAB
6038 "clr __zero_reg__");
6040 if (optimize_size && ldi_ok)
6042 *len = 5;
6043 return ("mov %A0,%B0" CR_TAB
6044 "ldi %B0,6" "\n1:\t"
6045 "lsr %A0" CR_TAB
6046 "dec %B0" CR_TAB
6047 "brne 1b");
6049 if (optimize_size && scratch)
6050 break; /* 5 */
6051 *len = 6;
6052 return ("clr %A0" CR_TAB
6053 "lsl %B0" CR_TAB
6054 "rol %A0" CR_TAB
6055 "lsl %B0" CR_TAB
6056 "rol %A0" CR_TAB
6057 "clr %B0");
6059 case 15:
6060 *len = 4;
6061 return ("clr %A0" CR_TAB
6062 "lsl %B0" CR_TAB
6063 "rol %A0" CR_TAB
6064 "clr %B0");
6066 len = t;
6068 out_shift_with_cnt ("lsr %B0" CR_TAB
6069 "ror %A0", insn, operands, len, 2);
6070 return "";
6074 /* 24-bit logic shift right */
6076 const char*
6077 avr_out_lshrpsi3 (rtx insn, rtx *op, int *plen)
6079 int dest = REGNO (op[0]);
6080 int src = REGNO (op[1]);
6082 if (CONST_INT_P (op[2]))
6084 if (plen)
6085 *plen = 0;
6087 switch (INTVAL (op[2]))
6089 case 8:
6090 if (dest <= src)
6091 return avr_asm_len ("mov %A0,%B1" CR_TAB
6092 "mov %B0,%C1" CR_TAB
6093 "clr %C0", op, plen, 3);
6094 else
6095 return avr_asm_len ("clr %C0" CR_TAB
6096 "mov %B0,%C1" CR_TAB
6097 "mov %A0,%B1", op, plen, 3);
6099 case 16:
6100 if (dest != src + 2)
6101 avr_asm_len ("mov %A0,%C1", op, plen, 1);
6103 return avr_asm_len ("clr %B0" CR_TAB
6104 "clr %C0", op, plen, 2);
6106 default:
6107 if (INTVAL (op[2]) < 24)
6108 break;
6110 /* fall through */
6112 case 23:
6113 return avr_asm_len ("clr %A0" CR_TAB
6114 "sbrc %C0,7" CR_TAB
6115 "inc %A0" CR_TAB
6116 "clr %B0" CR_TAB
6117 "clr %C0", op, plen, 5);
6118 } /* switch */
6121 out_shift_with_cnt ("lsr %C0" CR_TAB
6122 "ror %B0" CR_TAB
6123 "ror %A0", insn, op, plen, 3);
6124 return "";
6128 /* 32-bit logic shift right ((unsigned int)x >> i) */
6130 const char *
6131 lshrsi3_out (rtx insn, rtx operands[], int *len)
6133 if (GET_CODE (operands[2]) == CONST_INT)
6135 int k;
6136 int *t = len;
6138 if (!len)
6139 len = &k;
6141 switch (INTVAL (operands[2]))
6143 default:
6144 if (INTVAL (operands[2]) < 32)
6145 break;
6147 if (AVR_HAVE_MOVW)
6148 return *len = 3, ("clr %D0" CR_TAB
6149 "clr %C0" CR_TAB
6150 "movw %A0,%C0");
6151 *len = 4;
6152 return ("clr %D0" CR_TAB
6153 "clr %C0" CR_TAB
6154 "clr %B0" CR_TAB
6155 "clr %A0");
6157 case 8:
6159 int reg0 = true_regnum (operands[0]);
6160 int reg1 = true_regnum (operands[1]);
6161 *len = 4;
6162 if (reg0 <= reg1)
6163 return ("mov %A0,%B1" CR_TAB
6164 "mov %B0,%C1" CR_TAB
6165 "mov %C0,%D1" CR_TAB
6166 "clr %D0");
6167 else
6168 return ("clr %D0" CR_TAB
6169 "mov %C0,%D1" CR_TAB
6170 "mov %B0,%C1" CR_TAB
6171 "mov %A0,%B1");
6174 case 16:
6176 int reg0 = true_regnum (operands[0]);
6177 int reg1 = true_regnum (operands[1]);
6179 if (reg0 == reg1 + 2)
6180 return *len = 2, ("clr %C0" CR_TAB
6181 "clr %D0");
6182 if (AVR_HAVE_MOVW)
6183 return *len = 3, ("movw %A0,%C1" CR_TAB
6184 "clr %C0" CR_TAB
6185 "clr %D0");
6186 else
6187 return *len = 4, ("mov %B0,%D1" CR_TAB
6188 "mov %A0,%C1" CR_TAB
6189 "clr %C0" CR_TAB
6190 "clr %D0");
6193 case 24:
6194 return *len = 4, ("mov %A0,%D1" CR_TAB
6195 "clr %B0" CR_TAB
6196 "clr %C0" CR_TAB
6197 "clr %D0");
6199 case 31:
6200 *len = 6;
6201 return ("clr %A0" CR_TAB
6202 "sbrc %D0,7" CR_TAB
6203 "inc %A0" CR_TAB
6204 "clr %B0" CR_TAB
6205 "clr %C0" CR_TAB
6206 "clr %D0");
6208 len = t;
6210 out_shift_with_cnt ("lsr %D0" CR_TAB
6211 "ror %C0" CR_TAB
6212 "ror %B0" CR_TAB
6213 "ror %A0", insn, operands, len, 4);
6214 return "";
6218 /* Output addition of register XOP[0] and compile time constant XOP[2].
6219 CODE == PLUS: perform addition by using ADD instructions or
6220 CODE == MINUS: perform addition by using SUB instructions:
6222 XOP[0] = XOP[0] + XOP[2]
6224 Or perform addition/subtraction with register XOP[2] depending on CODE:
6226 XOP[0] = XOP[0] +/- XOP[2]
6228 If PLEN == NULL, print assembler instructions to perform the operation;
6229 otherwise, set *PLEN to the length of the instruction sequence (in words)
6230 printed with PLEN == NULL. XOP[3] is an 8-bit scratch register or NULL_RTX.
6231 Set *PCC to effect on cc0 according to respective CC_* insn attribute.
6233 CODE_SAT == UNKNOWN: Perform ordinary, non-saturating operation.
6234 CODE_SAT != UNKNOWN: Perform operation and saturate according to CODE_SAT.
6235 If CODE_SAT != UNKNOWN then SIGN contains the sign of the summand resp.
6236 the subtrahend in the original insn, provided it is a compile time constant.
6237 In all other cases, SIGN is 0.
6239 If OUT_LABEL is true, print the final 0: label which is needed for
6240 saturated addition / subtraction. The only case where OUT_LABEL = false
6241 is useful is for saturated addition / subtraction performed during
6242 fixed-point rounding, cf. `avr_out_round'. */
6244 static void
6245 avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc,
6246 enum rtx_code code_sat, int sign, bool out_label)
6248 /* MODE of the operation. */
6249 enum machine_mode mode = GET_MODE (xop[0]);
6251 /* INT_MODE of the same size. */
6252 enum machine_mode imode = int_mode_for_mode (mode);
6254 /* Number of bytes to operate on. */
6255 int i, n_bytes = GET_MODE_SIZE (mode);
6257 /* Value (0..0xff) held in clobber register op[3] or -1 if unknown. */
6258 int clobber_val = -1;
6260 /* op[0]: 8-bit destination register
6261 op[1]: 8-bit const int
6262 op[2]: 8-bit scratch register */
6263 rtx op[3];
6265 /* Started the operation? Before starting the operation we may skip
6266 adding 0. This is no more true after the operation started because
6267 carry must be taken into account. */
6268 bool started = false;
6270 /* Value to add. There are two ways to add VAL: R += VAL and R -= -VAL. */
6271 rtx xval = xop[2];
6273 /* Output a BRVC instruction. Only needed with saturation. */
6274 bool out_brvc = true;
6276 if (plen)
6277 *plen = 0;
6279 if (REG_P (xop[2]))
6281 *pcc = MINUS == code ? (int) CC_SET_CZN : (int) CC_SET_N;
6283 for (i = 0; i < n_bytes; i++)
6285 /* We operate byte-wise on the destination. */
6286 op[0] = simplify_gen_subreg (QImode, xop[0], mode, i);
6287 op[1] = simplify_gen_subreg (QImode, xop[2], mode, i);
6289 if (i == 0)
6290 avr_asm_len (code == PLUS ? "add %0,%1" : "sub %0,%1",
6291 op, plen, 1);
6292 else
6293 avr_asm_len (code == PLUS ? "adc %0,%1" : "sbc %0,%1",
6294 op, plen, 1);
6297 if (reg_overlap_mentioned_p (xop[0], xop[2]))
6299 gcc_assert (REGNO (xop[0]) == REGNO (xop[2]));
6301 if (MINUS == code)
6302 return;
6305 goto saturate;
6308 /* Except in the case of ADIW with 16-bit register (see below)
6309 addition does not set cc0 in a usable way. */
6311 *pcc = (MINUS == code) ? CC_SET_CZN : CC_CLOBBER;
6313 if (CONST_FIXED_P (xval))
6314 xval = avr_to_int_mode (xval);
6316 /* Adding/Subtracting zero is a no-op. */
6318 if (xval == const0_rtx)
6320 *pcc = CC_NONE;
6321 return;
6324 if (MINUS == code)
6325 xval = simplify_unary_operation (NEG, imode, xval, imode);
6327 op[2] = xop[3];
6329 if (SS_PLUS == code_sat && MINUS == code
6330 && sign < 0
6331 && 0x80 == (INTVAL (simplify_gen_subreg (QImode, xval, imode, n_bytes-1))
6332 & GET_MODE_MASK (QImode)))
6334 /* We compute x + 0x80 by means of SUB instructions. We negated the
6335 constant subtrahend above and are left with x - (-128) so that we
6336 need something like SUBI r,128 which does not exist because SUBI sets
6337 V according to the sign of the subtrahend. Notice the only case
6338 where this must be done is when NEG overflowed in case [2s] because
6339 the V computation needs the right sign of the subtrahend. */
6341 rtx msb = simplify_gen_subreg (QImode, xop[0], mode, n_bytes-1);
6343 avr_asm_len ("subi %0,128" CR_TAB
6344 "brmi 0f", &msb, plen, 2);
6345 out_brvc = false;
6347 goto saturate;
6350 for (i = 0; i < n_bytes; i++)
6352 /* We operate byte-wise on the destination. */
6353 rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
6354 rtx xval8 = simplify_gen_subreg (QImode, xval, imode, i);
6356 /* 8-bit value to operate with this byte. */
6357 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
6359 /* Registers R16..R31 can operate with immediate. */
6360 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
6362 op[0] = reg8;
6363 op[1] = gen_int_mode (val8, QImode);
6365 /* To get usable cc0 no low-bytes must have been skipped. */
6367 if (i && !started)
6368 *pcc = CC_CLOBBER;
6370 if (!started
6371 && i % 2 == 0
6372 && i + 2 <= n_bytes
6373 && test_hard_reg_class (ADDW_REGS, reg8))
6375 rtx xval16 = simplify_gen_subreg (HImode, xval, imode, i);
6376 unsigned int val16 = UINTVAL (xval16) & GET_MODE_MASK (HImode);
6378 /* Registers R24, X, Y, Z can use ADIW/SBIW with constants < 64
6379 i.e. operate word-wise. */
6381 if (val16 < 64)
6383 if (val16 != 0)
6385 started = true;
6386 avr_asm_len (code == PLUS ? "adiw %0,%1" : "sbiw %0,%1",
6387 op, plen, 1);
6389 if (n_bytes == 2 && PLUS == code)
6390 *pcc = CC_SET_ZN;
6393 i++;
6394 continue;
6398 if (val8 == 0)
6400 if (started)
6401 avr_asm_len (code == PLUS
6402 ? "adc %0,__zero_reg__" : "sbc %0,__zero_reg__",
6403 op, plen, 1);
6404 continue;
6406 else if ((val8 == 1 || val8 == 0xff)
6407 && UNKNOWN == code_sat
6408 && !started
6409 && i == n_bytes - 1)
6411 avr_asm_len ((code == PLUS) ^ (val8 == 1) ? "dec %0" : "inc %0",
6412 op, plen, 1);
6413 break;
6416 switch (code)
6418 case PLUS:
6420 gcc_assert (plen != NULL || (op[2] && REG_P (op[2])));
6422 if (plen != NULL && UNKNOWN != code_sat)
6424 /* This belongs to the x + 0x80 corner case. The code with
6425 ADD instruction is not smaller, thus make this case
6426 expensive so that the caller won't pick it. */
6428 *plen += 10;
6429 break;
6432 if (clobber_val != (int) val8)
6433 avr_asm_len ("ldi %2,%1", op, plen, 1);
6434 clobber_val = (int) val8;
6436 avr_asm_len (started ? "adc %0,%2" : "add %0,%2", op, plen, 1);
6438 break; /* PLUS */
6440 case MINUS:
6442 if (ld_reg_p)
6443 avr_asm_len (started ? "sbci %0,%1" : "subi %0,%1", op, plen, 1);
6444 else
6446 gcc_assert (plen != NULL || REG_P (op[2]));
6448 if (clobber_val != (int) val8)
6449 avr_asm_len ("ldi %2,%1", op, plen, 1);
6450 clobber_val = (int) val8;
6452 avr_asm_len (started ? "sbc %0,%2" : "sub %0,%2", op, plen, 1);
6455 break; /* MINUS */
6457 default:
6458 /* Unknown code */
6459 gcc_unreachable();
6462 started = true;
6464 } /* for all sub-bytes */
6466 saturate:
6468 if (UNKNOWN == code_sat)
6469 return;
6471 *pcc = (int) CC_CLOBBER;
6473 /* Vanilla addition/subtraction is done. We are left with saturation.
6475 We have to compute A = A <op> B where A is a register and
6476 B is a register or a non-zero compile time constant CONST.
6477 A is register class "r" if unsigned && B is REG. Otherwise, A is in "d".
6478 B stands for the original operand $2 in INSN. In the case of B = CONST,
6479 SIGN in { -1, 1 } is the sign of B. Otherwise, SIGN is 0.
6481 CODE is the instruction flavor we use in the asm sequence to perform <op>.
6484 unsigned
6485 operation | code | sat if | b is | sat value | case
6486 -----------------+-------+----------+--------------+-----------+-------
6487 + as a + b | add | C == 1 | const, reg | u+ = 0xff | [1u]
6488 + as a - (-b) | sub | C == 0 | const | u+ = 0xff | [2u]
6489 - as a - b | sub | C == 1 | const, reg | u- = 0 | [3u]
6490 - as a + (-b) | add | C == 0 | const | u- = 0 | [4u]
6493 signed
6494 operation | code | sat if | b is | sat value | case
6495 -----------------+-------+----------+--------------+-----------+-------
6496 + as a + b | add | V == 1 | const, reg | s+ | [1s]
6497 + as a - (-b) | sub | V == 1 | const | s+ | [2s]
6498 - as a - b | sub | V == 1 | const, reg | s- | [3s]
6499 - as a + (-b) | add | V == 1 | const | s- | [4s]
6501 s+ = b < 0 ? -0x80 : 0x7f
6502 s- = b < 0 ? 0x7f : -0x80
6504 The cases a - b actually perform a - (-(-b)) if B is CONST.
6507 op[0] = simplify_gen_subreg (QImode, xop[0], mode, n_bytes-1);
6508 op[1] = n_bytes > 1
6509 ? simplify_gen_subreg (QImode, xop[0], mode, n_bytes-2)
6510 : NULL_RTX;
6512 bool need_copy = true;
6513 int len_call = 1 + AVR_HAVE_JMP_CALL;
6515 switch (code_sat)
6517 default:
6518 gcc_unreachable();
6520 case SS_PLUS:
6521 case SS_MINUS:
6523 if (out_brvc)
6524 avr_asm_len ("brvc 0f", op, plen, 1);
6526 if (reg_overlap_mentioned_p (xop[0], xop[2]))
6528 /* [1s,reg] */
6530 if (n_bytes == 1)
6531 avr_asm_len ("ldi %0,0x7f" CR_TAB
6532 "adc %0,__zero_reg__", op, plen, 2);
6533 else
6534 avr_asm_len ("ldi %0,0x7f" CR_TAB
6535 "ldi %1,0xff" CR_TAB
6536 "adc %1,__zero_reg__" CR_TAB
6537 "adc %0,__zero_reg__", op, plen, 4);
6539 else if (sign == 0 && PLUS == code)
6541 /* [1s,reg] */
6543 op[2] = simplify_gen_subreg (QImode, xop[2], mode, n_bytes-1);
6545 if (n_bytes == 1)
6546 avr_asm_len ("ldi %0,0x80" CR_TAB
6547 "sbrs %2,7" CR_TAB
6548 "dec %0", op, plen, 3);
6549 else
6550 avr_asm_len ("ldi %0,0x80" CR_TAB
6551 "cp %2,%0" CR_TAB
6552 "sbc %1,%1" CR_TAB
6553 "sbci %0,0", op, plen, 4);
6555 else if (sign == 0 && MINUS == code)
6557 /* [3s,reg] */
6559 op[2] = simplify_gen_subreg (QImode, xop[2], mode, n_bytes-1);
6561 if (n_bytes == 1)
6562 avr_asm_len ("ldi %0,0x7f" CR_TAB
6563 "sbrs %2,7" CR_TAB
6564 "inc %0", op, plen, 3);
6565 else
6566 avr_asm_len ("ldi %0,0x7f" CR_TAB
6567 "cp %0,%2" CR_TAB
6568 "sbc %1,%1" CR_TAB
6569 "sbci %0,-1", op, plen, 4);
6571 else if ((sign < 0) ^ (SS_MINUS == code_sat))
6573 /* [1s,const,B < 0] [2s,B < 0] */
6574 /* [3s,const,B > 0] [4s,B > 0] */
6576 if (n_bytes == 8)
6578 avr_asm_len ("%~call __clr_8", op, plen, len_call);
6579 need_copy = false;
6582 avr_asm_len ("ldi %0,0x80", op, plen, 1);
6583 if (n_bytes > 1 && need_copy)
6584 avr_asm_len ("clr %1", op, plen, 1);
6586 else if ((sign > 0) ^ (SS_MINUS == code_sat))
6588 /* [1s,const,B > 0] [2s,B > 0] */
6589 /* [3s,const,B < 0] [4s,B < 0] */
6591 if (n_bytes == 8)
6593 avr_asm_len ("sec" CR_TAB
6594 "%~call __sbc_8", op, plen, 1 + len_call);
6595 need_copy = false;
6598 avr_asm_len ("ldi %0,0x7f", op, plen, 1);
6599 if (n_bytes > 1 && need_copy)
6600 avr_asm_len ("ldi %1,0xff", op, plen, 1);
6602 else
6603 gcc_unreachable();
6605 break;
6607 case US_PLUS:
6608 /* [1u] : [2u] */
6610 avr_asm_len (PLUS == code ? "brcc 0f" : "brcs 0f", op, plen, 1);
6612 if (n_bytes == 8)
6614 if (MINUS == code)
6615 avr_asm_len ("sec", op, plen, 1);
6616 avr_asm_len ("%~call __sbc_8", op, plen, len_call);
6618 need_copy = false;
6620 else
6622 if (MINUS == code && !test_hard_reg_class (LD_REGS, op[0]))
6623 avr_asm_len ("sec" CR_TAB "sbc %0,%0", op, plen, 2);
6624 else
6625 avr_asm_len (PLUS == code ? "sbc %0,%0" : "ldi %0,0xff",
6626 op, plen, 1);
6628 break; /* US_PLUS */
6630 case US_MINUS:
6631 /* [4u] : [3u] */
6633 avr_asm_len (PLUS == code ? "brcs 0f" : "brcc 0f", op, plen, 1);
6635 if (n_bytes == 8)
6637 avr_asm_len ("%~call __clr_8", op, plen, len_call);
6638 need_copy = false;
6640 else
6641 avr_asm_len ("clr %0", op, plen, 1);
6643 break;
6646 /* We set the MSB in the unsigned case and the 2 MSBs in the signed case.
6647 Now copy the right value to the LSBs. */
6649 if (need_copy && n_bytes > 1)
6651 if (US_MINUS == code_sat || US_PLUS == code_sat)
6653 avr_asm_len ("mov %1,%0", op, plen, 1);
6655 if (n_bytes > 2)
6657 op[0] = xop[0];
6658 if (AVR_HAVE_MOVW)
6659 avr_asm_len ("movw %0,%1", op, plen, 1);
6660 else
6661 avr_asm_len ("mov %A0,%1" CR_TAB
6662 "mov %B0,%1", op, plen, 2);
6665 else if (n_bytes > 2)
6667 op[0] = xop[0];
6668 avr_asm_len ("mov %A0,%1" CR_TAB
6669 "mov %B0,%1", op, plen, 2);
6673 if (need_copy && n_bytes == 8)
6675 if (AVR_HAVE_MOVW)
6676 avr_asm_len ("movw %r0+2,%0" CR_TAB
6677 "movw %r0+4,%0", xop, plen, 2);
6678 else
6679 avr_asm_len ("mov %r0+2,%0" CR_TAB
6680 "mov %r0+3,%0" CR_TAB
6681 "mov %r0+4,%0" CR_TAB
6682 "mov %r0+5,%0", xop, plen, 4);
6685 if (out_label)
6686 avr_asm_len ("0:", op, plen, 0);
6690 /* Output addition/subtraction of register XOP[0] and a constant XOP[2] that
6691 is ont a compile-time constant:
6693 XOP[0] = XOP[0] +/- XOP[2]
6695 This is a helper for the function below. The only insns that need this
6696 are additions/subtraction for pointer modes, i.e. HImode and PSImode. */
6698 static const char*
6699 avr_out_plus_symbol (rtx *xop, enum rtx_code code, int *plen, int *pcc)
6701 enum machine_mode mode = GET_MODE (xop[0]);
6703 /* Only pointer modes want to add symbols. */
6705 gcc_assert (mode == HImode || mode == PSImode);
6707 *pcc = MINUS == code ? (int) CC_SET_CZN : (int) CC_SET_N;
6709 avr_asm_len (PLUS == code
6710 ? "subi %A0,lo8(-(%2))" CR_TAB "sbci %B0,hi8(-(%2))"
6711 : "subi %A0,lo8(%2)" CR_TAB "sbci %B0,hi8(%2)",
6712 xop, plen, -2);
6714 if (PSImode == mode)
6715 avr_asm_len (PLUS == code
6716 ? "sbci %C0,hlo8(-(%2))"
6717 : "sbci %C0,hlo8(%2)", xop, plen, 1);
6718 return "";
6722 /* Prepare operands of addition/subtraction to be used with avr_out_plus_1.
6724 INSN is a single_set insn or an insn pattern with a binary operation as
6725 SET_SRC that is one of: PLUS, SS_PLUS, US_PLUS, MINUS, SS_MINUS, US_MINUS.
6727 XOP are the operands of INSN. In the case of 64-bit operations with
6728 constant XOP[] has just one element: The summand/subtrahend in XOP[0].
6729 The non-saturating insns up to 32 bits may or may not supply a "d" class
6730 scratch as XOP[3].
6732 If PLEN == NULL output the instructions.
6733 If PLEN != NULL set *PLEN to the length of the sequence in words.
6735 PCC is a pointer to store the instructions' effect on cc0.
6736 PCC may be NULL.
6738 PLEN and PCC default to NULL.
6740 OUT_LABEL defaults to TRUE. For a description, see AVR_OUT_PLUS_1.
6742 Return "" */
6744 const char*
6745 avr_out_plus (rtx insn, rtx *xop, int *plen, int *pcc, bool out_label)
6747 int cc_plus, cc_minus, cc_dummy;
6748 int len_plus, len_minus;
6749 rtx op[4];
6750 rtx xpattern = INSN_P (insn) ? single_set (insn) : insn;
6751 rtx xdest = SET_DEST (xpattern);
6752 enum machine_mode mode = GET_MODE (xdest);
6753 enum machine_mode imode = int_mode_for_mode (mode);
6754 int n_bytes = GET_MODE_SIZE (mode);
6755 enum rtx_code code_sat = GET_CODE (SET_SRC (xpattern));
6756 enum rtx_code code
6757 = (PLUS == code_sat || SS_PLUS == code_sat || US_PLUS == code_sat
6758 ? PLUS : MINUS);
6760 if (!pcc)
6761 pcc = &cc_dummy;
6763 /* PLUS and MINUS don't saturate: Use modular wrap-around. */
6765 if (PLUS == code_sat || MINUS == code_sat)
6766 code_sat = UNKNOWN;
6768 if (n_bytes <= 4 && REG_P (xop[2]))
6770 avr_out_plus_1 (xop, plen, code, pcc, code_sat, 0, out_label);
6771 return "";
6774 if (8 == n_bytes)
6776 op[0] = gen_rtx_REG (DImode, ACC_A);
6777 op[1] = gen_rtx_REG (DImode, ACC_A);
6778 op[2] = avr_to_int_mode (xop[0]);
6780 else
6782 if (!REG_P (xop[2])
6783 && !CONST_INT_P (xop[2])
6784 && !CONST_FIXED_P (xop[2]))
6786 return avr_out_plus_symbol (xop, code, plen, pcc);
6789 op[0] = avr_to_int_mode (xop[0]);
6790 op[1] = avr_to_int_mode (xop[1]);
6791 op[2] = avr_to_int_mode (xop[2]);
6794 /* Saturations and 64-bit operations don't have a clobber operand.
6795 For the other cases, the caller will provide a proper XOP[3]. */
6797 xpattern = INSN_P (insn) ? PATTERN (insn) : insn;
6798 op[3] = PARALLEL == GET_CODE (xpattern) ? xop[3] : NULL_RTX;
6800 /* Saturation will need the sign of the original operand. */
6802 rtx xmsb = simplify_gen_subreg (QImode, op[2], imode, n_bytes-1);
6803 int sign = INTVAL (xmsb) < 0 ? -1 : 1;
6805 /* If we subtract and the subtrahend is a constant, then negate it
6806 so that avr_out_plus_1 can be used. */
6808 if (MINUS == code)
6809 op[2] = simplify_unary_operation (NEG, imode, op[2], imode);
6811 /* Work out the shortest sequence. */
6813 avr_out_plus_1 (op, &len_minus, MINUS, &cc_minus, code_sat, sign, out_label);
6814 avr_out_plus_1 (op, &len_plus, PLUS, &cc_plus, code_sat, sign, out_label);
6816 if (plen)
6818 *plen = (len_minus <= len_plus) ? len_minus : len_plus;
6819 *pcc = (len_minus <= len_plus) ? cc_minus : cc_plus;
6821 else if (len_minus <= len_plus)
6822 avr_out_plus_1 (op, NULL, MINUS, pcc, code_sat, sign, out_label);
6823 else
6824 avr_out_plus_1 (op, NULL, PLUS, pcc, code_sat, sign, out_label);
6826 return "";
6830 /* Output bit operation (IOR, AND, XOR) with register XOP[0] and compile
6831 time constant XOP[2]:
6833 XOP[0] = XOP[0] <op> XOP[2]
6835 and return "". If PLEN == NULL, print assembler instructions to perform the
6836 operation; otherwise, set *PLEN to the length of the instruction sequence
6837 (in words) printed with PLEN == NULL. XOP[3] is either an 8-bit clobber
6838 register or SCRATCH if no clobber register is needed for the operation.
6839 INSN is an INSN_P or a pattern of an insn. */
6841 const char*
6842 avr_out_bitop (rtx insn, rtx *xop, int *plen)
6844 /* CODE and MODE of the operation. */
6845 rtx xpattern = INSN_P (insn) ? single_set (insn) : insn;
6846 enum rtx_code code = GET_CODE (SET_SRC (xpattern));
6847 enum machine_mode mode = GET_MODE (xop[0]);
6849 /* Number of bytes to operate on. */
6850 int i, n_bytes = GET_MODE_SIZE (mode);
6852 /* Value of T-flag (0 or 1) or -1 if unknow. */
6853 int set_t = -1;
6855 /* Value (0..0xff) held in clobber register op[3] or -1 if unknown. */
6856 int clobber_val = -1;
6858 /* op[0]: 8-bit destination register
6859 op[1]: 8-bit const int
6860 op[2]: 8-bit clobber register or SCRATCH
6861 op[3]: 8-bit register containing 0xff or NULL_RTX */
6862 rtx op[4];
6864 op[2] = xop[3];
6865 op[3] = NULL_RTX;
6867 if (plen)
6868 *plen = 0;
6870 for (i = 0; i < n_bytes; i++)
6872 /* We operate byte-wise on the destination. */
6873 rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
6874 rtx xval8 = simplify_gen_subreg (QImode, xop[2], mode, i);
6876 /* 8-bit value to operate with this byte. */
6877 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
6879 /* Number of bits set in the current byte of the constant. */
6880 int pop8 = avr_popcount (val8);
6882 /* Registers R16..R31 can operate with immediate. */
6883 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
6885 op[0] = reg8;
6886 op[1] = GEN_INT (val8);
6888 switch (code)
6890 case IOR:
6892 if (0 == pop8)
6893 continue;
6894 else if (ld_reg_p)
6895 avr_asm_len ("ori %0,%1", op, plen, 1);
6896 else if (1 == pop8)
6898 if (set_t != 1)
6899 avr_asm_len ("set", op, plen, 1);
6900 set_t = 1;
6902 op[1] = GEN_INT (exact_log2 (val8));
6903 avr_asm_len ("bld %0,%1", op, plen, 1);
6905 else if (8 == pop8)
6907 if (op[3] != NULL_RTX)
6908 avr_asm_len ("mov %0,%3", op, plen, 1);
6909 else
6910 avr_asm_len ("clr %0" CR_TAB
6911 "dec %0", op, plen, 2);
6913 op[3] = op[0];
6915 else
6917 if (clobber_val != (int) val8)
6918 avr_asm_len ("ldi %2,%1", op, plen, 1);
6919 clobber_val = (int) val8;
6921 avr_asm_len ("or %0,%2", op, plen, 1);
6924 continue; /* IOR */
6926 case AND:
6928 if (8 == pop8)
6929 continue;
6930 else if (0 == pop8)
6931 avr_asm_len ("clr %0", op, plen, 1);
6932 else if (ld_reg_p)
6933 avr_asm_len ("andi %0,%1", op, plen, 1);
6934 else if (7 == pop8)
6936 if (set_t != 0)
6937 avr_asm_len ("clt", op, plen, 1);
6938 set_t = 0;
6940 op[1] = GEN_INT (exact_log2 (GET_MODE_MASK (QImode) & ~val8));
6941 avr_asm_len ("bld %0,%1", op, plen, 1);
6943 else
6945 if (clobber_val != (int) val8)
6946 avr_asm_len ("ldi %2,%1", op, plen, 1);
6947 clobber_val = (int) val8;
6949 avr_asm_len ("and %0,%2", op, plen, 1);
6952 continue; /* AND */
6954 case XOR:
6956 if (0 == pop8)
6957 continue;
6958 else if (8 == pop8)
6959 avr_asm_len ("com %0", op, plen, 1);
6960 else if (ld_reg_p && val8 == (1 << 7))
6961 avr_asm_len ("subi %0,%1", op, plen, 1);
6962 else
6964 if (clobber_val != (int) val8)
6965 avr_asm_len ("ldi %2,%1", op, plen, 1);
6966 clobber_val = (int) val8;
6968 avr_asm_len ("eor %0,%2", op, plen, 1);
6971 continue; /* XOR */
6973 default:
6974 /* Unknown rtx_code */
6975 gcc_unreachable();
6977 } /* for all sub-bytes */
6979 return "";
6983 /* PLEN == NULL: Output code to add CONST_INT OP[0] to SP.
6984 PLEN != NULL: Set *PLEN to the length of that sequence.
6985 Return "". */
6987 const char*
6988 avr_out_addto_sp (rtx *op, int *plen)
6990 int pc_len = AVR_2_BYTE_PC ? 2 : 3;
6991 int addend = INTVAL (op[0]);
6993 if (plen)
6994 *plen = 0;
6996 if (addend < 0)
6998 if (flag_verbose_asm || flag_print_asm_name)
6999 avr_asm_len (ASM_COMMENT_START "SP -= %n0", op, plen, 0);
7001 while (addend <= -pc_len)
7003 addend += pc_len;
7004 avr_asm_len ("rcall .", op, plen, 1);
7007 while (addend++ < 0)
7008 avr_asm_len ("push __zero_reg__", op, plen, 1);
7010 else if (addend > 0)
7012 if (flag_verbose_asm || flag_print_asm_name)
7013 avr_asm_len (ASM_COMMENT_START "SP += %0", op, plen, 0);
7015 while (addend-- > 0)
7016 avr_asm_len ("pop __tmp_reg__", op, plen, 1);
7019 return "";
7023 /* Outputs instructions needed for fixed point type conversion.
7024 This includes converting between any fixed point type, as well
7025 as converting to any integer type. Conversion between integer
7026 types is not supported.
7028 Converting signed fractional types requires a bit shift if converting
7029 to or from any unsigned fractional type because the decimal place is
7030 shifted by 1 bit. When the destination is a signed fractional, the sign
7031 is stored in either the carry or T bit. */
7033 const char*
7034 avr_out_fract (rtx insn, rtx operands[], bool intsigned, int *plen)
7036 size_t i;
7037 rtx xop[6];
7038 RTX_CODE shift = UNKNOWN;
7039 bool sign_in_carry = false;
7040 bool msb_in_carry = false;
7041 bool lsb_in_carry = false;
7042 const char *code_ashift = "lsl %0";
7045 #define MAY_CLOBBER(RR) \
7046 /* Shorthand used below. */ \
7047 ((sign_bytes \
7048 && IN_RANGE (RR, dest.regno_msb - sign_bytes + 1, dest.regno_msb)) \
7049 || (reg_unused_after (insn, all_regs_rtx[RR]) \
7050 && !IN_RANGE (RR, dest.regno, dest.regno_msb)))
7052 struct
7054 /* bytes : Length of operand in bytes.
7055 ibyte : Length of integral part in bytes.
7056 fbyte, fbit : Length of fractional part in bytes, bits. */
7058 bool sbit;
7059 unsigned fbit, bytes, ibyte, fbyte;
7060 unsigned regno, regno_msb;
7061 } dest, src, *val[2] = { &dest, &src };
7063 if (plen)
7064 *plen = 0;
7066 /* Step 0: Determine information on source and destination operand we
7067 ====== will need in the remainder. */
7069 for (i = 0; i < sizeof (val) / sizeof (*val); i++)
7071 enum machine_mode mode;
7073 xop[i] = operands[i];
7075 mode = GET_MODE (xop[i]);
7077 val[i]->bytes = GET_MODE_SIZE (mode);
7078 val[i]->regno = REGNO (xop[i]);
7079 val[i]->regno_msb = REGNO (xop[i]) + val[i]->bytes - 1;
7081 if (SCALAR_INT_MODE_P (mode))
7083 val[i]->sbit = intsigned;
7084 val[i]->fbit = 0;
7086 else if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
7088 val[i]->sbit = SIGNED_SCALAR_FIXED_POINT_MODE_P (mode);
7089 val[i]->fbit = GET_MODE_FBIT (mode);
7091 else
7092 fatal_insn ("unsupported fixed-point conversion", insn);
7094 val[i]->fbyte = (1 + val[i]->fbit) / BITS_PER_UNIT;
7095 val[i]->ibyte = val[i]->bytes - val[i]->fbyte;
7098 // Byte offset of the decimal point taking into account different place
7099 // of the decimal point in input and output and different register numbers
7100 // of input and output.
7101 int offset = dest.regno - src.regno + dest.fbyte - src.fbyte;
7103 // Number of destination bytes that will come from sign / zero extension.
7104 int sign_bytes = (dest.ibyte - src.ibyte) * (dest.ibyte > src.ibyte);
7106 // Number of bytes at the low end to be filled with zeros.
7107 int zero_bytes = (dest.fbyte - src.fbyte) * (dest.fbyte > src.fbyte);
7109 // Do we have a 16-Bit register that is cleared?
7110 rtx clrw = NULL_RTX;
7112 bool sign_extend = src.sbit && sign_bytes;
7114 if (0 == dest.fbit % 8 && 7 == src.fbit % 8)
7115 shift = ASHIFT;
7116 else if (7 == dest.fbit % 8 && 0 == src.fbit % 8)
7117 shift = ASHIFTRT;
7118 else if (dest.fbit % 8 == src.fbit % 8)
7119 shift = UNKNOWN;
7120 else
7121 gcc_unreachable();
7123 /* Step 1: Clear bytes at the low end and copy payload bits from source
7124 ====== to destination. */
7126 int step = offset < 0 ? 1 : -1;
7127 unsigned d0 = offset < 0 ? dest.regno : dest.regno_msb;
7129 // We leared at least that number of registers.
7130 int clr_n = 0;
7132 for (; d0 >= dest.regno && d0 <= dest.regno_msb; d0 += step)
7134 // Next regno of destination is needed for MOVW
7135 unsigned d1 = d0 + step;
7137 // Current and next regno of source
7138 signed s0 = d0 - offset;
7139 signed s1 = s0 + step;
7141 // Must current resp. next regno be CLRed? This applies to the low
7142 // bytes of the destination that have no associated source bytes.
7143 bool clr0 = s0 < (signed) src.regno;
7144 bool clr1 = s1 < (signed) src.regno && d1 >= dest.regno;
7146 // First gather what code to emit (if any) and additional step to
7147 // apply if a MOVW is in use. xop[2] is destination rtx and xop[3]
7148 // is the source rtx for the current loop iteration.
7149 const char *code = NULL;
7150 int stepw = 0;
7152 if (clr0)
7154 if (AVR_HAVE_MOVW && clr1 && clrw)
7156 xop[2] = all_regs_rtx[d0 & ~1];
7157 xop[3] = clrw;
7158 code = "movw %2,%3";
7159 stepw = step;
7161 else
7163 xop[2] = all_regs_rtx[d0];
7164 code = "clr %2";
7166 if (++clr_n >= 2
7167 && !clrw
7168 && d0 % 2 == (step > 0))
7170 clrw = all_regs_rtx[d0 & ~1];
7174 else if (offset && s0 <= (signed) src.regno_msb)
7176 int movw = AVR_HAVE_MOVW && offset % 2 == 0
7177 && d0 % 2 == (offset > 0)
7178 && d1 <= dest.regno_msb && d1 >= dest.regno
7179 && s1 <= (signed) src.regno_msb && s1 >= (signed) src.regno;
7181 xop[2] = all_regs_rtx[d0 & ~movw];
7182 xop[3] = all_regs_rtx[s0 & ~movw];
7183 code = movw ? "movw %2,%3" : "mov %2,%3";
7184 stepw = step * movw;
7187 if (code)
7189 if (sign_extend && shift != ASHIFT && !sign_in_carry
7190 && (d0 == src.regno_msb || d0 + stepw == src.regno_msb))
7192 /* We are going to override the sign bit. If we sign-extend,
7193 store the sign in the Carry flag. This is not needed if
7194 the destination will be ASHIFT is the remainder because
7195 the ASHIFT will set Carry without extra instruction. */
7197 avr_asm_len ("lsl %0", &all_regs_rtx[src.regno_msb], plen, 1);
7198 sign_in_carry = true;
7201 unsigned src_msb = dest.regno_msb - sign_bytes - offset + 1;
7203 if (!sign_extend && shift == ASHIFTRT && !msb_in_carry
7204 && src.ibyte > dest.ibyte
7205 && (d0 == src_msb || d0 + stepw == src_msb))
7207 /* We are going to override the MSB. If we shift right,
7208 store the MSB in the Carry flag. This is only needed if
7209 we don't sign-extend becaue with sign-extension the MSB
7210 (the sign) will be produced by the sign extension. */
7212 avr_asm_len ("lsr %0", &all_regs_rtx[src_msb], plen, 1);
7213 msb_in_carry = true;
7216 unsigned src_lsb = dest.regno - offset -1;
7218 if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry
7219 && (d0 == src_lsb || d0 + stepw == src_lsb))
7221 /* We are going to override the new LSB; store it into carry. */
7223 avr_asm_len ("lsl %0", &all_regs_rtx[src_lsb], plen, 1);
7224 code_ashift = "rol %0";
7225 lsb_in_carry = true;
7228 avr_asm_len (code, xop, plen, 1);
7229 d0 += stepw;
7233 /* Step 2: Shift destination left by 1 bit position. This might be needed
7234 ====== for signed input and unsigned output. */
7236 if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry)
7238 unsigned s0 = dest.regno - offset -1;
7240 if (MAY_CLOBBER (s0))
7241 avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1);
7242 else
7243 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
7244 "lsl __tmp_reg__", &all_regs_rtx[s0], plen, 2);
7246 code_ashift = "rol %0";
7247 lsb_in_carry = true;
7250 if (shift == ASHIFT)
7252 for (d0 = dest.regno + zero_bytes;
7253 d0 <= dest.regno_msb - sign_bytes; d0++)
7255 avr_asm_len (code_ashift, &all_regs_rtx[d0], plen, 1);
7256 code_ashift = "rol %0";
7259 lsb_in_carry = false;
7260 sign_in_carry = true;
7263 /* Step 4a: Store MSB in carry if we don't already have it or will produce
7264 ======= it in sign-extension below. */
7266 if (!sign_extend && shift == ASHIFTRT && !msb_in_carry
7267 && src.ibyte > dest.ibyte)
7269 unsigned s0 = dest.regno_msb - sign_bytes - offset + 1;
7271 if (MAY_CLOBBER (s0))
7272 avr_asm_len ("lsr %0", &all_regs_rtx[s0], plen, 1);
7273 else
7274 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
7275 "lsr __tmp_reg__", &all_regs_rtx[s0], plen, 2);
7277 msb_in_carry = true;
7280 /* Step 3: Sign-extend or zero-extend the destination as needed.
7281 ====== */
7283 if (sign_extend && !sign_in_carry)
7285 unsigned s0 = src.regno_msb;
7287 if (MAY_CLOBBER (s0))
7288 avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1);
7289 else
7290 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
7291 "lsl __tmp_reg__", &all_regs_rtx[s0], plen, 2);
7293 sign_in_carry = true;
7296 gcc_assert (sign_in_carry + msb_in_carry + lsb_in_carry <= 1);
7298 unsigned copies = 0;
7299 rtx movw = sign_extend ? NULL_RTX : clrw;
7301 for (d0 = dest.regno_msb - sign_bytes + 1; d0 <= dest.regno_msb; d0++)
7303 if (AVR_HAVE_MOVW && movw
7304 && d0 % 2 == 0 && d0 + 1 <= dest.regno_msb)
7306 xop[2] = all_regs_rtx[d0];
7307 xop[3] = movw;
7308 avr_asm_len ("movw %2,%3", xop, plen, 1);
7309 d0++;
7311 else
7313 avr_asm_len (sign_extend ? "sbc %0,%0" : "clr %0",
7314 &all_regs_rtx[d0], plen, 1);
7316 if (++copies >= 2 && !movw && d0 % 2 == 1)
7317 movw = all_regs_rtx[d0-1];
7319 } /* for */
7322 /* Step 4: Right shift the destination. This might be needed for
7323 ====== conversions from unsigned to signed. */
7325 if (shift == ASHIFTRT)
7327 const char *code_ashiftrt = "lsr %0";
7329 if (sign_extend || msb_in_carry)
7330 code_ashiftrt = "ror %0";
7332 if (src.sbit && src.ibyte == dest.ibyte)
7333 code_ashiftrt = "asr %0";
7335 for (d0 = dest.regno_msb - sign_bytes;
7336 d0 >= dest.regno + zero_bytes - 1 && d0 >= dest.regno; d0--)
7338 avr_asm_len (code_ashiftrt, &all_regs_rtx[d0], plen, 1);
7339 code_ashiftrt = "ror %0";
7343 #undef MAY_CLOBBER
7345 return "";
7349 /* Output fixed-point rounding. XOP[0] = XOP[1] is the operand to round.
7350 XOP[2] is the rounding point, a CONST_INT. The function prints the
7351 instruction sequence if PLEN = NULL and computes the length in words
7352 of the sequence if PLEN != NULL. Most of this function deals with
7353 preparing operands for calls to `avr_out_plus' and `avr_out_bitop'. */
7355 const char*
7356 avr_out_round (rtx insn ATTRIBUTE_UNUSED, rtx *xop, int *plen)
7358 enum machine_mode mode = GET_MODE (xop[0]);
7359 enum machine_mode imode = int_mode_for_mode (mode);
7360 // The smallest fractional bit not cleared by the rounding is 2^(-RP).
7361 int fbit = (int) GET_MODE_FBIT (mode);
7362 double_int i_add = double_int_zero.set_bit (fbit-1 - INTVAL (xop[2]));
7363 // Lengths of PLUS and AND parts.
7364 int len_add = 0, *plen_add = plen ? &len_add : NULL;
7365 int len_and = 0, *plen_and = plen ? &len_and : NULL;
7367 // Add-Saturate 1/2 * 2^(-RP). Don't print the label "0:" when printing
7368 // the saturated addition so that we can emit the "rjmp 1f" before the
7369 // "0:" below.
7371 rtx xadd = const_fixed_from_double_int (i_add, mode);
7372 rtx xpattern, xsrc, op[4];
7374 xsrc = SIGNED_FIXED_POINT_MODE_P (mode)
7375 ? gen_rtx_SS_PLUS (mode, xop[1], xadd)
7376 : gen_rtx_US_PLUS (mode, xop[1], xadd);
7377 xpattern = gen_rtx_SET (VOIDmode, xop[0], xsrc);
7379 op[0] = xop[0];
7380 op[1] = xop[1];
7381 op[2] = xadd;
7382 avr_out_plus (xpattern, op, plen_add, NULL, false /* Don't print "0:" */);
7384 avr_asm_len ("rjmp 1f" CR_TAB
7385 "0:", NULL, plen_add, 1);
7387 // Keep all bits from RP and higher: ... 2^(-RP)
7388 // Clear all bits from RP+1 and lower: 2^(-RP-1) ...
7389 // Rounding point ^^^^^^^
7390 // Added above ^^^^^^^^^
7391 rtx xreg = simplify_gen_subreg (imode, xop[0], mode, 0);
7392 rtx xmask = immed_double_int_const (-i_add - i_add, imode);
7394 xpattern = gen_rtx_SET (VOIDmode, xreg, gen_rtx_AND (imode, xreg, xmask));
7396 op[0] = xreg;
7397 op[1] = xreg;
7398 op[2] = xmask;
7399 op[3] = gen_rtx_SCRATCH (QImode);
7400 avr_out_bitop (xpattern, op, plen_and);
7401 avr_asm_len ("1:", NULL, plen, 0);
7403 if (plen)
7404 *plen = len_add + len_and;
7406 return "";
7410 /* Create RTL split patterns for byte sized rotate expressions. This
7411 produces a series of move instructions and considers overlap situations.
7412 Overlapping non-HImode operands need a scratch register. */
7414 bool
7415 avr_rotate_bytes (rtx operands[])
7417 int i, j;
7418 enum machine_mode mode = GET_MODE (operands[0]);
7419 bool overlapped = reg_overlap_mentioned_p (operands[0], operands[1]);
7420 bool same_reg = rtx_equal_p (operands[0], operands[1]);
7421 int num = INTVAL (operands[2]);
7422 rtx scratch = operands[3];
7423 /* Work out if byte or word move is needed. Odd byte rotates need QImode.
7424 Word move if no scratch is needed, otherwise use size of scratch. */
7425 enum machine_mode move_mode = QImode;
7426 int move_size, offset, size;
7428 if (num & 0xf)
7429 move_mode = QImode;
7430 else if ((mode == SImode && !same_reg) || !overlapped)
7431 move_mode = HImode;
7432 else
7433 move_mode = GET_MODE (scratch);
7435 /* Force DI rotate to use QI moves since other DI moves are currently split
7436 into QI moves so forward propagation works better. */
7437 if (mode == DImode)
7438 move_mode = QImode;
7439 /* Make scratch smaller if needed. */
7440 if (SCRATCH != GET_CODE (scratch)
7441 && HImode == GET_MODE (scratch)
7442 && QImode == move_mode)
7443 scratch = simplify_gen_subreg (move_mode, scratch, HImode, 0);
7445 move_size = GET_MODE_SIZE (move_mode);
7446 /* Number of bytes/words to rotate. */
7447 offset = (num >> 3) / move_size;
7448 /* Number of moves needed. */
7449 size = GET_MODE_SIZE (mode) / move_size;
7450 /* Himode byte swap is special case to avoid a scratch register. */
7451 if (mode == HImode && same_reg)
7453 /* HImode byte swap, using xor. This is as quick as using scratch. */
7454 rtx src, dst;
7455 src = simplify_gen_subreg (move_mode, operands[1], mode, 0);
7456 dst = simplify_gen_subreg (move_mode, operands[0], mode, 1);
7457 if (!rtx_equal_p (dst, src))
7459 emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
7460 emit_move_insn (src, gen_rtx_XOR (QImode, src, dst));
7461 emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
7464 else
7466 #define MAX_SIZE 8 /* GET_MODE_SIZE (DImode) / GET_MODE_SIZE (QImode) */
7467 /* Create linked list of moves to determine move order. */
7468 struct {
7469 rtx src, dst;
7470 int links;
7471 } move[MAX_SIZE + 8];
7472 int blocked, moves;
7474 gcc_assert (size <= MAX_SIZE);
7475 /* Generate list of subreg moves. */
7476 for (i = 0; i < size; i++)
7478 int from = i;
7479 int to = (from + offset) % size;
7480 move[i].src = simplify_gen_subreg (move_mode, operands[1],
7481 mode, from * move_size);
7482 move[i].dst = simplify_gen_subreg (move_mode, operands[0],
7483 mode, to * move_size);
7484 move[i].links = -1;
7486 /* Mark dependence where a dst of one move is the src of another move.
7487 The first move is a conflict as it must wait until second is
7488 performed. We ignore moves to self - we catch this later. */
7489 if (overlapped)
7490 for (i = 0; i < size; i++)
7491 if (reg_overlap_mentioned_p (move[i].dst, operands[1]))
7492 for (j = 0; j < size; j++)
7493 if (j != i && rtx_equal_p (move[j].src, move[i].dst))
7495 /* The dst of move i is the src of move j. */
7496 move[i].links = j;
7497 break;
7500 blocked = -1;
7501 moves = 0;
7502 /* Go through move list and perform non-conflicting moves. As each
7503 non-overlapping move is made, it may remove other conflicts
7504 so the process is repeated until no conflicts remain. */
7507 blocked = -1;
7508 moves = 0;
7509 /* Emit move where dst is not also a src or we have used that
7510 src already. */
7511 for (i = 0; i < size; i++)
7512 if (move[i].src != NULL_RTX)
7514 if (move[i].links == -1
7515 || move[move[i].links].src == NULL_RTX)
7517 moves++;
7518 /* Ignore NOP moves to self. */
7519 if (!rtx_equal_p (move[i].dst, move[i].src))
7520 emit_move_insn (move[i].dst, move[i].src);
7522 /* Remove conflict from list. */
7523 move[i].src = NULL_RTX;
7525 else
7526 blocked = i;
7529 /* Check for deadlock. This is when no moves occurred and we have
7530 at least one blocked move. */
7531 if (moves == 0 && blocked != -1)
7533 /* Need to use scratch register to break deadlock.
7534 Add move to put dst of blocked move into scratch.
7535 When this move occurs, it will break chain deadlock.
7536 The scratch register is substituted for real move. */
7538 gcc_assert (SCRATCH != GET_CODE (scratch));
7540 move[size].src = move[blocked].dst;
7541 move[size].dst = scratch;
7542 /* Scratch move is never blocked. */
7543 move[size].links = -1;
7544 /* Make sure we have valid link. */
7545 gcc_assert (move[blocked].links != -1);
7546 /* Replace src of blocking move with scratch reg. */
7547 move[move[blocked].links].src = scratch;
7548 /* Make dependent on scratch move occuring. */
7549 move[blocked].links = size;
7550 size=size+1;
7553 while (blocked != -1);
7555 return true;
7559 /* Worker function for `ADJUST_INSN_LENGTH'. */
7560 /* Modifies the length assigned to instruction INSN
7561 LEN is the initially computed length of the insn. */
7564 avr_adjust_insn_length (rtx insn, int len)
7566 rtx *op = recog_data.operand;
7567 enum attr_adjust_len adjust_len;
7569 /* Some complex insns don't need length adjustment and therefore
7570 the length need not/must not be adjusted for these insns.
7571 It is easier to state this in an insn attribute "adjust_len" than
7572 to clutter up code here... */
7574 if (-1 == recog_memoized (insn))
7576 return len;
7579 /* Read from insn attribute "adjust_len" if/how length is to be adjusted. */
7581 adjust_len = get_attr_adjust_len (insn);
7583 if (adjust_len == ADJUST_LEN_NO)
7585 /* Nothing to adjust: The length from attribute "length" is fine.
7586 This is the default. */
7588 return len;
7591 /* Extract insn's operands. */
7593 extract_constrain_insn_cached (insn);
7595 /* Dispatch to right function. */
7597 switch (adjust_len)
7599 case ADJUST_LEN_RELOAD_IN16: output_reload_inhi (op, op[2], &len); break;
7600 case ADJUST_LEN_RELOAD_IN24: avr_out_reload_inpsi (op, op[2], &len); break;
7601 case ADJUST_LEN_RELOAD_IN32: output_reload_insisf (op, op[2], &len); break;
7603 case ADJUST_LEN_OUT_BITOP: avr_out_bitop (insn, op, &len); break;
7605 case ADJUST_LEN_PLUS: avr_out_plus (insn, op, &len); break;
7606 case ADJUST_LEN_ADDTO_SP: avr_out_addto_sp (op, &len); break;
7608 case ADJUST_LEN_MOV8: output_movqi (insn, op, &len); break;
7609 case ADJUST_LEN_MOV16: output_movhi (insn, op, &len); break;
7610 case ADJUST_LEN_MOV24: avr_out_movpsi (insn, op, &len); break;
7611 case ADJUST_LEN_MOV32: output_movsisf (insn, op, &len); break;
7612 case ADJUST_LEN_MOVMEM: avr_out_movmem (insn, op, &len); break;
7613 case ADJUST_LEN_XLOAD: avr_out_xload (insn, op, &len); break;
7614 case ADJUST_LEN_LPM: avr_out_lpm (insn, op, &len); break;
7616 case ADJUST_LEN_SFRACT: avr_out_fract (insn, op, true, &len); break;
7617 case ADJUST_LEN_UFRACT: avr_out_fract (insn, op, false, &len); break;
7618 case ADJUST_LEN_ROUND: avr_out_round (insn, op, &len); break;
7620 case ADJUST_LEN_TSTHI: avr_out_tsthi (insn, op, &len); break;
7621 case ADJUST_LEN_TSTPSI: avr_out_tstpsi (insn, op, &len); break;
7622 case ADJUST_LEN_TSTSI: avr_out_tstsi (insn, op, &len); break;
7623 case ADJUST_LEN_COMPARE: avr_out_compare (insn, op, &len); break;
7624 case ADJUST_LEN_COMPARE64: avr_out_compare64 (insn, op, &len); break;
7626 case ADJUST_LEN_LSHRQI: lshrqi3_out (insn, op, &len); break;
7627 case ADJUST_LEN_LSHRHI: lshrhi3_out (insn, op, &len); break;
7628 case ADJUST_LEN_LSHRSI: lshrsi3_out (insn, op, &len); break;
7630 case ADJUST_LEN_ASHRQI: ashrqi3_out (insn, op, &len); break;
7631 case ADJUST_LEN_ASHRHI: ashrhi3_out (insn, op, &len); break;
7632 case ADJUST_LEN_ASHRSI: ashrsi3_out (insn, op, &len); break;
7634 case ADJUST_LEN_ASHLQI: ashlqi3_out (insn, op, &len); break;
7635 case ADJUST_LEN_ASHLHI: ashlhi3_out (insn, op, &len); break;
7636 case ADJUST_LEN_ASHLSI: ashlsi3_out (insn, op, &len); break;
7638 case ADJUST_LEN_ASHLPSI: avr_out_ashlpsi3 (insn, op, &len); break;
7639 case ADJUST_LEN_ASHRPSI: avr_out_ashrpsi3 (insn, op, &len); break;
7640 case ADJUST_LEN_LSHRPSI: avr_out_lshrpsi3 (insn, op, &len); break;
7642 case ADJUST_LEN_CALL: len = AVR_HAVE_JMP_CALL ? 2 : 1; break;
7644 case ADJUST_LEN_INSERT_BITS: avr_out_insert_bits (op, &len); break;
7646 default:
7647 gcc_unreachable();
7650 return len;
7653 /* Return nonzero if register REG dead after INSN. */
7656 reg_unused_after (rtx insn, rtx reg)
7658 return (dead_or_set_p (insn, reg)
7659 || (REG_P(reg) && _reg_unused_after (insn, reg)));
7662 /* Return nonzero if REG is not used after INSN.
7663 We assume REG is a reload reg, and therefore does
7664 not live past labels. It may live past calls or jumps though. */
7667 _reg_unused_after (rtx insn, rtx reg)
7669 enum rtx_code code;
7670 rtx set;
7672 /* If the reg is set by this instruction, then it is safe for our
7673 case. Disregard the case where this is a store to memory, since
7674 we are checking a register used in the store address. */
7675 set = single_set (insn);
7676 if (set && GET_CODE (SET_DEST (set)) != MEM
7677 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
7678 return 1;
7680 while ((insn = NEXT_INSN (insn)))
7682 rtx set;
7683 code = GET_CODE (insn);
7685 #if 0
7686 /* If this is a label that existed before reload, then the register
7687 if dead here. However, if this is a label added by reorg, then
7688 the register may still be live here. We can't tell the difference,
7689 so we just ignore labels completely. */
7690 if (code == CODE_LABEL)
7691 return 1;
7692 /* else */
7693 #endif
7695 if (!INSN_P (insn))
7696 continue;
7698 if (code == JUMP_INSN)
7699 return 0;
7701 /* If this is a sequence, we must handle them all at once.
7702 We could have for instance a call that sets the target register,
7703 and an insn in a delay slot that uses the register. In this case,
7704 we must return 0. */
7705 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
7707 int i;
7708 int retval = 0;
7710 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
7712 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
7713 rtx set = single_set (this_insn);
7715 if (GET_CODE (this_insn) == CALL_INSN)
7716 code = CALL_INSN;
7717 else if (GET_CODE (this_insn) == JUMP_INSN)
7719 if (INSN_ANNULLED_BRANCH_P (this_insn))
7720 return 0;
7721 code = JUMP_INSN;
7724 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
7725 return 0;
7726 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
7728 if (GET_CODE (SET_DEST (set)) != MEM)
7729 retval = 1;
7730 else
7731 return 0;
7733 if (set == 0
7734 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
7735 return 0;
7737 if (retval == 1)
7738 return 1;
7739 else if (code == JUMP_INSN)
7740 return 0;
7743 if (code == CALL_INSN)
7745 rtx tem;
7746 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
7747 if (GET_CODE (XEXP (tem, 0)) == USE
7748 && REG_P (XEXP (XEXP (tem, 0), 0))
7749 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
7750 return 0;
7751 if (call_used_regs[REGNO (reg)])
7752 return 1;
7755 set = single_set (insn);
7757 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
7758 return 0;
7759 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
7760 return GET_CODE (SET_DEST (set)) != MEM;
7761 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
7762 return 0;
7764 return 1;
7768 /* Implement `TARGET_ASM_INTEGER'. */
7769 /* Target hook for assembling integer objects. The AVR version needs
7770 special handling for references to certain labels. */
7772 static bool
7773 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
7775 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
7776 && text_segment_operand (x, VOIDmode))
7778 fputs ("\t.word\tgs(", asm_out_file);
7779 output_addr_const (asm_out_file, x);
7780 fputs (")\n", asm_out_file);
7782 return true;
7784 else if (GET_MODE (x) == PSImode)
7786 /* This needs binutils 2.23+, see PR binutils/13503 */
7788 fputs ("\t.byte\tlo8(", asm_out_file);
7789 output_addr_const (asm_out_file, x);
7790 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
7792 fputs ("\t.byte\thi8(", asm_out_file);
7793 output_addr_const (asm_out_file, x);
7794 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
7796 fputs ("\t.byte\thh8(", asm_out_file);
7797 output_addr_const (asm_out_file, x);
7798 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
7800 return true;
7802 else if (CONST_FIXED_P (x))
7804 unsigned n;
7806 /* varasm fails to handle big fixed modes that don't fit in hwi. */
7808 for (n = 0; n < size; n++)
7810 rtx xn = simplify_gen_subreg (QImode, x, GET_MODE (x), n);
7811 default_assemble_integer (xn, 1, aligned_p);
7814 return true;
7817 return default_assemble_integer (x, size, aligned_p);
7821 /* Implement `TARGET_CLASS_LIKELY_SPILLED_P'. */
7822 /* Return value is nonzero if pseudos that have been
7823 assigned to registers of class CLASS would likely be spilled
7824 because registers of CLASS are needed for spill registers. */
7826 static bool
7827 avr_class_likely_spilled_p (reg_class_t c)
7829 return (c != ALL_REGS && c != ADDW_REGS);
7833 /* Valid attributes:
7834 progmem - Put data to program memory.
7835 signal - Make a function to be hardware interrupt.
7836 After function prologue interrupts remain disabled.
7837 interrupt - Make a function to be hardware interrupt. Before function
7838 prologue interrupts are enabled by means of SEI.
7839 naked - Don't generate function prologue/epilogue and RET
7840 instruction. */
7842 /* Handle a "progmem" attribute; arguments as in
7843 struct attribute_spec.handler. */
7845 static tree
7846 avr_handle_progmem_attribute (tree *node, tree name,
7847 tree args ATTRIBUTE_UNUSED,
7848 int flags ATTRIBUTE_UNUSED,
7849 bool *no_add_attrs)
7851 if (DECL_P (*node))
7853 if (TREE_CODE (*node) == TYPE_DECL)
7855 /* This is really a decl attribute, not a type attribute,
7856 but try to handle it for GCC 3.0 backwards compatibility. */
7858 tree type = TREE_TYPE (*node);
7859 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
7860 tree newtype = build_type_attribute_variant (type, attr);
7862 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
7863 TREE_TYPE (*node) = newtype;
7864 *no_add_attrs = true;
7866 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
7868 *no_add_attrs = false;
7870 else
7872 warning (OPT_Wattributes, "%qE attribute ignored",
7873 name);
7874 *no_add_attrs = true;
7878 return NULL_TREE;
7881 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
7882 struct attribute_spec.handler. */
7884 static tree
7885 avr_handle_fndecl_attribute (tree *node, tree name,
7886 tree args ATTRIBUTE_UNUSED,
7887 int flags ATTRIBUTE_UNUSED,
7888 bool *no_add_attrs)
7890 if (TREE_CODE (*node) != FUNCTION_DECL)
7892 warning (OPT_Wattributes, "%qE attribute only applies to functions",
7893 name);
7894 *no_add_attrs = true;
7897 return NULL_TREE;
7900 static tree
7901 avr_handle_fntype_attribute (tree *node, tree name,
7902 tree args ATTRIBUTE_UNUSED,
7903 int flags ATTRIBUTE_UNUSED,
7904 bool *no_add_attrs)
7906 if (TREE_CODE (*node) != FUNCTION_TYPE)
7908 warning (OPT_Wattributes, "%qE attribute only applies to functions",
7909 name);
7910 *no_add_attrs = true;
7913 return NULL_TREE;
7917 /* AVR attributes. */
7918 static const struct attribute_spec
7919 avr_attribute_table[] =
7921 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
7922 affects_type_identity } */
7923 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute,
7924 false },
7925 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute,
7926 false },
7927 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute,
7928 false },
7929 { "naked", 0, 0, false, true, true, avr_handle_fntype_attribute,
7930 false },
7931 { "OS_task", 0, 0, false, true, true, avr_handle_fntype_attribute,
7932 false },
7933 { "OS_main", 0, 0, false, true, true, avr_handle_fntype_attribute,
7934 false },
7935 { NULL, 0, 0, false, false, false, NULL, false }
7939 /* Look if DECL shall be placed in program memory space by
7940 means of attribute `progmem' or some address-space qualifier.
7941 Return non-zero if DECL is data that must end up in Flash and
7942 zero if the data lives in RAM (.bss, .data, .rodata, ...).
7944 Return 2 if DECL is located in 24-bit flash address-space
7945 Return 1 if DECL is located in 16-bit flash address-space
7946 Return -1 if attribute `progmem' occurs in DECL or ATTRIBUTES
7947 Return 0 otherwise */
7950 avr_progmem_p (tree decl, tree attributes)
7952 tree a;
7954 if (TREE_CODE (decl) != VAR_DECL)
7955 return 0;
7957 if (avr_decl_memx_p (decl))
7958 return 2;
7960 if (avr_decl_flash_p (decl))
7961 return 1;
7963 if (NULL_TREE
7964 != lookup_attribute ("progmem", attributes))
7965 return -1;
7967 a = decl;
7970 a = TREE_TYPE(a);
7971 while (TREE_CODE (a) == ARRAY_TYPE);
7973 if (a == error_mark_node)
7974 return 0;
7976 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
7977 return -1;
7979 return 0;
7983 /* Scan type TYP for pointer references to address space ASn.
7984 Return ADDR_SPACE_GENERIC (i.e. 0) if all pointers targeting
7985 the AS are also declared to be CONST.
7986 Otherwise, return the respective address space, i.e. a value != 0. */
7988 static addr_space_t
7989 avr_nonconst_pointer_addrspace (tree typ)
7991 while (ARRAY_TYPE == TREE_CODE (typ))
7992 typ = TREE_TYPE (typ);
7994 if (POINTER_TYPE_P (typ))
7996 addr_space_t as;
7997 tree target = TREE_TYPE (typ);
7999 /* Pointer to function: Test the function's return type. */
8001 if (FUNCTION_TYPE == TREE_CODE (target))
8002 return avr_nonconst_pointer_addrspace (TREE_TYPE (target));
8004 /* "Ordinary" pointers... */
8006 while (TREE_CODE (target) == ARRAY_TYPE)
8007 target = TREE_TYPE (target);
8009 /* Pointers to non-generic address space must be const.
8010 Refuse address spaces outside the device's flash. */
8012 as = TYPE_ADDR_SPACE (target);
8014 if (!ADDR_SPACE_GENERIC_P (as)
8015 && (!TYPE_READONLY (target)
8016 || avr_addrspace[as].segment >= avr_current_device->n_flash))
8018 return as;
8021 /* Scan pointer's target type. */
8023 return avr_nonconst_pointer_addrspace (target);
8026 return ADDR_SPACE_GENERIC;
8030 /* Sanity check NODE so that all pointers targeting non-generic address spaces
8031 go along with CONST qualifier. Writing to these address spaces should
8032 be detected and complained about as early as possible. */
8034 static bool
8035 avr_pgm_check_var_decl (tree node)
8037 const char *reason = NULL;
8039 addr_space_t as = ADDR_SPACE_GENERIC;
8041 gcc_assert (as == 0);
8043 if (avr_log.progmem)
8044 avr_edump ("%?: %t\n", node);
8046 switch (TREE_CODE (node))
8048 default:
8049 break;
8051 case VAR_DECL:
8052 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
8053 reason = "variable";
8054 break;
8056 case PARM_DECL:
8057 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
8058 reason = "function parameter";
8059 break;
8061 case FIELD_DECL:
8062 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
8063 reason = "structure field";
8064 break;
8066 case FUNCTION_DECL:
8067 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (TREE_TYPE (node))),
8069 reason = "return type of function";
8070 break;
8072 case POINTER_TYPE:
8073 if (as = avr_nonconst_pointer_addrspace (node), as)
8074 reason = "pointer";
8075 break;
8078 if (reason)
8080 if (avr_addrspace[as].segment >= avr_current_device->n_flash)
8082 if (TYPE_P (node))
8083 error ("%qT uses address space %qs beyond flash of %qs",
8084 node, avr_addrspace[as].name, avr_current_device->name);
8085 else
8086 error ("%s %q+D uses address space %qs beyond flash of %qs",
8087 reason, node, avr_addrspace[as].name,
8088 avr_current_device->name);
8090 else
8092 if (TYPE_P (node))
8093 error ("pointer targeting address space %qs must be const in %qT",
8094 avr_addrspace[as].name, node);
8095 else
8096 error ("pointer targeting address space %qs must be const"
8097 " in %s %q+D",
8098 avr_addrspace[as].name, reason, node);
8102 return reason == NULL;
8106 /* Add the section attribute if the variable is in progmem. */
8108 static void
8109 avr_insert_attributes (tree node, tree *attributes)
8111 avr_pgm_check_var_decl (node);
8113 if (TREE_CODE (node) == VAR_DECL
8114 && (TREE_STATIC (node) || DECL_EXTERNAL (node))
8115 && avr_progmem_p (node, *attributes))
8117 addr_space_t as;
8118 tree node0 = node;
8120 /* For C++, we have to peel arrays in order to get correct
8121 determination of readonlyness. */
8124 node0 = TREE_TYPE (node0);
8125 while (TREE_CODE (node0) == ARRAY_TYPE);
8127 if (error_mark_node == node0)
8128 return;
8130 as = TYPE_ADDR_SPACE (TREE_TYPE (node));
8132 if (avr_addrspace[as].segment >= avr_current_device->n_flash)
8134 error ("variable %q+D located in address space %qs"
8135 " beyond flash of %qs",
8136 node, avr_addrspace[as].name, avr_current_device->name);
8139 if (!TYPE_READONLY (node0)
8140 && !TREE_READONLY (node))
8142 const char *reason = "__attribute__((progmem))";
8144 if (!ADDR_SPACE_GENERIC_P (as))
8145 reason = avr_addrspace[as].name;
8147 if (avr_log.progmem)
8148 avr_edump ("\n%?: %t\n%t\n", node, node0);
8150 error ("variable %q+D must be const in order to be put into"
8151 " read-only section by means of %qs", node, reason);
8157 /* Implement `ASM_OUTPUT_ALIGNED_DECL_LOCAL'. */
8158 /* Implement `ASM_OUTPUT_ALIGNED_DECL_COMMON'. */
8159 /* Track need of __do_clear_bss. */
8161 void
8162 avr_asm_output_aligned_decl_common (FILE * stream,
8163 const_tree decl ATTRIBUTE_UNUSED,
8164 const char *name,
8165 unsigned HOST_WIDE_INT size,
8166 unsigned int align, bool local_p)
8168 /* __gnu_lto_v1 etc. are just markers for the linker injected by toplev.c.
8169 There is no need to trigger __do_clear_bss code for them. */
8171 if (!STR_PREFIX_P (name, "__gnu_lto"))
8172 avr_need_clear_bss_p = true;
8174 if (local_p)
8175 ASM_OUTPUT_ALIGNED_LOCAL (stream, name, size, align);
8176 else
8177 ASM_OUTPUT_ALIGNED_COMMON (stream, name, size, align);
8181 /* Unnamed section callback for data_section
8182 to track need of __do_copy_data. */
8184 static void
8185 avr_output_data_section_asm_op (const void *data)
8187 avr_need_copy_data_p = true;
8189 /* Dispatch to default. */
8190 output_section_asm_op (data);
8194 /* Unnamed section callback for bss_section
8195 to track need of __do_clear_bss. */
8197 static void
8198 avr_output_bss_section_asm_op (const void *data)
8200 avr_need_clear_bss_p = true;
8202 /* Dispatch to default. */
8203 output_section_asm_op (data);
8207 /* Unnamed section callback for progmem*.data sections. */
8209 static void
8210 avr_output_progmem_section_asm_op (const void *data)
8212 fprintf (asm_out_file, "\t.section\t%s,\"a\",@progbits\n",
8213 (const char*) data);
8217 /* Implement `TARGET_ASM_INIT_SECTIONS'. */
8219 static void
8220 avr_asm_init_sections (void)
8222 /* Set up a section for jump tables. Alignment is handled by
8223 ASM_OUTPUT_BEFORE_CASE_LABEL. */
8225 if (AVR_HAVE_JMP_CALL)
8227 progmem_swtable_section
8228 = get_unnamed_section (0, output_section_asm_op,
8229 "\t.section\t.progmem.gcc_sw_table"
8230 ",\"a\",@progbits");
8232 else
8234 progmem_swtable_section
8235 = get_unnamed_section (SECTION_CODE, output_section_asm_op,
8236 "\t.section\t.progmem.gcc_sw_table"
8237 ",\"ax\",@progbits");
8240 /* Override section callbacks to keep track of `avr_need_clear_bss_p'
8241 resp. `avr_need_copy_data_p'. */
8243 readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
8244 data_section->unnamed.callback = avr_output_data_section_asm_op;
8245 bss_section->unnamed.callback = avr_output_bss_section_asm_op;
8249 /* Implement `TARGET_ASM_FUNCTION_RODATA_SECTION'. */
8251 static section*
8252 avr_asm_function_rodata_section (tree decl)
8254 /* If a function is unused and optimized out by -ffunction-sections
8255 and --gc-sections, ensure that the same will happen for its jump
8256 tables by putting them into individual sections. */
8258 unsigned int flags;
8259 section * frodata;
8261 /* Get the frodata section from the default function in varasm.c
8262 but treat function-associated data-like jump tables as code
8263 rather than as user defined data. AVR has no constant pools. */
8265 int fdata = flag_data_sections;
8267 flag_data_sections = flag_function_sections;
8268 frodata = default_function_rodata_section (decl);
8269 flag_data_sections = fdata;
8270 flags = frodata->common.flags;
8273 if (frodata != readonly_data_section
8274 && flags & SECTION_NAMED)
8276 /* Adjust section flags and replace section name prefix. */
8278 unsigned int i;
8280 static const char* const prefix[] =
8282 ".rodata", ".progmem.gcc_sw_table",
8283 ".gnu.linkonce.r.", ".gnu.linkonce.t."
8286 for (i = 0; i < sizeof (prefix) / sizeof (*prefix); i += 2)
8288 const char * old_prefix = prefix[i];
8289 const char * new_prefix = prefix[i+1];
8290 const char * name = frodata->named.name;
8292 if (STR_PREFIX_P (name, old_prefix))
8294 const char *rname = ACONCAT ((new_prefix,
8295 name + strlen (old_prefix), NULL));
8296 flags &= ~SECTION_CODE;
8297 flags |= AVR_HAVE_JMP_CALL ? 0 : SECTION_CODE;
8299 return get_section (rname, flags, frodata->named.decl);
8304 return progmem_swtable_section;
8308 /* Implement `TARGET_ASM_NAMED_SECTION'. */
8309 /* Track need of __do_clear_bss, __do_copy_data for named sections. */
8311 static void
8312 avr_asm_named_section (const char *name, unsigned int flags, tree decl)
8314 if (flags & AVR_SECTION_PROGMEM)
8316 addr_space_t as = (flags & AVR_SECTION_PROGMEM) / SECTION_MACH_DEP;
8317 const char *old_prefix = ".rodata";
8318 const char *new_prefix = avr_addrspace[as].section_name;
8320 if (STR_PREFIX_P (name, old_prefix))
8322 const char *sname = ACONCAT ((new_prefix,
8323 name + strlen (old_prefix), NULL));
8324 default_elf_asm_named_section (sname, flags, decl);
8325 return;
8328 default_elf_asm_named_section (new_prefix, flags, decl);
8329 return;
8332 if (!avr_need_copy_data_p)
8333 avr_need_copy_data_p = (STR_PREFIX_P (name, ".data")
8334 || STR_PREFIX_P (name, ".rodata")
8335 || STR_PREFIX_P (name, ".gnu.linkonce.d"));
8337 if (!avr_need_clear_bss_p)
8338 avr_need_clear_bss_p = STR_PREFIX_P (name, ".bss");
8340 default_elf_asm_named_section (name, flags, decl);
8344 /* Implement `TARGET_SECTION_TYPE_FLAGS'. */
8346 static unsigned int
8347 avr_section_type_flags (tree decl, const char *name, int reloc)
8349 unsigned int flags = default_section_type_flags (decl, name, reloc);
8351 if (STR_PREFIX_P (name, ".noinit"))
8353 if (decl && TREE_CODE (decl) == VAR_DECL
8354 && DECL_INITIAL (decl) == NULL_TREE)
8355 flags |= SECTION_BSS; /* @nobits */
8356 else
8357 warning (0, "only uninitialized variables can be placed in the "
8358 ".noinit section");
8361 if (decl && DECL_P (decl)
8362 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
8364 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
8366 /* Attribute progmem puts data in generic address space.
8367 Set section flags as if it was in __flash to get the right
8368 section prefix in the remainder. */
8370 if (ADDR_SPACE_GENERIC_P (as))
8371 as = ADDR_SPACE_FLASH;
8373 flags |= as * SECTION_MACH_DEP;
8374 flags &= ~SECTION_WRITE;
8375 flags &= ~SECTION_BSS;
8378 return flags;
8382 /* Implement `TARGET_ENCODE_SECTION_INFO'. */
8384 static void
8385 avr_encode_section_info (tree decl, rtx rtl, int new_decl_p)
8387 /* In avr_handle_progmem_attribute, DECL_INITIAL is not yet
8388 readily available, see PR34734. So we postpone the warning
8389 about uninitialized data in program memory section until here. */
8391 if (new_decl_p
8392 && decl && DECL_P (decl)
8393 && NULL_TREE == DECL_INITIAL (decl)
8394 && !DECL_EXTERNAL (decl)
8395 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
8397 warning (OPT_Wuninitialized,
8398 "uninitialized variable %q+D put into "
8399 "program memory area", decl);
8402 default_encode_section_info (decl, rtl, new_decl_p);
8404 if (decl && DECL_P (decl)
8405 && TREE_CODE (decl) != FUNCTION_DECL
8406 && MEM_P (rtl)
8407 && SYMBOL_REF == GET_CODE (XEXP (rtl, 0)))
8409 rtx sym = XEXP (rtl, 0);
8410 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
8412 /* PSTR strings are in generic space but located in flash:
8413 patch address space. */
8415 if (-1 == avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
8416 as = ADDR_SPACE_FLASH;
8418 AVR_SYMBOL_SET_ADDR_SPACE (sym, as);
8423 /* Implement `TARGET_ASM_SELECT_SECTION' */
8425 static section *
8426 avr_asm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
8428 section * sect = default_elf_select_section (decl, reloc, align);
8430 if (decl && DECL_P (decl)
8431 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
8433 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
8435 /* __progmem__ goes in generic space but shall be allocated to
8436 .progmem.data */
8438 if (ADDR_SPACE_GENERIC_P (as))
8439 as = ADDR_SPACE_FLASH;
8441 if (sect->common.flags & SECTION_NAMED)
8443 const char * name = sect->named.name;
8444 const char * old_prefix = ".rodata";
8445 const char * new_prefix = avr_addrspace[as].section_name;
8447 if (STR_PREFIX_P (name, old_prefix))
8449 const char *sname = ACONCAT ((new_prefix,
8450 name + strlen (old_prefix), NULL));
8451 return get_section (sname, sect->common.flags, sect->named.decl);
8455 if (!progmem_section[as])
8457 progmem_section[as]
8458 = get_unnamed_section (0, avr_output_progmem_section_asm_op,
8459 avr_addrspace[as].section_name);
8462 return progmem_section[as];
8465 return sect;
8468 /* Implement `TARGET_ASM_FILE_START'. */
8469 /* Outputs some text at the start of each assembler file. */
8471 static void
8472 avr_file_start (void)
8474 int sfr_offset = avr_current_arch->sfr_offset;
8476 if (avr_current_arch->asm_only)
8477 error ("MCU %qs supported for assembler only", avr_current_device->name);
8479 default_file_start ();
8481 /* Print I/O addresses of some SFRs used with IN and OUT. */
8483 if (AVR_HAVE_SPH)
8484 fprintf (asm_out_file, "__SP_H__ = 0x%02x\n", avr_addr.sp_h - sfr_offset);
8486 fprintf (asm_out_file, "__SP_L__ = 0x%02x\n", avr_addr.sp_l - sfr_offset);
8487 fprintf (asm_out_file, "__SREG__ = 0x%02x\n", avr_addr.sreg - sfr_offset);
8488 if (AVR_HAVE_RAMPZ)
8489 fprintf (asm_out_file, "__RAMPZ__ = 0x%02x\n", avr_addr.rampz - sfr_offset);
8490 if (AVR_HAVE_RAMPY)
8491 fprintf (asm_out_file, "__RAMPY__ = 0x%02x\n", avr_addr.rampy - sfr_offset);
8492 if (AVR_HAVE_RAMPX)
8493 fprintf (asm_out_file, "__RAMPX__ = 0x%02x\n", avr_addr.rampx - sfr_offset);
8494 if (AVR_HAVE_RAMPD)
8495 fprintf (asm_out_file, "__RAMPD__ = 0x%02x\n", avr_addr.rampd - sfr_offset);
8496 if (AVR_XMEGA)
8497 fprintf (asm_out_file, "__CCP__ = 0x%02x\n", avr_addr.ccp - sfr_offset);
8498 fprintf (asm_out_file, "__tmp_reg__ = %d\n", TMP_REGNO);
8499 fprintf (asm_out_file, "__zero_reg__ = %d\n", ZERO_REGNO);
8503 /* Implement `TARGET_ASM_FILE_END'. */
8504 /* Outputs to the stdio stream FILE some
8505 appropriate text to go at the end of an assembler file. */
8507 static void
8508 avr_file_end (void)
8510 /* Output these only if there is anything in the
8511 .data* / .rodata* / .gnu.linkonce.* resp. .bss* or COMMON
8512 input section(s) - some code size can be saved by not
8513 linking in the initialization code from libgcc if resp.
8514 sections are empty, see PR18145. */
8516 if (avr_need_copy_data_p)
8517 fputs (".global __do_copy_data\n", asm_out_file);
8519 if (avr_need_clear_bss_p)
8520 fputs (".global __do_clear_bss\n", asm_out_file);
8524 /* Worker function for `ADJUST_REG_ALLOC_ORDER'. */
8525 /* Choose the order in which to allocate hard registers for
8526 pseudo-registers local to a basic block.
8528 Store the desired register order in the array `reg_alloc_order'.
8529 Element 0 should be the register to allocate first; element 1, the
8530 next register; and so on. */
8532 void
8533 avr_adjust_reg_alloc_order (void)
8535 unsigned int i;
8536 static const int order_0[] =
8538 24, 25,
8539 18, 19, 20, 21, 22, 23,
8540 30, 31,
8541 26, 27, 28, 29,
8542 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
8543 0, 1,
8544 32, 33, 34, 35
8546 static const int order_1[] =
8548 18, 19, 20, 21, 22, 23, 24, 25,
8549 30, 31,
8550 26, 27, 28, 29,
8551 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
8552 0, 1,
8553 32, 33, 34, 35
8555 static const int order_2[] =
8557 25, 24, 23, 22, 21, 20, 19, 18,
8558 30, 31,
8559 26, 27, 28, 29,
8560 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
8561 1, 0,
8562 32, 33, 34, 35
8565 const int *order = (TARGET_ORDER_1 ? order_1 :
8566 TARGET_ORDER_2 ? order_2 :
8567 order_0);
8568 for (i = 0; i < ARRAY_SIZE (order_0); ++i)
8569 reg_alloc_order[i] = order[i];
8573 /* Implement `TARGET_REGISTER_MOVE_COST' */
8575 static int
8576 avr_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
8577 reg_class_t from, reg_class_t to)
8579 return (from == STACK_REG ? 6
8580 : to == STACK_REG ? 12
8581 : 2);
8585 /* Implement `TARGET_MEMORY_MOVE_COST' */
8587 static int
8588 avr_memory_move_cost (enum machine_mode mode,
8589 reg_class_t rclass ATTRIBUTE_UNUSED,
8590 bool in ATTRIBUTE_UNUSED)
8592 return (mode == QImode ? 2
8593 : mode == HImode ? 4
8594 : mode == SImode ? 8
8595 : mode == SFmode ? 8
8596 : 16);
8600 /* Mutually recursive subroutine of avr_rtx_cost for calculating the
8601 cost of an RTX operand given its context. X is the rtx of the
8602 operand, MODE is its mode, and OUTER is the rtx_code of this
8603 operand's parent operator. */
8605 static int
8606 avr_operand_rtx_cost (rtx x, enum machine_mode mode, enum rtx_code outer,
8607 int opno, bool speed)
8609 enum rtx_code code = GET_CODE (x);
8610 int total;
8612 switch (code)
8614 case REG:
8615 case SUBREG:
8616 return 0;
8618 case CONST_INT:
8619 case CONST_FIXED:
8620 case CONST_DOUBLE:
8621 return COSTS_N_INSNS (GET_MODE_SIZE (mode));
8623 default:
8624 break;
8627 total = 0;
8628 avr_rtx_costs (x, code, outer, opno, &total, speed);
8629 return total;
8632 /* Worker function for AVR backend's rtx_cost function.
8633 X is rtx expression whose cost is to be calculated.
8634 Return true if the complete cost has been computed.
8635 Return false if subexpressions should be scanned.
8636 In either case, *TOTAL contains the cost result. */
8638 static bool
8639 avr_rtx_costs_1 (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED,
8640 int opno ATTRIBUTE_UNUSED, int *total, bool speed)
8642 enum rtx_code code = (enum rtx_code) codearg;
8643 enum machine_mode mode = GET_MODE (x);
8644 HOST_WIDE_INT val;
8646 switch (code)
8648 case CONST_INT:
8649 case CONST_FIXED:
8650 case CONST_DOUBLE:
8651 case SYMBOL_REF:
8652 case CONST:
8653 case LABEL_REF:
8654 /* Immediate constants are as cheap as registers. */
8655 *total = 0;
8656 return true;
8658 case MEM:
8659 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
8660 return true;
8662 case NEG:
8663 switch (mode)
8665 case QImode:
8666 case SFmode:
8667 *total = COSTS_N_INSNS (1);
8668 break;
8670 case HImode:
8671 case PSImode:
8672 case SImode:
8673 *total = COSTS_N_INSNS (2 * GET_MODE_SIZE (mode) - 1);
8674 break;
8676 default:
8677 return false;
8679 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8680 return true;
8682 case ABS:
8683 switch (mode)
8685 case QImode:
8686 case SFmode:
8687 *total = COSTS_N_INSNS (1);
8688 break;
8690 default:
8691 return false;
8693 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8694 return true;
8696 case NOT:
8697 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
8698 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8699 return true;
8701 case ZERO_EXTEND:
8702 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
8703 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
8704 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8705 return true;
8707 case SIGN_EXTEND:
8708 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
8709 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
8710 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8711 return true;
8713 case PLUS:
8714 switch (mode)
8716 case QImode:
8717 if (AVR_HAVE_MUL
8718 && MULT == GET_CODE (XEXP (x, 0))
8719 && register_operand (XEXP (x, 1), QImode))
8721 /* multiply-add */
8722 *total = COSTS_N_INSNS (speed ? 4 : 3);
8723 /* multiply-add with constant: will be split and load constant. */
8724 if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
8725 *total = COSTS_N_INSNS (1) + *total;
8726 return true;
8728 *total = COSTS_N_INSNS (1);
8729 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
8730 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
8731 break;
8733 case HImode:
8734 if (AVR_HAVE_MUL
8735 && (MULT == GET_CODE (XEXP (x, 0))
8736 || ASHIFT == GET_CODE (XEXP (x, 0)))
8737 && register_operand (XEXP (x, 1), HImode)
8738 && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))
8739 || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))))
8741 /* multiply-add */
8742 *total = COSTS_N_INSNS (speed ? 5 : 4);
8743 /* multiply-add with constant: will be split and load constant. */
8744 if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
8745 *total = COSTS_N_INSNS (1) + *total;
8746 return true;
8748 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
8750 *total = COSTS_N_INSNS (2);
8751 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
8752 speed);
8754 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
8755 *total = COSTS_N_INSNS (1);
8756 else
8757 *total = COSTS_N_INSNS (2);
8758 break;
8760 case PSImode:
8761 if (!CONST_INT_P (XEXP (x, 1)))
8763 *total = COSTS_N_INSNS (3);
8764 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
8765 speed);
8767 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
8768 *total = COSTS_N_INSNS (2);
8769 else
8770 *total = COSTS_N_INSNS (3);
8771 break;
8773 case SImode:
8774 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
8776 *total = COSTS_N_INSNS (4);
8777 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
8778 speed);
8780 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
8781 *total = COSTS_N_INSNS (1);
8782 else
8783 *total = COSTS_N_INSNS (4);
8784 break;
8786 default:
8787 return false;
8789 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8790 return true;
8792 case MINUS:
8793 if (AVR_HAVE_MUL
8794 && QImode == mode
8795 && register_operand (XEXP (x, 0), QImode)
8796 && MULT == GET_CODE (XEXP (x, 1)))
8798 /* multiply-sub */
8799 *total = COSTS_N_INSNS (speed ? 4 : 3);
8800 /* multiply-sub with constant: will be split and load constant. */
8801 if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
8802 *total = COSTS_N_INSNS (1) + *total;
8803 return true;
8805 if (AVR_HAVE_MUL
8806 && HImode == mode
8807 && register_operand (XEXP (x, 0), HImode)
8808 && (MULT == GET_CODE (XEXP (x, 1))
8809 || ASHIFT == GET_CODE (XEXP (x, 1)))
8810 && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))
8811 || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))))
8813 /* multiply-sub */
8814 *total = COSTS_N_INSNS (speed ? 5 : 4);
8815 /* multiply-sub with constant: will be split and load constant. */
8816 if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
8817 *total = COSTS_N_INSNS (1) + *total;
8818 return true;
8820 /* FALLTHRU */
8821 case AND:
8822 case IOR:
8823 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
8824 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8825 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
8826 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
8827 return true;
8829 case XOR:
8830 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
8831 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8832 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
8833 return true;
8835 case MULT:
8836 switch (mode)
8838 case QImode:
8839 if (AVR_HAVE_MUL)
8840 *total = COSTS_N_INSNS (!speed ? 3 : 4);
8841 else if (!speed)
8842 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
8843 else
8844 return false;
8845 break;
8847 case HImode:
8848 if (AVR_HAVE_MUL)
8850 rtx op0 = XEXP (x, 0);
8851 rtx op1 = XEXP (x, 1);
8852 enum rtx_code code0 = GET_CODE (op0);
8853 enum rtx_code code1 = GET_CODE (op1);
8854 bool ex0 = SIGN_EXTEND == code0 || ZERO_EXTEND == code0;
8855 bool ex1 = SIGN_EXTEND == code1 || ZERO_EXTEND == code1;
8857 if (ex0
8858 && (u8_operand (op1, HImode)
8859 || s8_operand (op1, HImode)))
8861 *total = COSTS_N_INSNS (!speed ? 4 : 6);
8862 return true;
8864 if (ex0
8865 && register_operand (op1, HImode))
8867 *total = COSTS_N_INSNS (!speed ? 5 : 8);
8868 return true;
8870 else if (ex0 || ex1)
8872 *total = COSTS_N_INSNS (!speed ? 3 : 5);
8873 return true;
8875 else if (register_operand (op0, HImode)
8876 && (u8_operand (op1, HImode)
8877 || s8_operand (op1, HImode)))
8879 *total = COSTS_N_INSNS (!speed ? 6 : 9);
8880 return true;
8882 else
8883 *total = COSTS_N_INSNS (!speed ? 7 : 10);
8885 else if (!speed)
8886 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
8887 else
8888 return false;
8889 break;
8891 case PSImode:
8892 if (!speed)
8893 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
8894 else
8895 *total = 10;
8896 break;
8898 case SImode:
8899 if (AVR_HAVE_MUL)
8901 if (!speed)
8903 /* Add some additional costs besides CALL like moves etc. */
8905 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
8907 else
8909 /* Just a rough estimate. Even with -O2 we don't want bulky
8910 code expanded inline. */
8912 *total = COSTS_N_INSNS (25);
8915 else
8917 if (speed)
8918 *total = COSTS_N_INSNS (300);
8919 else
8920 /* Add some additional costs besides CALL like moves etc. */
8921 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
8924 return true;
8926 default:
8927 return false;
8929 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8930 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
8931 return true;
8933 case DIV:
8934 case MOD:
8935 case UDIV:
8936 case UMOD:
8937 if (!speed)
8938 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
8939 else
8940 *total = COSTS_N_INSNS (15 * GET_MODE_SIZE (mode));
8941 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8942 /* For div/mod with const-int divisor we have at least the cost of
8943 loading the divisor. */
8944 if (CONST_INT_P (XEXP (x, 1)))
8945 *total += COSTS_N_INSNS (GET_MODE_SIZE (mode));
8946 /* Add some overall penaly for clobbering and moving around registers */
8947 *total += COSTS_N_INSNS (2);
8948 return true;
8950 case ROTATE:
8951 switch (mode)
8953 case QImode:
8954 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 4)
8955 *total = COSTS_N_INSNS (1);
8957 break;
8959 case HImode:
8960 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 8)
8961 *total = COSTS_N_INSNS (3);
8963 break;
8965 case SImode:
8966 if (CONST_INT_P (XEXP (x, 1)))
8967 switch (INTVAL (XEXP (x, 1)))
8969 case 8:
8970 case 24:
8971 *total = COSTS_N_INSNS (5);
8972 break;
8973 case 16:
8974 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 6);
8975 break;
8977 break;
8979 default:
8980 return false;
8982 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8983 return true;
8985 case ASHIFT:
8986 switch (mode)
8988 case QImode:
8989 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
8991 *total = COSTS_N_INSNS (!speed ? 4 : 17);
8992 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
8993 speed);
8995 else
8997 val = INTVAL (XEXP (x, 1));
8998 if (val == 7)
8999 *total = COSTS_N_INSNS (3);
9000 else if (val >= 0 && val <= 7)
9001 *total = COSTS_N_INSNS (val);
9002 else
9003 *total = COSTS_N_INSNS (1);
9005 break;
9007 case HImode:
9008 if (AVR_HAVE_MUL)
9010 if (const_2_to_7_operand (XEXP (x, 1), HImode)
9011 && (SIGN_EXTEND == GET_CODE (XEXP (x, 0))
9012 || ZERO_EXTEND == GET_CODE (XEXP (x, 0))))
9014 *total = COSTS_N_INSNS (!speed ? 4 : 6);
9015 return true;
9019 if (const1_rtx == (XEXP (x, 1))
9020 && SIGN_EXTEND == GET_CODE (XEXP (x, 0)))
9022 *total = COSTS_N_INSNS (2);
9023 return true;
9026 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9028 *total = COSTS_N_INSNS (!speed ? 5 : 41);
9029 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9030 speed);
9032 else
9033 switch (INTVAL (XEXP (x, 1)))
9035 case 0:
9036 *total = 0;
9037 break;
9038 case 1:
9039 case 8:
9040 *total = COSTS_N_INSNS (2);
9041 break;
9042 case 9:
9043 *total = COSTS_N_INSNS (3);
9044 break;
9045 case 2:
9046 case 3:
9047 case 10:
9048 case 15:
9049 *total = COSTS_N_INSNS (4);
9050 break;
9051 case 7:
9052 case 11:
9053 case 12:
9054 *total = COSTS_N_INSNS (5);
9055 break;
9056 case 4:
9057 *total = COSTS_N_INSNS (!speed ? 5 : 8);
9058 break;
9059 case 6:
9060 *total = COSTS_N_INSNS (!speed ? 5 : 9);
9061 break;
9062 case 5:
9063 *total = COSTS_N_INSNS (!speed ? 5 : 10);
9064 break;
9065 default:
9066 *total = COSTS_N_INSNS (!speed ? 5 : 41);
9067 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9068 speed);
9070 break;
9072 case PSImode:
9073 if (!CONST_INT_P (XEXP (x, 1)))
9075 *total = COSTS_N_INSNS (!speed ? 6 : 73);
9077 else
9078 switch (INTVAL (XEXP (x, 1)))
9080 case 0:
9081 *total = 0;
9082 break;
9083 case 1:
9084 case 8:
9085 case 16:
9086 *total = COSTS_N_INSNS (3);
9087 break;
9088 case 23:
9089 *total = COSTS_N_INSNS (5);
9090 break;
9091 default:
9092 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
9093 break;
9095 break;
9097 case SImode:
9098 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9100 *total = COSTS_N_INSNS (!speed ? 7 : 113);
9101 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9102 speed);
9104 else
9105 switch (INTVAL (XEXP (x, 1)))
9107 case 0:
9108 *total = 0;
9109 break;
9110 case 24:
9111 *total = COSTS_N_INSNS (3);
9112 break;
9113 case 1:
9114 case 8:
9115 case 16:
9116 *total = COSTS_N_INSNS (4);
9117 break;
9118 case 31:
9119 *total = COSTS_N_INSNS (6);
9120 break;
9121 case 2:
9122 *total = COSTS_N_INSNS (!speed ? 7 : 8);
9123 break;
9124 default:
9125 *total = COSTS_N_INSNS (!speed ? 7 : 113);
9126 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9127 speed);
9129 break;
9131 default:
9132 return false;
9134 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9135 return true;
9137 case ASHIFTRT:
9138 switch (mode)
9140 case QImode:
9141 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9143 *total = COSTS_N_INSNS (!speed ? 4 : 17);
9144 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9145 speed);
9147 else
9149 val = INTVAL (XEXP (x, 1));
9150 if (val == 6)
9151 *total = COSTS_N_INSNS (4);
9152 else if (val == 7)
9153 *total = COSTS_N_INSNS (2);
9154 else if (val >= 0 && val <= 7)
9155 *total = COSTS_N_INSNS (val);
9156 else
9157 *total = COSTS_N_INSNS (1);
9159 break;
9161 case HImode:
9162 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9164 *total = COSTS_N_INSNS (!speed ? 5 : 41);
9165 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9166 speed);
9168 else
9169 switch (INTVAL (XEXP (x, 1)))
9171 case 0:
9172 *total = 0;
9173 break;
9174 case 1:
9175 *total = COSTS_N_INSNS (2);
9176 break;
9177 case 15:
9178 *total = COSTS_N_INSNS (3);
9179 break;
9180 case 2:
9181 case 7:
9182 case 8:
9183 case 9:
9184 *total = COSTS_N_INSNS (4);
9185 break;
9186 case 10:
9187 case 14:
9188 *total = COSTS_N_INSNS (5);
9189 break;
9190 case 11:
9191 *total = COSTS_N_INSNS (!speed ? 5 : 6);
9192 break;
9193 case 12:
9194 *total = COSTS_N_INSNS (!speed ? 5 : 7);
9195 break;
9196 case 6:
9197 case 13:
9198 *total = COSTS_N_INSNS (!speed ? 5 : 8);
9199 break;
9200 default:
9201 *total = COSTS_N_INSNS (!speed ? 5 : 41);
9202 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9203 speed);
9205 break;
9207 case PSImode:
9208 if (!CONST_INT_P (XEXP (x, 1)))
9210 *total = COSTS_N_INSNS (!speed ? 6 : 73);
9212 else
9213 switch (INTVAL (XEXP (x, 1)))
9215 case 0:
9216 *total = 0;
9217 break;
9218 case 1:
9219 *total = COSTS_N_INSNS (3);
9220 break;
9221 case 16:
9222 case 8:
9223 *total = COSTS_N_INSNS (5);
9224 break;
9225 case 23:
9226 *total = COSTS_N_INSNS (4);
9227 break;
9228 default:
9229 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
9230 break;
9232 break;
9234 case SImode:
9235 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9237 *total = COSTS_N_INSNS (!speed ? 7 : 113);
9238 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9239 speed);
9241 else
9242 switch (INTVAL (XEXP (x, 1)))
9244 case 0:
9245 *total = 0;
9246 break;
9247 case 1:
9248 *total = COSTS_N_INSNS (4);
9249 break;
9250 case 8:
9251 case 16:
9252 case 24:
9253 *total = COSTS_N_INSNS (6);
9254 break;
9255 case 2:
9256 *total = COSTS_N_INSNS (!speed ? 7 : 8);
9257 break;
9258 case 31:
9259 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 5);
9260 break;
9261 default:
9262 *total = COSTS_N_INSNS (!speed ? 7 : 113);
9263 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9264 speed);
9266 break;
9268 default:
9269 return false;
9271 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9272 return true;
9274 case LSHIFTRT:
9275 switch (mode)
9277 case QImode:
9278 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9280 *total = COSTS_N_INSNS (!speed ? 4 : 17);
9281 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9282 speed);
9284 else
9286 val = INTVAL (XEXP (x, 1));
9287 if (val == 7)
9288 *total = COSTS_N_INSNS (3);
9289 else if (val >= 0 && val <= 7)
9290 *total = COSTS_N_INSNS (val);
9291 else
9292 *total = COSTS_N_INSNS (1);
9294 break;
9296 case HImode:
9297 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9299 *total = COSTS_N_INSNS (!speed ? 5 : 41);
9300 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9301 speed);
9303 else
9304 switch (INTVAL (XEXP (x, 1)))
9306 case 0:
9307 *total = 0;
9308 break;
9309 case 1:
9310 case 8:
9311 *total = COSTS_N_INSNS (2);
9312 break;
9313 case 9:
9314 *total = COSTS_N_INSNS (3);
9315 break;
9316 case 2:
9317 case 10:
9318 case 15:
9319 *total = COSTS_N_INSNS (4);
9320 break;
9321 case 7:
9322 case 11:
9323 *total = COSTS_N_INSNS (5);
9324 break;
9325 case 3:
9326 case 12:
9327 case 13:
9328 case 14:
9329 *total = COSTS_N_INSNS (!speed ? 5 : 6);
9330 break;
9331 case 4:
9332 *total = COSTS_N_INSNS (!speed ? 5 : 7);
9333 break;
9334 case 5:
9335 case 6:
9336 *total = COSTS_N_INSNS (!speed ? 5 : 9);
9337 break;
9338 default:
9339 *total = COSTS_N_INSNS (!speed ? 5 : 41);
9340 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9341 speed);
9343 break;
9345 case PSImode:
9346 if (!CONST_INT_P (XEXP (x, 1)))
9348 *total = COSTS_N_INSNS (!speed ? 6 : 73);
9350 else
9351 switch (INTVAL (XEXP (x, 1)))
9353 case 0:
9354 *total = 0;
9355 break;
9356 case 1:
9357 case 8:
9358 case 16:
9359 *total = COSTS_N_INSNS (3);
9360 break;
9361 case 23:
9362 *total = COSTS_N_INSNS (5);
9363 break;
9364 default:
9365 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
9366 break;
9368 break;
9370 case SImode:
9371 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9373 *total = COSTS_N_INSNS (!speed ? 7 : 113);
9374 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9375 speed);
9377 else
9378 switch (INTVAL (XEXP (x, 1)))
9380 case 0:
9381 *total = 0;
9382 break;
9383 case 1:
9384 *total = COSTS_N_INSNS (4);
9385 break;
9386 case 2:
9387 *total = COSTS_N_INSNS (!speed ? 7 : 8);
9388 break;
9389 case 8:
9390 case 16:
9391 case 24:
9392 *total = COSTS_N_INSNS (4);
9393 break;
9394 case 31:
9395 *total = COSTS_N_INSNS (6);
9396 break;
9397 default:
9398 *total = COSTS_N_INSNS (!speed ? 7 : 113);
9399 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9400 speed);
9402 break;
9404 default:
9405 return false;
9407 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9408 return true;
9410 case COMPARE:
9411 switch (GET_MODE (XEXP (x, 0)))
9413 case QImode:
9414 *total = COSTS_N_INSNS (1);
9415 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9416 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
9417 break;
9419 case HImode:
9420 *total = COSTS_N_INSNS (2);
9421 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9422 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
9423 else if (INTVAL (XEXP (x, 1)) != 0)
9424 *total += COSTS_N_INSNS (1);
9425 break;
9427 case PSImode:
9428 *total = COSTS_N_INSNS (3);
9429 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) != 0)
9430 *total += COSTS_N_INSNS (2);
9431 break;
9433 case SImode:
9434 *total = COSTS_N_INSNS (4);
9435 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9436 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
9437 else if (INTVAL (XEXP (x, 1)) != 0)
9438 *total += COSTS_N_INSNS (3);
9439 break;
9441 default:
9442 return false;
9444 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9445 return true;
9447 case TRUNCATE:
9448 if (AVR_HAVE_MUL
9449 && LSHIFTRT == GET_CODE (XEXP (x, 0))
9450 && MULT == GET_CODE (XEXP (XEXP (x, 0), 0))
9451 && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
9453 if (QImode == mode || HImode == mode)
9455 *total = COSTS_N_INSNS (2);
9456 return true;
9459 break;
9461 default:
9462 break;
9464 return false;
9468 /* Implement `TARGET_RTX_COSTS'. */
9470 static bool
9471 avr_rtx_costs (rtx x, int codearg, int outer_code,
9472 int opno, int *total, bool speed)
9474 bool done = avr_rtx_costs_1 (x, codearg, outer_code,
9475 opno, total, speed);
9477 if (avr_log.rtx_costs)
9479 avr_edump ("\n%?=%b (%s) total=%d, outer=%C:\n%r\n",
9480 done, speed ? "speed" : "size", *total, outer_code, x);
9483 return done;
9487 /* Implement `TARGET_ADDRESS_COST'. */
9489 static int
9490 avr_address_cost (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED,
9491 addr_space_t as ATTRIBUTE_UNUSED,
9492 bool speed ATTRIBUTE_UNUSED)
9494 int cost = 4;
9496 if (GET_CODE (x) == PLUS
9497 && CONST_INT_P (XEXP (x, 1))
9498 && (REG_P (XEXP (x, 0))
9499 || GET_CODE (XEXP (x, 0)) == SUBREG))
9501 if (INTVAL (XEXP (x, 1)) >= 61)
9502 cost = 18;
9504 else if (CONSTANT_ADDRESS_P (x))
9506 if (optimize > 0
9507 && io_address_operand (x, QImode))
9508 cost = 2;
9511 if (avr_log.address_cost)
9512 avr_edump ("\n%?: %d = %r\n", cost, x);
9514 return cost;
9517 /* Test for extra memory constraint 'Q'.
9518 It's a memory address based on Y or Z pointer with valid displacement. */
9521 extra_constraint_Q (rtx x)
9523 int ok = 0;
9525 if (GET_CODE (XEXP (x,0)) == PLUS
9526 && REG_P (XEXP (XEXP (x,0), 0))
9527 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
9528 && (INTVAL (XEXP (XEXP (x,0), 1))
9529 <= MAX_LD_OFFSET (GET_MODE (x))))
9531 rtx xx = XEXP (XEXP (x,0), 0);
9532 int regno = REGNO (xx);
9534 ok = (/* allocate pseudos */
9535 regno >= FIRST_PSEUDO_REGISTER
9536 /* strictly check */
9537 || regno == REG_Z || regno == REG_Y
9538 /* XXX frame & arg pointer checks */
9539 || xx == frame_pointer_rtx
9540 || xx == arg_pointer_rtx);
9542 if (avr_log.constraints)
9543 avr_edump ("\n%?=%d reload_completed=%d reload_in_progress=%d\n %r\n",
9544 ok, reload_completed, reload_in_progress, x);
9547 return ok;
9550 /* Convert condition code CONDITION to the valid AVR condition code. */
9552 RTX_CODE
9553 avr_normalize_condition (RTX_CODE condition)
9555 switch (condition)
9557 case GT:
9558 return GE;
9559 case GTU:
9560 return GEU;
9561 case LE:
9562 return LT;
9563 case LEU:
9564 return LTU;
9565 default:
9566 gcc_unreachable ();
9570 /* Helper function for `avr_reorg'. */
9572 static rtx
9573 avr_compare_pattern (rtx insn)
9575 rtx pattern = single_set (insn);
9577 if (pattern
9578 && NONJUMP_INSN_P (insn)
9579 && SET_DEST (pattern) == cc0_rtx
9580 && GET_CODE (SET_SRC (pattern)) == COMPARE)
9582 enum machine_mode mode0 = GET_MODE (XEXP (SET_SRC (pattern), 0));
9583 enum machine_mode mode1 = GET_MODE (XEXP (SET_SRC (pattern), 1));
9585 /* The 64-bit comparisons have fixed operands ACC_A and ACC_B.
9586 They must not be swapped, thus skip them. */
9588 if ((mode0 == VOIDmode || GET_MODE_SIZE (mode0) <= 4)
9589 && (mode1 == VOIDmode || GET_MODE_SIZE (mode1) <= 4))
9590 return pattern;
9593 return NULL_RTX;
9596 /* Helper function for `avr_reorg'. */
9598 /* Expansion of switch/case decision trees leads to code like
9600 cc0 = compare (Reg, Num)
9601 if (cc0 == 0)
9602 goto L1
9604 cc0 = compare (Reg, Num)
9605 if (cc0 > 0)
9606 goto L2
9608 The second comparison is superfluous and can be deleted.
9609 The second jump condition can be transformed from a
9610 "difficult" one to a "simple" one because "cc0 > 0" and
9611 "cc0 >= 0" will have the same effect here.
9613 This function relies on the way switch/case is being expaned
9614 as binary decision tree. For example code see PR 49903.
9616 Return TRUE if optimization performed.
9617 Return FALSE if nothing changed.
9619 INSN1 is a comparison, i.e. avr_compare_pattern != 0.
9621 We don't want to do this in text peephole because it is
9622 tedious to work out jump offsets there and the second comparison
9623 might have been transormed by `avr_reorg'.
9625 RTL peephole won't do because peephole2 does not scan across
9626 basic blocks. */
9628 static bool
9629 avr_reorg_remove_redundant_compare (rtx insn1)
9631 rtx comp1, ifelse1, xcond1, branch1;
9632 rtx comp2, ifelse2, xcond2, branch2, insn2;
9633 enum rtx_code code;
9634 rtx jump, target, cond;
9636 /* Look out for: compare1 - branch1 - compare2 - branch2 */
9638 branch1 = next_nonnote_nondebug_insn (insn1);
9639 if (!branch1 || !JUMP_P (branch1))
9640 return false;
9642 insn2 = next_nonnote_nondebug_insn (branch1);
9643 if (!insn2 || !avr_compare_pattern (insn2))
9644 return false;
9646 branch2 = next_nonnote_nondebug_insn (insn2);
9647 if (!branch2 || !JUMP_P (branch2))
9648 return false;
9650 comp1 = avr_compare_pattern (insn1);
9651 comp2 = avr_compare_pattern (insn2);
9652 xcond1 = single_set (branch1);
9653 xcond2 = single_set (branch2);
9655 if (!comp1 || !comp2
9656 || !rtx_equal_p (comp1, comp2)
9657 || !xcond1 || SET_DEST (xcond1) != pc_rtx
9658 || !xcond2 || SET_DEST (xcond2) != pc_rtx
9659 || IF_THEN_ELSE != GET_CODE (SET_SRC (xcond1))
9660 || IF_THEN_ELSE != GET_CODE (SET_SRC (xcond2)))
9662 return false;
9665 comp1 = SET_SRC (comp1);
9666 ifelse1 = SET_SRC (xcond1);
9667 ifelse2 = SET_SRC (xcond2);
9669 /* comp<n> is COMPARE now and ifelse<n> is IF_THEN_ELSE. */
9671 if (EQ != GET_CODE (XEXP (ifelse1, 0))
9672 || !REG_P (XEXP (comp1, 0))
9673 || !CONST_INT_P (XEXP (comp1, 1))
9674 || XEXP (ifelse1, 2) != pc_rtx
9675 || XEXP (ifelse2, 2) != pc_rtx
9676 || LABEL_REF != GET_CODE (XEXP (ifelse1, 1))
9677 || LABEL_REF != GET_CODE (XEXP (ifelse2, 1))
9678 || !COMPARISON_P (XEXP (ifelse2, 0))
9679 || cc0_rtx != XEXP (XEXP (ifelse1, 0), 0)
9680 || cc0_rtx != XEXP (XEXP (ifelse2, 0), 0)
9681 || const0_rtx != XEXP (XEXP (ifelse1, 0), 1)
9682 || const0_rtx != XEXP (XEXP (ifelse2, 0), 1))
9684 return false;
9687 /* We filtered the insn sequence to look like
9689 (set (cc0)
9690 (compare (reg:M N)
9691 (const_int VAL)))
9692 (set (pc)
9693 (if_then_else (eq (cc0)
9694 (const_int 0))
9695 (label_ref L1)
9696 (pc)))
9698 (set (cc0)
9699 (compare (reg:M N)
9700 (const_int VAL)))
9701 (set (pc)
9702 (if_then_else (CODE (cc0)
9703 (const_int 0))
9704 (label_ref L2)
9705 (pc)))
9708 code = GET_CODE (XEXP (ifelse2, 0));
9710 /* Map GT/GTU to GE/GEU which is easier for AVR.
9711 The first two instructions compare/branch on EQ
9712 so we may replace the difficult
9714 if (x == VAL) goto L1;
9715 if (x > VAL) goto L2;
9717 with easy
9719 if (x == VAL) goto L1;
9720 if (x >= VAL) goto L2;
9722 Similarly, replace LE/LEU by LT/LTU. */
9724 switch (code)
9726 case EQ:
9727 case LT: case LTU:
9728 case GE: case GEU:
9729 break;
9731 case LE: case LEU:
9732 case GT: case GTU:
9733 code = avr_normalize_condition (code);
9734 break;
9736 default:
9737 return false;
9740 /* Wrap the branches into UNSPECs so they won't be changed or
9741 optimized in the remainder. */
9743 target = XEXP (XEXP (ifelse1, 1), 0);
9744 cond = XEXP (ifelse1, 0);
9745 jump = emit_jump_insn_after (gen_branch_unspec (target, cond), insn1);
9747 JUMP_LABEL (jump) = JUMP_LABEL (branch1);
9749 target = XEXP (XEXP (ifelse2, 1), 0);
9750 cond = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
9751 jump = emit_jump_insn_after (gen_branch_unspec (target, cond), insn2);
9753 JUMP_LABEL (jump) = JUMP_LABEL (branch2);
9755 /* The comparisons in insn1 and insn2 are exactly the same;
9756 insn2 is superfluous so delete it. */
9758 delete_insn (insn2);
9759 delete_insn (branch1);
9760 delete_insn (branch2);
9762 return true;
9766 /* Implement `TARGET_MACHINE_DEPENDENT_REORG'. */
9767 /* Optimize conditional jumps. */
9769 static void
9770 avr_reorg (void)
9772 rtx insn = get_insns();
9774 for (insn = next_real_insn (insn); insn; insn = next_real_insn (insn))
9776 rtx pattern = avr_compare_pattern (insn);
9778 if (!pattern)
9779 continue;
9781 if (optimize
9782 && avr_reorg_remove_redundant_compare (insn))
9784 continue;
9787 if (compare_diff_p (insn))
9789 /* Now we work under compare insn with difficult branch. */
9791 rtx next = next_real_insn (insn);
9792 rtx pat = PATTERN (next);
9794 pattern = SET_SRC (pattern);
9796 if (true_regnum (XEXP (pattern, 0)) >= 0
9797 && true_regnum (XEXP (pattern, 1)) >= 0)
9799 rtx x = XEXP (pattern, 0);
9800 rtx src = SET_SRC (pat);
9801 rtx t = XEXP (src,0);
9802 PUT_CODE (t, swap_condition (GET_CODE (t)));
9803 XEXP (pattern, 0) = XEXP (pattern, 1);
9804 XEXP (pattern, 1) = x;
9805 INSN_CODE (next) = -1;
9807 else if (true_regnum (XEXP (pattern, 0)) >= 0
9808 && XEXP (pattern, 1) == const0_rtx)
9810 /* This is a tst insn, we can reverse it. */
9811 rtx src = SET_SRC (pat);
9812 rtx t = XEXP (src,0);
9814 PUT_CODE (t, swap_condition (GET_CODE (t)));
9815 XEXP (pattern, 1) = XEXP (pattern, 0);
9816 XEXP (pattern, 0) = const0_rtx;
9817 INSN_CODE (next) = -1;
9818 INSN_CODE (insn) = -1;
9820 else if (true_regnum (XEXP (pattern, 0)) >= 0
9821 && CONST_INT_P (XEXP (pattern, 1)))
9823 rtx x = XEXP (pattern, 1);
9824 rtx src = SET_SRC (pat);
9825 rtx t = XEXP (src,0);
9826 enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
9828 if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
9830 XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
9831 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
9832 INSN_CODE (next) = -1;
9833 INSN_CODE (insn) = -1;
9840 /* Returns register number for function return value.*/
9842 static inline unsigned int
9843 avr_ret_register (void)
9845 return 24;
9849 /* Implement `TARGET_FUNCTION_VALUE_REGNO_P'. */
9851 static bool
9852 avr_function_value_regno_p (const unsigned int regno)
9854 return (regno == avr_ret_register ());
9858 /* Implement `TARGET_LIBCALL_VALUE'. */
9859 /* Create an RTX representing the place where a
9860 library function returns a value of mode MODE. */
9862 static rtx
9863 avr_libcall_value (enum machine_mode mode,
9864 const_rtx func ATTRIBUTE_UNUSED)
9866 int offs = GET_MODE_SIZE (mode);
9868 if (offs <= 4)
9869 offs = (offs + 1) & ~1;
9871 return gen_rtx_REG (mode, avr_ret_register () + 2 - offs);
9875 /* Implement `TARGET_FUNCTION_VALUE'. */
9876 /* Create an RTX representing the place where a
9877 function returns a value of data type VALTYPE. */
9879 static rtx
9880 avr_function_value (const_tree type,
9881 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
9882 bool outgoing ATTRIBUTE_UNUSED)
9884 unsigned int offs;
9886 if (TYPE_MODE (type) != BLKmode)
9887 return avr_libcall_value (TYPE_MODE (type), NULL_RTX);
9889 offs = int_size_in_bytes (type);
9890 if (offs < 2)
9891 offs = 2;
9892 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
9893 offs = GET_MODE_SIZE (SImode);
9894 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
9895 offs = GET_MODE_SIZE (DImode);
9897 return gen_rtx_REG (BLKmode, avr_ret_register () + 2 - offs);
9901 test_hard_reg_class (enum reg_class rclass, rtx x)
9903 int regno = true_regnum (x);
9904 if (regno < 0)
9905 return 0;
9907 if (TEST_HARD_REG_CLASS (rclass, regno))
9908 return 1;
9910 return 0;
9914 /* Helper for jump_over_one_insn_p: Test if INSN is a 2-word instruction
9915 and thus is suitable to be skipped by CPSE, SBRC, etc. */
9917 static bool
9918 avr_2word_insn_p (rtx insn)
9920 if (avr_current_device->errata_skip
9921 || !insn
9922 || 2 != get_attr_length (insn))
9924 return false;
9927 switch (INSN_CODE (insn))
9929 default:
9930 return false;
9932 case CODE_FOR_movqi_insn:
9933 case CODE_FOR_movuqq_insn:
9934 case CODE_FOR_movqq_insn:
9936 rtx set = single_set (insn);
9937 rtx src = SET_SRC (set);
9938 rtx dest = SET_DEST (set);
9940 /* Factor out LDS and STS from movqi_insn. */
9942 if (MEM_P (dest)
9943 && (REG_P (src) || src == CONST0_RTX (GET_MODE (dest))))
9945 return CONSTANT_ADDRESS_P (XEXP (dest, 0));
9947 else if (REG_P (dest)
9948 && MEM_P (src))
9950 return CONSTANT_ADDRESS_P (XEXP (src, 0));
9953 return false;
9956 case CODE_FOR_call_insn:
9957 case CODE_FOR_call_value_insn:
9958 return true;
9964 jump_over_one_insn_p (rtx insn, rtx dest)
9966 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
9967 ? XEXP (dest, 0)
9968 : dest);
9969 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
9970 int dest_addr = INSN_ADDRESSES (uid);
9971 int jump_offset = dest_addr - jump_addr - get_attr_length (insn);
9973 return (jump_offset == 1
9974 || (jump_offset == 2
9975 && avr_2word_insn_p (next_active_insn (insn))));
9979 /* Worker function for `HARD_REGNO_MODE_OK'. */
9980 /* Returns 1 if a value of mode MODE can be stored starting with hard
9981 register number REGNO. On the enhanced core, anything larger than
9982 1 byte must start in even numbered register for "movw" to work
9983 (this way we don't have to check for odd registers everywhere). */
9986 avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
9988 /* NOTE: 8-bit values must not be disallowed for R28 or R29.
9989 Disallowing QI et al. in these regs might lead to code like
9990 (set (subreg:QI (reg:HI 28) n) ...)
9991 which will result in wrong code because reload does not
9992 handle SUBREGs of hard regsisters like this.
9993 This could be fixed in reload. However, it appears
9994 that fixing reload is not wanted by reload people. */
9996 /* Any GENERAL_REGS register can hold 8-bit values. */
9998 if (GET_MODE_SIZE (mode) == 1)
9999 return 1;
10001 /* FIXME: Ideally, the following test is not needed.
10002 However, it turned out that it can reduce the number
10003 of spill fails. AVR and it's poor endowment with
10004 address registers is extreme stress test for reload. */
10006 if (GET_MODE_SIZE (mode) >= 4
10007 && regno >= REG_X)
10008 return 0;
10010 /* All modes larger than 8 bits should start in an even register. */
10012 return !(regno & 1);
10016 /* Implement `HARD_REGNO_CALL_PART_CLOBBERED'. */
10019 avr_hard_regno_call_part_clobbered (unsigned regno, enum machine_mode mode)
10021 /* FIXME: This hook gets called with MODE:REGNO combinations that don't
10022 represent valid hard registers like, e.g. HI:29. Returning TRUE
10023 for such registers can lead to performance degradation as mentioned
10024 in PR53595. Thus, report invalid hard registers as FALSE. */
10026 if (!avr_hard_regno_mode_ok (regno, mode))
10027 return 0;
10029 /* Return true if any of the following boundaries is crossed:
10030 17/18, 27/28 and 29/30. */
10032 return ((regno < 18 && regno + GET_MODE_SIZE (mode) > 18)
10033 || (regno < REG_Y && regno + GET_MODE_SIZE (mode) > REG_Y)
10034 || (regno < REG_Z && regno + GET_MODE_SIZE (mode) > REG_Z));
10038 /* Implement `MODE_CODE_BASE_REG_CLASS'. */
10040 enum reg_class
10041 avr_mode_code_base_reg_class (enum machine_mode mode ATTRIBUTE_UNUSED,
10042 addr_space_t as, RTX_CODE outer_code,
10043 RTX_CODE index_code ATTRIBUTE_UNUSED)
10045 if (!ADDR_SPACE_GENERIC_P (as))
10047 return POINTER_Z_REGS;
10050 if (!avr_strict_X)
10051 return reload_completed ? BASE_POINTER_REGS : POINTER_REGS;
10053 return PLUS == outer_code ? BASE_POINTER_REGS : POINTER_REGS;
10057 /* Implement `REGNO_MODE_CODE_OK_FOR_BASE_P'. */
10059 bool
10060 avr_regno_mode_code_ok_for_base_p (int regno,
10061 enum machine_mode mode ATTRIBUTE_UNUSED,
10062 addr_space_t as ATTRIBUTE_UNUSED,
10063 RTX_CODE outer_code,
10064 RTX_CODE index_code ATTRIBUTE_UNUSED)
10066 bool ok = false;
10068 if (!ADDR_SPACE_GENERIC_P (as))
10070 if (regno < FIRST_PSEUDO_REGISTER
10071 && regno == REG_Z)
10073 return true;
10076 if (reg_renumber)
10078 regno = reg_renumber[regno];
10080 if (regno == REG_Z)
10082 return true;
10086 return false;
10089 if (regno < FIRST_PSEUDO_REGISTER
10090 && (regno == REG_X
10091 || regno == REG_Y
10092 || regno == REG_Z
10093 || regno == ARG_POINTER_REGNUM))
10095 ok = true;
10097 else if (reg_renumber)
10099 regno = reg_renumber[regno];
10101 if (regno == REG_X
10102 || regno == REG_Y
10103 || regno == REG_Z
10104 || regno == ARG_POINTER_REGNUM)
10106 ok = true;
10110 if (avr_strict_X
10111 && PLUS == outer_code
10112 && regno == REG_X)
10114 ok = false;
10117 return ok;
10121 /* A helper for `output_reload_insisf' and `output_reload_inhi'. */
10122 /* Set 32-bit register OP[0] to compile-time constant OP[1].
10123 CLOBBER_REG is a QI clobber register or NULL_RTX.
10124 LEN == NULL: output instructions.
10125 LEN != NULL: set *LEN to the length of the instruction sequence
10126 (in words) printed with LEN = NULL.
10127 If CLEAR_P is true, OP[0] had been cleard to Zero already.
10128 If CLEAR_P is false, nothing is known about OP[0].
10130 The effect on cc0 is as follows:
10132 Load 0 to any register except ZERO_REG : NONE
10133 Load ld register with any value : NONE
10134 Anything else: : CLOBBER */
10136 static void
10137 output_reload_in_const (rtx *op, rtx clobber_reg, int *len, bool clear_p)
10139 rtx src = op[1];
10140 rtx dest = op[0];
10141 rtx xval, xdest[4];
10142 int ival[4];
10143 int clobber_val = 1234;
10144 bool cooked_clobber_p = false;
10145 bool set_p = false;
10146 enum machine_mode mode = GET_MODE (dest);
10147 int n, n_bytes = GET_MODE_SIZE (mode);
10149 gcc_assert (REG_P (dest)
10150 && CONSTANT_P (src));
10152 if (len)
10153 *len = 0;
10155 /* (REG:SI 14) is special: It's neither in LD_REGS nor in NO_LD_REGS
10156 but has some subregs that are in LD_REGS. Use the MSB (REG:QI 17). */
10158 if (REGNO (dest) < 16
10159 && REGNO (dest) + GET_MODE_SIZE (mode) > 16)
10161 clobber_reg = all_regs_rtx[REGNO (dest) + n_bytes - 1];
10164 /* We might need a clobber reg but don't have one. Look at the value to
10165 be loaded more closely. A clobber is only needed if it is a symbol
10166 or contains a byte that is neither 0, -1 or a power of 2. */
10168 if (NULL_RTX == clobber_reg
10169 && !test_hard_reg_class (LD_REGS, dest)
10170 && (! (CONST_INT_P (src) || CONST_FIXED_P (src) || CONST_DOUBLE_P (src))
10171 || !avr_popcount_each_byte (src, n_bytes,
10172 (1 << 0) | (1 << 1) | (1 << 8))))
10174 /* We have no clobber register but need one. Cook one up.
10175 That's cheaper than loading from constant pool. */
10177 cooked_clobber_p = true;
10178 clobber_reg = all_regs_rtx[REG_Z + 1];
10179 avr_asm_len ("mov __tmp_reg__,%0", &clobber_reg, len, 1);
10182 /* Now start filling DEST from LSB to MSB. */
10184 for (n = 0; n < n_bytes; n++)
10186 int ldreg_p;
10187 bool done_byte = false;
10188 int j;
10189 rtx xop[3];
10191 /* Crop the n-th destination byte. */
10193 xdest[n] = simplify_gen_subreg (QImode, dest, mode, n);
10194 ldreg_p = test_hard_reg_class (LD_REGS, xdest[n]);
10196 if (!CONST_INT_P (src)
10197 && !CONST_FIXED_P (src)
10198 && !CONST_DOUBLE_P (src))
10200 static const char* const asm_code[][2] =
10202 { "ldi %2,lo8(%1)" CR_TAB "mov %0,%2", "ldi %0,lo8(%1)" },
10203 { "ldi %2,hi8(%1)" CR_TAB "mov %0,%2", "ldi %0,hi8(%1)" },
10204 { "ldi %2,hlo8(%1)" CR_TAB "mov %0,%2", "ldi %0,hlo8(%1)" },
10205 { "ldi %2,hhi8(%1)" CR_TAB "mov %0,%2", "ldi %0,hhi8(%1)" }
10208 xop[0] = xdest[n];
10209 xop[1] = src;
10210 xop[2] = clobber_reg;
10212 avr_asm_len (asm_code[n][ldreg_p], xop, len, ldreg_p ? 1 : 2);
10214 continue;
10217 /* Crop the n-th source byte. */
10219 xval = simplify_gen_subreg (QImode, src, mode, n);
10220 ival[n] = INTVAL (xval);
10222 /* Look if we can reuse the low word by means of MOVW. */
10224 if (n == 2
10225 && n_bytes >= 4
10226 && AVR_HAVE_MOVW)
10228 rtx lo16 = simplify_gen_subreg (HImode, src, mode, 0);
10229 rtx hi16 = simplify_gen_subreg (HImode, src, mode, 2);
10231 if (INTVAL (lo16) == INTVAL (hi16))
10233 if (0 != INTVAL (lo16)
10234 || !clear_p)
10236 avr_asm_len ("movw %C0,%A0", &op[0], len, 1);
10239 break;
10243 /* Don't use CLR so that cc0 is set as expected. */
10245 if (ival[n] == 0)
10247 if (!clear_p)
10248 avr_asm_len (ldreg_p ? "ldi %0,0"
10249 : ZERO_REGNO == REGNO (xdest[n]) ? "clr %0"
10250 : "mov %0,__zero_reg__",
10251 &xdest[n], len, 1);
10252 continue;
10255 if (clobber_val == ival[n]
10256 && REGNO (clobber_reg) == REGNO (xdest[n]))
10258 continue;
10261 /* LD_REGS can use LDI to move a constant value */
10263 if (ldreg_p)
10265 xop[0] = xdest[n];
10266 xop[1] = xval;
10267 avr_asm_len ("ldi %0,lo8(%1)", xop, len, 1);
10268 continue;
10271 /* Try to reuse value already loaded in some lower byte. */
10273 for (j = 0; j < n; j++)
10274 if (ival[j] == ival[n])
10276 xop[0] = xdest[n];
10277 xop[1] = xdest[j];
10279 avr_asm_len ("mov %0,%1", xop, len, 1);
10280 done_byte = true;
10281 break;
10284 if (done_byte)
10285 continue;
10287 /* Need no clobber reg for -1: Use CLR/DEC */
10289 if (-1 == ival[n])
10291 if (!clear_p)
10292 avr_asm_len ("clr %0", &xdest[n], len, 1);
10294 avr_asm_len ("dec %0", &xdest[n], len, 1);
10295 continue;
10297 else if (1 == ival[n])
10299 if (!clear_p)
10300 avr_asm_len ("clr %0", &xdest[n], len, 1);
10302 avr_asm_len ("inc %0", &xdest[n], len, 1);
10303 continue;
10306 /* Use T flag or INC to manage powers of 2 if we have
10307 no clobber reg. */
10309 if (NULL_RTX == clobber_reg
10310 && single_one_operand (xval, QImode))
10312 xop[0] = xdest[n];
10313 xop[1] = GEN_INT (exact_log2 (ival[n] & GET_MODE_MASK (QImode)));
10315 gcc_assert (constm1_rtx != xop[1]);
10317 if (!set_p)
10319 set_p = true;
10320 avr_asm_len ("set", xop, len, 1);
10323 if (!clear_p)
10324 avr_asm_len ("clr %0", xop, len, 1);
10326 avr_asm_len ("bld %0,%1", xop, len, 1);
10327 continue;
10330 /* We actually need the LD_REGS clobber reg. */
10332 gcc_assert (NULL_RTX != clobber_reg);
10334 xop[0] = xdest[n];
10335 xop[1] = xval;
10336 xop[2] = clobber_reg;
10337 clobber_val = ival[n];
10339 avr_asm_len ("ldi %2,lo8(%1)" CR_TAB
10340 "mov %0,%2", xop, len, 2);
10343 /* If we cooked up a clobber reg above, restore it. */
10345 if (cooked_clobber_p)
10347 avr_asm_len ("mov %0,__tmp_reg__", &clobber_reg, len, 1);
10352 /* Reload the constant OP[1] into the HI register OP[0].
10353 CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
10354 into a NO_LD_REGS register. If CLOBBER_REG is NULL_RTX we either don't
10355 need a clobber reg or have to cook one up.
10357 PLEN == NULL: Output instructions.
10358 PLEN != NULL: Output nothing. Set *PLEN to number of words occupied
10359 by the insns printed.
10361 Return "". */
10363 const char*
10364 output_reload_inhi (rtx *op, rtx clobber_reg, int *plen)
10366 output_reload_in_const (op, clobber_reg, plen, false);
10367 return "";
10371 /* Reload a SI or SF compile time constant OP[1] into the register OP[0].
10372 CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
10373 into a NO_LD_REGS register. If CLOBBER_REG is NULL_RTX we either don't
10374 need a clobber reg or have to cook one up.
10376 LEN == NULL: Output instructions.
10378 LEN != NULL: Output nothing. Set *LEN to number of words occupied
10379 by the insns printed.
10381 Return "". */
10383 const char *
10384 output_reload_insisf (rtx *op, rtx clobber_reg, int *len)
10386 if (AVR_HAVE_MOVW
10387 && !test_hard_reg_class (LD_REGS, op[0])
10388 && (CONST_INT_P (op[1])
10389 || CONST_FIXED_P (op[1])
10390 || CONST_DOUBLE_P (op[1])))
10392 int len_clr, len_noclr;
10394 /* In some cases it is better to clear the destination beforehand, e.g.
10396 CLR R2 CLR R3 MOVW R4,R2 INC R2
10398 is shorther than
10400 CLR R2 INC R2 CLR R3 CLR R4 CLR R5
10402 We find it too tedious to work that out in the print function.
10403 Instead, we call the print function twice to get the lengths of
10404 both methods and use the shortest one. */
10406 output_reload_in_const (op, clobber_reg, &len_clr, true);
10407 output_reload_in_const (op, clobber_reg, &len_noclr, false);
10409 if (len_noclr - len_clr == 4)
10411 /* Default needs 4 CLR instructions: clear register beforehand. */
10413 avr_asm_len ("mov %A0,__zero_reg__" CR_TAB
10414 "mov %B0,__zero_reg__" CR_TAB
10415 "movw %C0,%A0", &op[0], len, 3);
10417 output_reload_in_const (op, clobber_reg, len, true);
10419 if (len)
10420 *len += 3;
10422 return "";
10426 /* Default: destination not pre-cleared. */
10428 output_reload_in_const (op, clobber_reg, len, false);
10429 return "";
10432 const char*
10433 avr_out_reload_inpsi (rtx *op, rtx clobber_reg, int *len)
10435 output_reload_in_const (op, clobber_reg, len, false);
10436 return "";
10440 /* Worker function for `ASM_OUTPUT_ADDR_VEC_ELT'. */
10442 void
10443 avr_output_addr_vec_elt (FILE *stream, int value)
10445 if (AVR_HAVE_JMP_CALL)
10446 fprintf (stream, "\t.word gs(.L%d)\n", value);
10447 else
10448 fprintf (stream, "\trjmp .L%d\n", value);
10452 /* Implement `TARGET_HARD_REGNO_SCRATCH_OK'. */
10453 /* Returns true if SCRATCH are safe to be allocated as a scratch
10454 registers (for a define_peephole2) in the current function. */
10456 static bool
10457 avr_hard_regno_scratch_ok (unsigned int regno)
10459 /* Interrupt functions can only use registers that have already been saved
10460 by the prologue, even if they would normally be call-clobbered. */
10462 if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
10463 && !df_regs_ever_live_p (regno))
10464 return false;
10466 /* Don't allow hard registers that might be part of the frame pointer.
10467 Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
10468 and don't care for a frame pointer that spans more than one register. */
10470 if ((!reload_completed || frame_pointer_needed)
10471 && (regno == REG_Y || regno == REG_Y + 1))
10473 return false;
10476 return true;
10480 /* Worker function for `HARD_REGNO_RENAME_OK'. */
10481 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
10484 avr_hard_regno_rename_ok (unsigned int old_reg,
10485 unsigned int new_reg)
10487 /* Interrupt functions can only use registers that have already been
10488 saved by the prologue, even if they would normally be
10489 call-clobbered. */
10491 if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
10492 && !df_regs_ever_live_p (new_reg))
10493 return 0;
10495 /* Don't allow hard registers that might be part of the frame pointer.
10496 Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
10497 and don't care for a frame pointer that spans more than one register. */
10499 if ((!reload_completed || frame_pointer_needed)
10500 && (old_reg == REG_Y || old_reg == REG_Y + 1
10501 || new_reg == REG_Y || new_reg == REG_Y + 1))
10503 return 0;
10506 return 1;
10509 /* Output a branch that tests a single bit of a register (QI, HI, SI or DImode)
10510 or memory location in the I/O space (QImode only).
10512 Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
10513 Operand 1: register operand to test, or CONST_INT memory address.
10514 Operand 2: bit number.
10515 Operand 3: label to jump to if the test is true. */
10517 const char*
10518 avr_out_sbxx_branch (rtx insn, rtx operands[])
10520 enum rtx_code comp = GET_CODE (operands[0]);
10521 bool long_jump = get_attr_length (insn) >= 4;
10522 bool reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
10524 if (comp == GE)
10525 comp = EQ;
10526 else if (comp == LT)
10527 comp = NE;
10529 if (reverse)
10530 comp = reverse_condition (comp);
10532 switch (GET_CODE (operands[1]))
10534 default:
10535 gcc_unreachable();
10537 case CONST_INT:
10539 if (low_io_address_operand (operands[1], QImode))
10541 if (comp == EQ)
10542 output_asm_insn ("sbis %i1,%2", operands);
10543 else
10544 output_asm_insn ("sbic %i1,%2", operands);
10546 else
10548 output_asm_insn ("in __tmp_reg__,%i1", operands);
10549 if (comp == EQ)
10550 output_asm_insn ("sbrs __tmp_reg__,%2", operands);
10551 else
10552 output_asm_insn ("sbrc __tmp_reg__,%2", operands);
10555 break; /* CONST_INT */
10557 case REG:
10559 if (comp == EQ)
10560 output_asm_insn ("sbrs %T1%T2", operands);
10561 else
10562 output_asm_insn ("sbrc %T1%T2", operands);
10564 break; /* REG */
10565 } /* switch */
10567 if (long_jump)
10568 return ("rjmp .+4" CR_TAB
10569 "jmp %x3");
10571 if (!reverse)
10572 return "rjmp %x3";
10574 return "";
10577 /* Worker function for `TARGET_ASM_CONSTRUCTOR'. */
10579 static void
10580 avr_asm_out_ctor (rtx symbol, int priority)
10582 fputs ("\t.global __do_global_ctors\n", asm_out_file);
10583 default_ctor_section_asm_out_constructor (symbol, priority);
10587 /* Worker function for `TARGET_ASM_DESTRUCTOR'. */
10589 static void
10590 avr_asm_out_dtor (rtx symbol, int priority)
10592 fputs ("\t.global __do_global_dtors\n", asm_out_file);
10593 default_dtor_section_asm_out_destructor (symbol, priority);
10597 /* Worker function for `TARGET_RETURN_IN_MEMORY'. */
10599 static bool
10600 avr_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
10602 if (TYPE_MODE (type) == BLKmode)
10604 HOST_WIDE_INT size = int_size_in_bytes (type);
10605 return (size == -1 || size > 8);
10607 else
10608 return false;
10612 /* Implement `CASE_VALUES_THRESHOLD'. */
10613 /* Supply the default for --param case-values-threshold=0 */
10615 static unsigned int
10616 avr_case_values_threshold (void)
10618 /* The exact break-even point between a jump table and an if-else tree
10619 depends on several factors not available here like, e.g. if 8-bit
10620 comparisons can be used in the if-else tree or not, on the
10621 range of the case values, if the case value can be reused, on the
10622 register allocation, etc. '7' appears to be a good choice. */
10624 return 7;
10628 /* Implement `TARGET_ADDR_SPACE_ADDRESS_MODE'. */
10630 static enum machine_mode
10631 avr_addr_space_address_mode (addr_space_t as)
10633 return avr_addrspace[as].pointer_size == 3 ? PSImode : HImode;
10637 /* Implement `TARGET_ADDR_SPACE_POINTER_MODE'. */
10639 static enum machine_mode
10640 avr_addr_space_pointer_mode (addr_space_t as)
10642 return avr_addr_space_address_mode (as);
10646 /* Helper for following function. */
10648 static bool
10649 avr_reg_ok_for_pgm_addr (rtx reg, bool strict)
10651 gcc_assert (REG_P (reg));
10653 if (strict)
10655 return REGNO (reg) == REG_Z;
10658 /* Avoid combine to propagate hard regs. */
10660 if (can_create_pseudo_p()
10661 && REGNO (reg) < REG_Z)
10663 return false;
10666 return true;
10670 /* Implement `TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P'. */
10672 static bool
10673 avr_addr_space_legitimate_address_p (enum machine_mode mode, rtx x,
10674 bool strict, addr_space_t as)
10676 bool ok = false;
10678 switch (as)
10680 default:
10681 gcc_unreachable();
10683 case ADDR_SPACE_GENERIC:
10684 return avr_legitimate_address_p (mode, x, strict);
10686 case ADDR_SPACE_FLASH:
10687 case ADDR_SPACE_FLASH1:
10688 case ADDR_SPACE_FLASH2:
10689 case ADDR_SPACE_FLASH3:
10690 case ADDR_SPACE_FLASH4:
10691 case ADDR_SPACE_FLASH5:
10693 switch (GET_CODE (x))
10695 case REG:
10696 ok = avr_reg_ok_for_pgm_addr (x, strict);
10697 break;
10699 case POST_INC:
10700 ok = avr_reg_ok_for_pgm_addr (XEXP (x, 0), strict);
10701 break;
10703 default:
10704 break;
10707 break; /* FLASH */
10709 case ADDR_SPACE_MEMX:
10710 if (REG_P (x))
10711 ok = (!strict
10712 && can_create_pseudo_p());
10714 if (LO_SUM == GET_CODE (x))
10716 rtx hi = XEXP (x, 0);
10717 rtx lo = XEXP (x, 1);
10719 ok = (REG_P (hi)
10720 && (!strict || REGNO (hi) < FIRST_PSEUDO_REGISTER)
10721 && REG_P (lo)
10722 && REGNO (lo) == REG_Z);
10725 break; /* MEMX */
10728 if (avr_log.legitimate_address_p)
10730 avr_edump ("\n%?: ret=%b, mode=%m strict=%d "
10731 "reload_completed=%d reload_in_progress=%d %s:",
10732 ok, mode, strict, reload_completed, reload_in_progress,
10733 reg_renumber ? "(reg_renumber)" : "");
10735 if (GET_CODE (x) == PLUS
10736 && REG_P (XEXP (x, 0))
10737 && CONST_INT_P (XEXP (x, 1))
10738 && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
10739 && reg_renumber)
10741 avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
10742 true_regnum (XEXP (x, 0)));
10745 avr_edump ("\n%r\n", x);
10748 return ok;
10752 /* Implement `TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS'. */
10754 static rtx
10755 avr_addr_space_legitimize_address (rtx x, rtx old_x,
10756 enum machine_mode mode, addr_space_t as)
10758 if (ADDR_SPACE_GENERIC_P (as))
10759 return avr_legitimize_address (x, old_x, mode);
10761 if (avr_log.legitimize_address)
10763 avr_edump ("\n%?: mode=%m\n %r\n", mode, old_x);
10766 return old_x;
10770 /* Implement `TARGET_ADDR_SPACE_CONVERT'. */
10772 static rtx
10773 avr_addr_space_convert (rtx src, tree type_from, tree type_to)
10775 addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (type_from));
10776 addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type_to));
10778 if (avr_log.progmem)
10779 avr_edump ("\n%!: op = %r\nfrom = %t\nto = %t\n",
10780 src, type_from, type_to);
10782 /* Up-casting from 16-bit to 24-bit pointer. */
10784 if (as_from != ADDR_SPACE_MEMX
10785 && as_to == ADDR_SPACE_MEMX)
10787 int msb;
10788 rtx sym = src;
10789 rtx reg = gen_reg_rtx (PSImode);
10791 while (CONST == GET_CODE (sym) || PLUS == GET_CODE (sym))
10792 sym = XEXP (sym, 0);
10794 /* Look at symbol flags: avr_encode_section_info set the flags
10795 also if attribute progmem was seen so that we get the right
10796 promotion for, e.g. PSTR-like strings that reside in generic space
10797 but are located in flash. In that case we patch the incoming
10798 address space. */
10800 if (SYMBOL_REF == GET_CODE (sym)
10801 && ADDR_SPACE_FLASH == AVR_SYMBOL_GET_ADDR_SPACE (sym))
10803 as_from = ADDR_SPACE_FLASH;
10806 /* Linearize memory: RAM has bit 23 set. */
10808 msb = ADDR_SPACE_GENERIC_P (as_from)
10809 ? 0x80
10810 : avr_addrspace[as_from].segment;
10812 src = force_reg (Pmode, src);
10814 emit_insn (msb == 0
10815 ? gen_zero_extendhipsi2 (reg, src)
10816 : gen_n_extendhipsi2 (reg, gen_int_mode (msb, QImode), src));
10818 return reg;
10821 /* Down-casting from 24-bit to 16-bit throws away the high byte. */
10823 if (as_from == ADDR_SPACE_MEMX
10824 && as_to != ADDR_SPACE_MEMX)
10826 rtx new_src = gen_reg_rtx (Pmode);
10828 src = force_reg (PSImode, src);
10830 emit_move_insn (new_src,
10831 simplify_gen_subreg (Pmode, src, PSImode, 0));
10832 return new_src;
10835 return src;
10839 /* Implement `TARGET_ADDR_SPACE_SUBSET_P'. */
10841 static bool
10842 avr_addr_space_subset_p (addr_space_t subset ATTRIBUTE_UNUSED,
10843 addr_space_t superset ATTRIBUTE_UNUSED)
10845 /* Allow any kind of pointer mess. */
10847 return true;
10851 /* Implement `TARGET_CONVERT_TO_TYPE'. */
10853 static tree
10854 avr_convert_to_type (tree type, tree expr)
10856 /* Print a diagnose for pointer conversion that changes the address
10857 space of the pointer target to a non-enclosing address space,
10858 provided -Waddr-space-convert is on.
10860 FIXME: Filter out cases where the target object is known to
10861 be located in the right memory, like in
10863 (const __flash*) PSTR ("text")
10865 Also try to distinguish between explicit casts requested by
10866 the user and implicit casts like
10868 void f (const __flash char*);
10870 void g (const char *p)
10872 f ((const __flash*) p);
10875 under the assumption that an explicit casts means that the user
10876 knows what he is doing, e.g. interface with PSTR or old style
10877 code with progmem and pgm_read_xxx.
10880 if (avr_warn_addr_space_convert
10881 && expr != error_mark_node
10882 && POINTER_TYPE_P (type)
10883 && POINTER_TYPE_P (TREE_TYPE (expr)))
10885 addr_space_t as_old = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
10886 addr_space_t as_new = TYPE_ADDR_SPACE (TREE_TYPE (type));
10888 if (avr_log.progmem)
10889 avr_edump ("%?: type = %t\nexpr = %t\n\n", type, expr);
10891 if (as_new != ADDR_SPACE_MEMX
10892 && as_new != as_old)
10894 location_t loc = EXPR_LOCATION (expr);
10895 const char *name_old = avr_addrspace[as_old].name;
10896 const char *name_new = avr_addrspace[as_new].name;
10898 warning (OPT_Waddr_space_convert,
10899 "conversion from address space %qs to address space %qs",
10900 ADDR_SPACE_GENERIC_P (as_old) ? "generic" : name_old,
10901 ADDR_SPACE_GENERIC_P (as_new) ? "generic" : name_new);
10903 return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, expr);
10907 return NULL_TREE;
10911 /* Worker function for movmemhi expander.
10912 XOP[0] Destination as MEM:BLK
10913 XOP[1] Source " "
10914 XOP[2] # Bytes to copy
10916 Return TRUE if the expansion is accomplished.
10917 Return FALSE if the operand compination is not supported. */
10919 bool
10920 avr_emit_movmemhi (rtx *xop)
10922 HOST_WIDE_INT count;
10923 enum machine_mode loop_mode;
10924 addr_space_t as = MEM_ADDR_SPACE (xop[1]);
10925 rtx loop_reg, addr1, a_src, a_dest, insn, xas;
10926 rtx a_hi8 = NULL_RTX;
10928 if (avr_mem_flash_p (xop[0]))
10929 return false;
10931 if (!CONST_INT_P (xop[2]))
10932 return false;
10934 count = INTVAL (xop[2]);
10935 if (count <= 0)
10936 return false;
10938 a_src = XEXP (xop[1], 0);
10939 a_dest = XEXP (xop[0], 0);
10941 if (PSImode == GET_MODE (a_src))
10943 gcc_assert (as == ADDR_SPACE_MEMX);
10945 loop_mode = (count < 0x100) ? QImode : HImode;
10946 loop_reg = gen_rtx_REG (loop_mode, 24);
10947 emit_move_insn (loop_reg, gen_int_mode (count, loop_mode));
10949 addr1 = simplify_gen_subreg (HImode, a_src, PSImode, 0);
10950 a_hi8 = simplify_gen_subreg (QImode, a_src, PSImode, 2);
10952 else
10954 int segment = avr_addrspace[as].segment;
10956 if (segment
10957 && avr_current_device->n_flash > 1)
10959 a_hi8 = GEN_INT (segment);
10960 emit_move_insn (rampz_rtx, a_hi8 = copy_to_mode_reg (QImode, a_hi8));
10962 else if (!ADDR_SPACE_GENERIC_P (as))
10964 as = ADDR_SPACE_FLASH;
10967 addr1 = a_src;
10969 loop_mode = (count <= 0x100) ? QImode : HImode;
10970 loop_reg = copy_to_mode_reg (loop_mode, gen_int_mode (count, loop_mode));
10973 xas = GEN_INT (as);
10975 /* FIXME: Register allocator might come up with spill fails if it is left
10976 on its own. Thus, we allocate the pointer registers by hand:
10977 Z = source address
10978 X = destination address */
10980 emit_move_insn (lpm_addr_reg_rtx, addr1);
10981 emit_move_insn (gen_rtx_REG (HImode, REG_X), a_dest);
10983 /* FIXME: Register allocator does a bad job and might spill address
10984 register(s) inside the loop leading to additional move instruction
10985 to/from stack which could clobber tmp_reg. Thus, do *not* emit
10986 load and store as separate insns. Instead, we perform the copy
10987 by means of one monolithic insn. */
10989 gcc_assert (TMP_REGNO == LPM_REGNO);
10991 if (as != ADDR_SPACE_MEMX)
10993 /* Load instruction ([E]LPM or LD) is known at compile time:
10994 Do the copy-loop inline. */
10996 rtx (*fun) (rtx, rtx, rtx)
10997 = QImode == loop_mode ? gen_movmem_qi : gen_movmem_hi;
10999 insn = fun (xas, loop_reg, loop_reg);
11001 else
11003 rtx (*fun) (rtx, rtx)
11004 = QImode == loop_mode ? gen_movmemx_qi : gen_movmemx_hi;
11006 emit_move_insn (gen_rtx_REG (QImode, 23), a_hi8);
11008 insn = fun (xas, GEN_INT (avr_addr.rampz));
11011 set_mem_addr_space (SET_SRC (XVECEXP (insn, 0, 0)), as);
11012 emit_insn (insn);
11014 return true;
11018 /* Print assembler for movmem_qi, movmem_hi insns...
11019 $0 : Address Space
11020 $1, $2 : Loop register
11021 Z : Source address
11022 X : Destination address
11025 const char*
11026 avr_out_movmem (rtx insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
11028 addr_space_t as = (addr_space_t) INTVAL (op[0]);
11029 enum machine_mode loop_mode = GET_MODE (op[1]);
11030 bool sbiw_p = test_hard_reg_class (ADDW_REGS, op[1]);
11031 rtx xop[3];
11033 if (plen)
11034 *plen = 0;
11036 xop[0] = op[0];
11037 xop[1] = op[1];
11038 xop[2] = tmp_reg_rtx;
11040 /* Loop label */
11042 avr_asm_len ("0:", xop, plen, 0);
11044 /* Load with post-increment */
11046 switch (as)
11048 default:
11049 gcc_unreachable();
11051 case ADDR_SPACE_GENERIC:
11053 avr_asm_len ("ld %2,Z+", xop, plen, 1);
11054 break;
11056 case ADDR_SPACE_FLASH:
11058 if (AVR_HAVE_LPMX)
11059 avr_asm_len ("lpm %2,Z+", xop, plen, 1);
11060 else
11061 avr_asm_len ("lpm" CR_TAB
11062 "adiw r30,1", xop, plen, 2);
11063 break;
11065 case ADDR_SPACE_FLASH1:
11066 case ADDR_SPACE_FLASH2:
11067 case ADDR_SPACE_FLASH3:
11068 case ADDR_SPACE_FLASH4:
11069 case ADDR_SPACE_FLASH5:
11071 if (AVR_HAVE_ELPMX)
11072 avr_asm_len ("elpm %2,Z+", xop, plen, 1);
11073 else
11074 avr_asm_len ("elpm" CR_TAB
11075 "adiw r30,1", xop, plen, 2);
11076 break;
11079 /* Store with post-increment */
11081 avr_asm_len ("st X+,%2", xop, plen, 1);
11083 /* Decrement loop-counter and set Z-flag */
11085 if (QImode == loop_mode)
11087 avr_asm_len ("dec %1", xop, plen, 1);
11089 else if (sbiw_p)
11091 avr_asm_len ("sbiw %1,1", xop, plen, 1);
11093 else
11095 avr_asm_len ("subi %A1,1" CR_TAB
11096 "sbci %B1,0", xop, plen, 2);
11099 /* Loop until zero */
11101 return avr_asm_len ("brne 0b", xop, plen, 1);
11106 /* Helper for __builtin_avr_delay_cycles */
11108 static rtx
11109 avr_mem_clobber (void)
11111 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11112 MEM_VOLATILE_P (mem) = 1;
11113 return mem;
11116 static void
11117 avr_expand_delay_cycles (rtx operands0)
11119 unsigned HOST_WIDE_INT cycles = UINTVAL (operands0) & GET_MODE_MASK (SImode);
11120 unsigned HOST_WIDE_INT cycles_used;
11121 unsigned HOST_WIDE_INT loop_count;
11123 if (IN_RANGE (cycles, 83886082, 0xFFFFFFFF))
11125 loop_count = ((cycles - 9) / 6) + 1;
11126 cycles_used = ((loop_count - 1) * 6) + 9;
11127 emit_insn (gen_delay_cycles_4 (gen_int_mode (loop_count, SImode),
11128 avr_mem_clobber()));
11129 cycles -= cycles_used;
11132 if (IN_RANGE (cycles, 262145, 83886081))
11134 loop_count = ((cycles - 7) / 5) + 1;
11135 if (loop_count > 0xFFFFFF)
11136 loop_count = 0xFFFFFF;
11137 cycles_used = ((loop_count - 1) * 5) + 7;
11138 emit_insn (gen_delay_cycles_3 (gen_int_mode (loop_count, SImode),
11139 avr_mem_clobber()));
11140 cycles -= cycles_used;
11143 if (IN_RANGE (cycles, 768, 262144))
11145 loop_count = ((cycles - 5) / 4) + 1;
11146 if (loop_count > 0xFFFF)
11147 loop_count = 0xFFFF;
11148 cycles_used = ((loop_count - 1) * 4) + 5;
11149 emit_insn (gen_delay_cycles_2 (gen_int_mode (loop_count, HImode),
11150 avr_mem_clobber()));
11151 cycles -= cycles_used;
11154 if (IN_RANGE (cycles, 6, 767))
11156 loop_count = cycles / 3;
11157 if (loop_count > 255)
11158 loop_count = 255;
11159 cycles_used = loop_count * 3;
11160 emit_insn (gen_delay_cycles_1 (gen_int_mode (loop_count, QImode),
11161 avr_mem_clobber()));
11162 cycles -= cycles_used;
11165 while (cycles >= 2)
11167 emit_insn (gen_nopv (GEN_INT(2)));
11168 cycles -= 2;
11171 if (cycles == 1)
11173 emit_insn (gen_nopv (GEN_INT(1)));
11174 cycles--;
11179 /* Return VAL * BASE + DIGIT. BASE = 0 is shortcut for BASE = 2^{32} */
11181 static double_int
11182 avr_double_int_push_digit (double_int val, int base,
11183 unsigned HOST_WIDE_INT digit)
11185 val = 0 == base
11186 ? val.llshift (32, 64)
11187 : val * double_int::from_uhwi (base);
11189 return val + double_int::from_uhwi (digit);
11193 /* Compute the image of x under f, i.e. perform x --> f(x) */
11195 static int
11196 avr_map (double_int f, int x)
11198 return 0xf & f.lrshift (4*x, 64).to_uhwi ();
11202 /* Return some metrics of map A. */
11204 enum
11206 /* Number of fixed points in { 0 ... 7 } */
11207 MAP_FIXED_0_7,
11209 /* Size of preimage of non-fixed points in { 0 ... 7 } */
11210 MAP_NONFIXED_0_7,
11212 /* Mask representing the fixed points in { 0 ... 7 } */
11213 MAP_MASK_FIXED_0_7,
11215 /* Size of the preimage of { 0 ... 7 } */
11216 MAP_PREIMAGE_0_7,
11218 /* Mask that represents the preimage of { f } */
11219 MAP_MASK_PREIMAGE_F
11222 static unsigned
11223 avr_map_metric (double_int a, int mode)
11225 unsigned i, metric = 0;
11227 for (i = 0; i < 8; i++)
11229 unsigned ai = avr_map (a, i);
11231 if (mode == MAP_FIXED_0_7)
11232 metric += ai == i;
11233 else if (mode == MAP_NONFIXED_0_7)
11234 metric += ai < 8 && ai != i;
11235 else if (mode == MAP_MASK_FIXED_0_7)
11236 metric |= ((unsigned) (ai == i)) << i;
11237 else if (mode == MAP_PREIMAGE_0_7)
11238 metric += ai < 8;
11239 else if (mode == MAP_MASK_PREIMAGE_F)
11240 metric |= ((unsigned) (ai == 0xf)) << i;
11241 else
11242 gcc_unreachable();
11245 return metric;
11249 /* Return true if IVAL has a 0xf in its hexadecimal representation
11250 and false, otherwise. Only nibbles 0..7 are taken into account.
11251 Used as constraint helper for C0f and Cxf. */
11253 bool
11254 avr_has_nibble_0xf (rtx ival)
11256 return 0 != avr_map_metric (rtx_to_double_int (ival), MAP_MASK_PREIMAGE_F);
11260 /* We have a set of bits that are mapped by a function F.
11261 Try to decompose F by means of a second function G so that
11263 F = F o G^-1 o G
11267 cost (F o G^-1) + cost (G) < cost (F)
11269 Example: Suppose builtin insert_bits supplies us with the map
11270 F = 0x3210ffff. Instead of doing 4 bit insertions to get the high
11271 nibble of the result, we can just as well rotate the bits before inserting
11272 them and use the map 0x7654ffff which is cheaper than the original map.
11273 For this example G = G^-1 = 0x32107654 and F o G^-1 = 0x7654ffff. */
11275 typedef struct
11277 /* tree code of binary function G */
11278 enum tree_code code;
11280 /* The constant second argument of G */
11281 int arg;
11283 /* G^-1, the inverse of G (*, arg) */
11284 unsigned ginv;
11286 /* The cost of appplying G (*, arg) */
11287 int cost;
11289 /* The composition F o G^-1 (*, arg) for some function F */
11290 double_int map;
11292 /* For debug purpose only */
11293 const char *str;
11294 } avr_map_op_t;
11296 static const avr_map_op_t avr_map_op[] =
11298 { LROTATE_EXPR, 0, 0x76543210, 0, { 0, 0 }, "id" },
11299 { LROTATE_EXPR, 1, 0x07654321, 2, { 0, 0 }, "<<<" },
11300 { LROTATE_EXPR, 2, 0x10765432, 4, { 0, 0 }, "<<<" },
11301 { LROTATE_EXPR, 3, 0x21076543, 4, { 0, 0 }, "<<<" },
11302 { LROTATE_EXPR, 4, 0x32107654, 1, { 0, 0 }, "<<<" },
11303 { LROTATE_EXPR, 5, 0x43210765, 3, { 0, 0 }, "<<<" },
11304 { LROTATE_EXPR, 6, 0x54321076, 5, { 0, 0 }, "<<<" },
11305 { LROTATE_EXPR, 7, 0x65432107, 3, { 0, 0 }, "<<<" },
11306 { RSHIFT_EXPR, 1, 0x6543210c, 1, { 0, 0 }, ">>" },
11307 { RSHIFT_EXPR, 1, 0x7543210c, 1, { 0, 0 }, ">>" },
11308 { RSHIFT_EXPR, 2, 0x543210cc, 2, { 0, 0 }, ">>" },
11309 { RSHIFT_EXPR, 2, 0x643210cc, 2, { 0, 0 }, ">>" },
11310 { RSHIFT_EXPR, 2, 0x743210cc, 2, { 0, 0 }, ">>" },
11311 { LSHIFT_EXPR, 1, 0xc7654321, 1, { 0, 0 }, "<<" },
11312 { LSHIFT_EXPR, 2, 0xcc765432, 2, { 0, 0 }, "<<" }
11316 /* Try to decompose F as F = (F o G^-1) o G as described above.
11317 The result is a struct representing F o G^-1 and G.
11318 If result.cost < 0 then such a decomposition does not exist. */
11320 static avr_map_op_t
11321 avr_map_decompose (double_int f, const avr_map_op_t *g, bool val_const_p)
11323 int i;
11324 bool val_used_p = 0 != avr_map_metric (f, MAP_MASK_PREIMAGE_F);
11325 avr_map_op_t f_ginv = *g;
11326 double_int ginv = double_int::from_uhwi (g->ginv);
11328 f_ginv.cost = -1;
11330 /* Step 1: Computing F o G^-1 */
11332 for (i = 7; i >= 0; i--)
11334 int x = avr_map (f, i);
11336 if (x <= 7)
11338 x = avr_map (ginv, x);
11340 /* The bit is no element of the image of G: no avail (cost = -1) */
11342 if (x > 7)
11343 return f_ginv;
11346 f_ginv.map = avr_double_int_push_digit (f_ginv.map, 16, x);
11349 /* Step 2: Compute the cost of the operations.
11350 The overall cost of doing an operation prior to the insertion is
11351 the cost of the insertion plus the cost of the operation. */
11353 /* Step 2a: Compute cost of F o G^-1 */
11355 if (0 == avr_map_metric (f_ginv.map, MAP_NONFIXED_0_7))
11357 /* The mapping consists only of fixed points and can be folded
11358 to AND/OR logic in the remainder. Reasonable cost is 3. */
11360 f_ginv.cost = 2 + (val_used_p && !val_const_p);
11362 else
11364 rtx xop[4];
11366 /* Get the cost of the insn by calling the output worker with some
11367 fake values. Mimic effect of reloading xop[3]: Unused operands
11368 are mapped to 0 and used operands are reloaded to xop[0]. */
11370 xop[0] = all_regs_rtx[24];
11371 xop[1] = gen_int_mode (f_ginv.map.to_uhwi (), SImode);
11372 xop[2] = all_regs_rtx[25];
11373 xop[3] = val_used_p ? xop[0] : const0_rtx;
11375 avr_out_insert_bits (xop, &f_ginv.cost);
11377 f_ginv.cost += val_const_p && val_used_p ? 1 : 0;
11380 /* Step 2b: Add cost of G */
11382 f_ginv.cost += g->cost;
11384 if (avr_log.builtin)
11385 avr_edump (" %s%d=%d", g->str, g->arg, f_ginv.cost);
11387 return f_ginv;
11391 /* Insert bits from XOP[1] into XOP[0] according to MAP.
11392 XOP[0] and XOP[1] don't overlap.
11393 If FIXP_P = true: Move all bits according to MAP using BLD/BST sequences.
11394 If FIXP_P = false: Just move the bit if its position in the destination
11395 is different to its source position. */
11397 static void
11398 avr_move_bits (rtx *xop, double_int map, bool fixp_p, int *plen)
11400 int bit_dest, b;
11402 /* T-flag contains this bit of the source, i.e. of XOP[1] */
11403 int t_bit_src = -1;
11405 /* We order the operations according to the requested source bit b. */
11407 for (b = 0; b < 8; b++)
11408 for (bit_dest = 0; bit_dest < 8; bit_dest++)
11410 int bit_src = avr_map (map, bit_dest);
11412 if (b != bit_src
11413 || bit_src >= 8
11414 /* Same position: No need to copy as requested by FIXP_P. */
11415 || (bit_dest == bit_src && !fixp_p))
11416 continue;
11418 if (t_bit_src != bit_src)
11420 /* Source bit is not yet in T: Store it to T. */
11422 t_bit_src = bit_src;
11424 xop[3] = GEN_INT (bit_src);
11425 avr_asm_len ("bst %T1%T3", xop, plen, 1);
11428 /* Load destination bit with T. */
11430 xop[3] = GEN_INT (bit_dest);
11431 avr_asm_len ("bld %T0%T3", xop, plen, 1);
11436 /* PLEN == 0: Print assembler code for `insert_bits'.
11437 PLEN != 0: Compute code length in bytes.
11439 OP[0]: Result
11440 OP[1]: The mapping composed of nibbles. If nibble no. N is
11441 0: Bit N of result is copied from bit OP[2].0
11442 ... ...
11443 7: Bit N of result is copied from bit OP[2].7
11444 0xf: Bit N of result is copied from bit OP[3].N
11445 OP[2]: Bits to be inserted
11446 OP[3]: Target value */
11448 const char*
11449 avr_out_insert_bits (rtx *op, int *plen)
11451 double_int map = rtx_to_double_int (op[1]);
11452 unsigned mask_fixed;
11453 bool fixp_p = true;
11454 rtx xop[4];
11456 xop[0] = op[0];
11457 xop[1] = op[2];
11458 xop[2] = op[3];
11460 gcc_assert (REG_P (xop[2]) || CONST_INT_P (xop[2]));
11462 if (plen)
11463 *plen = 0;
11464 else if (flag_print_asm_name)
11465 fprintf (asm_out_file,
11466 ASM_COMMENT_START "map = 0x%08" HOST_LONG_FORMAT "x\n",
11467 map.to_uhwi () & GET_MODE_MASK (SImode));
11469 /* If MAP has fixed points it might be better to initialize the result
11470 with the bits to be inserted instead of moving all bits by hand. */
11472 mask_fixed = avr_map_metric (map, MAP_MASK_FIXED_0_7);
11474 if (REGNO (xop[0]) == REGNO (xop[1]))
11476 /* Avoid early-clobber conflicts */
11478 avr_asm_len ("mov __tmp_reg__,%1", xop, plen, 1);
11479 xop[1] = tmp_reg_rtx;
11480 fixp_p = false;
11483 if (avr_map_metric (map, MAP_MASK_PREIMAGE_F))
11485 /* XOP[2] is used and reloaded to XOP[0] already */
11487 int n_fix = 0, n_nofix = 0;
11489 gcc_assert (REG_P (xop[2]));
11491 /* Get the code size of the bit insertions; once with all bits
11492 moved and once with fixed points omitted. */
11494 avr_move_bits (xop, map, true, &n_fix);
11495 avr_move_bits (xop, map, false, &n_nofix);
11497 if (fixp_p && n_fix - n_nofix > 3)
11499 xop[3] = gen_int_mode (~mask_fixed, QImode);
11501 avr_asm_len ("eor %0,%1" CR_TAB
11502 "andi %0,%3" CR_TAB
11503 "eor %0,%1", xop, plen, 3);
11504 fixp_p = false;
11507 else
11509 /* XOP[2] is unused */
11511 if (fixp_p && mask_fixed)
11513 avr_asm_len ("mov %0,%1", xop, plen, 1);
11514 fixp_p = false;
11518 /* Move/insert remaining bits. */
11520 avr_move_bits (xop, map, fixp_p, plen);
11522 return "";
11526 /* IDs for all the AVR builtins. */
11528 enum avr_builtin_id
11530 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME) \
11531 AVR_BUILTIN_ ## NAME,
11532 #include "builtins.def"
11533 #undef DEF_BUILTIN
11535 AVR_BUILTIN_COUNT
11538 struct GTY(()) avr_builtin_description
11540 enum insn_code icode;
11541 int n_args;
11542 tree fndecl;
11546 /* Notice that avr_bdesc[] and avr_builtin_id are initialized in such a way
11547 that a built-in's ID can be used to access the built-in by means of
11548 avr_bdesc[ID] */
11550 static GTY(()) struct avr_builtin_description
11551 avr_bdesc[AVR_BUILTIN_COUNT] =
11553 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, LIBNAME) \
11554 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
11555 #include "builtins.def"
11556 #undef DEF_BUILTIN
11560 /* Implement `TARGET_BUILTIN_DECL'. */
11562 static tree
11563 avr_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED)
11565 if (id < AVR_BUILTIN_COUNT)
11566 return avr_bdesc[id].fndecl;
11568 return error_mark_node;
11572 static void
11573 avr_init_builtin_int24 (void)
11575 tree int24_type = make_signed_type (GET_MODE_BITSIZE (PSImode));
11576 tree uint24_type = make_unsigned_type (GET_MODE_BITSIZE (PSImode));
11578 lang_hooks.types.register_builtin_type (int24_type, "__int24");
11579 lang_hooks.types.register_builtin_type (uint24_type, "__uint24");
11583 /* Implement `TARGET_INIT_BUILTINS' */
11584 /* Set up all builtin functions for this target. */
11586 static void
11587 avr_init_builtins (void)
11589 tree void_ftype_void
11590 = build_function_type_list (void_type_node, NULL_TREE);
11591 tree uchar_ftype_uchar
11592 = build_function_type_list (unsigned_char_type_node,
11593 unsigned_char_type_node,
11594 NULL_TREE);
11595 tree uint_ftype_uchar_uchar
11596 = build_function_type_list (unsigned_type_node,
11597 unsigned_char_type_node,
11598 unsigned_char_type_node,
11599 NULL_TREE);
11600 tree int_ftype_char_char
11601 = build_function_type_list (integer_type_node,
11602 char_type_node,
11603 char_type_node,
11604 NULL_TREE);
11605 tree int_ftype_char_uchar
11606 = build_function_type_list (integer_type_node,
11607 char_type_node,
11608 unsigned_char_type_node,
11609 NULL_TREE);
11610 tree void_ftype_ulong
11611 = build_function_type_list (void_type_node,
11612 long_unsigned_type_node,
11613 NULL_TREE);
11615 tree uchar_ftype_ulong_uchar_uchar
11616 = build_function_type_list (unsigned_char_type_node,
11617 long_unsigned_type_node,
11618 unsigned_char_type_node,
11619 unsigned_char_type_node,
11620 NULL_TREE);
11622 tree const_memx_void_node
11623 = build_qualified_type (void_type_node,
11624 TYPE_QUAL_CONST
11625 | ENCODE_QUAL_ADDR_SPACE (ADDR_SPACE_MEMX));
11627 tree const_memx_ptr_type_node
11628 = build_pointer_type_for_mode (const_memx_void_node, PSImode, false);
11630 tree char_ftype_const_memx_ptr
11631 = build_function_type_list (char_type_node,
11632 const_memx_ptr_type_node,
11633 NULL);
11635 #define ITYP(T) \
11636 lang_hooks.types.type_for_size (TYPE_PRECISION (T), TYPE_UNSIGNED (T))
11638 #define FX_FTYPE_FX(fx) \
11639 tree fx##r_ftype_##fx##r \
11640 = build_function_type_list (node_##fx##r, node_##fx##r, NULL); \
11641 tree fx##k_ftype_##fx##k \
11642 = build_function_type_list (node_##fx##k, node_##fx##k, NULL)
11644 #define FX_FTYPE_FX_INT(fx) \
11645 tree fx##r_ftype_##fx##r_int \
11646 = build_function_type_list (node_##fx##r, node_##fx##r, \
11647 integer_type_node, NULL); \
11648 tree fx##k_ftype_##fx##k_int \
11649 = build_function_type_list (node_##fx##k, node_##fx##k, \
11650 integer_type_node, NULL)
11652 #define INT_FTYPE_FX(fx) \
11653 tree int_ftype_##fx##r \
11654 = build_function_type_list (integer_type_node, node_##fx##r, NULL); \
11655 tree int_ftype_##fx##k \
11656 = build_function_type_list (integer_type_node, node_##fx##k, NULL)
11658 #define INTX_FTYPE_FX(fx) \
11659 tree int##fx##r_ftype_##fx##r \
11660 = build_function_type_list (ITYP (node_##fx##r), node_##fx##r, NULL); \
11661 tree int##fx##k_ftype_##fx##k \
11662 = build_function_type_list (ITYP (node_##fx##k), node_##fx##k, NULL)
11664 #define FX_FTYPE_INTX(fx) \
11665 tree fx##r_ftype_int##fx##r \
11666 = build_function_type_list (node_##fx##r, ITYP (node_##fx##r), NULL); \
11667 tree fx##k_ftype_int##fx##k \
11668 = build_function_type_list (node_##fx##k, ITYP (node_##fx##k), NULL)
11670 tree node_hr = short_fract_type_node;
11671 tree node_nr = fract_type_node;
11672 tree node_lr = long_fract_type_node;
11673 tree node_llr = long_long_fract_type_node;
11675 tree node_uhr = unsigned_short_fract_type_node;
11676 tree node_unr = unsigned_fract_type_node;
11677 tree node_ulr = unsigned_long_fract_type_node;
11678 tree node_ullr = unsigned_long_long_fract_type_node;
11680 tree node_hk = short_accum_type_node;
11681 tree node_nk = accum_type_node;
11682 tree node_lk = long_accum_type_node;
11683 tree node_llk = long_long_accum_type_node;
11685 tree node_uhk = unsigned_short_accum_type_node;
11686 tree node_unk = unsigned_accum_type_node;
11687 tree node_ulk = unsigned_long_accum_type_node;
11688 tree node_ullk = unsigned_long_long_accum_type_node;
11691 /* For absfx builtins. */
11693 FX_FTYPE_FX (h);
11694 FX_FTYPE_FX (n);
11695 FX_FTYPE_FX (l);
11696 FX_FTYPE_FX (ll);
11698 /* For roundfx builtins. */
11700 FX_FTYPE_FX_INT (h);
11701 FX_FTYPE_FX_INT (n);
11702 FX_FTYPE_FX_INT (l);
11703 FX_FTYPE_FX_INT (ll);
11705 FX_FTYPE_FX_INT (uh);
11706 FX_FTYPE_FX_INT (un);
11707 FX_FTYPE_FX_INT (ul);
11708 FX_FTYPE_FX_INT (ull);
11710 /* For countlsfx builtins. */
11712 INT_FTYPE_FX (h);
11713 INT_FTYPE_FX (n);
11714 INT_FTYPE_FX (l);
11715 INT_FTYPE_FX (ll);
11717 INT_FTYPE_FX (uh);
11718 INT_FTYPE_FX (un);
11719 INT_FTYPE_FX (ul);
11720 INT_FTYPE_FX (ull);
11722 /* For bitsfx builtins. */
11724 INTX_FTYPE_FX (h);
11725 INTX_FTYPE_FX (n);
11726 INTX_FTYPE_FX (l);
11727 INTX_FTYPE_FX (ll);
11729 INTX_FTYPE_FX (uh);
11730 INTX_FTYPE_FX (un);
11731 INTX_FTYPE_FX (ul);
11732 INTX_FTYPE_FX (ull);
11734 /* For fxbits builtins. */
11736 FX_FTYPE_INTX (h);
11737 FX_FTYPE_INTX (n);
11738 FX_FTYPE_INTX (l);
11739 FX_FTYPE_INTX (ll);
11741 FX_FTYPE_INTX (uh);
11742 FX_FTYPE_INTX (un);
11743 FX_FTYPE_INTX (ul);
11744 FX_FTYPE_INTX (ull);
11747 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME) \
11749 int id = AVR_BUILTIN_ ## NAME; \
11750 const char *Name = "__builtin_avr_" #NAME; \
11751 char *name = (char*) alloca (1 + strlen (Name)); \
11753 gcc_assert (id < AVR_BUILTIN_COUNT); \
11754 avr_bdesc[id].fndecl \
11755 = add_builtin_function (avr_tolower (name, Name), TYPE, id, \
11756 BUILT_IN_MD, LIBNAME, NULL_TREE); \
11758 #include "builtins.def"
11759 #undef DEF_BUILTIN
11761 avr_init_builtin_int24 ();
11765 /* Subroutine of avr_expand_builtin to expand vanilla builtins
11766 with non-void result and 1 ... 3 arguments. */
11768 static rtx
11769 avr_default_expand_builtin (enum insn_code icode, tree exp, rtx target)
11771 rtx pat, xop[3];
11772 int n, n_args = call_expr_nargs (exp);
11773 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11775 gcc_assert (n_args >= 1 && n_args <= 3);
11777 if (target == NULL_RTX
11778 || GET_MODE (target) != tmode
11779 || !insn_data[icode].operand[0].predicate (target, tmode))
11781 target = gen_reg_rtx (tmode);
11784 for (n = 0; n < n_args; n++)
11786 tree arg = CALL_EXPR_ARG (exp, n);
11787 rtx op = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
11788 enum machine_mode opmode = GET_MODE (op);
11789 enum machine_mode mode = insn_data[icode].operand[n+1].mode;
11791 if ((opmode == SImode || opmode == VOIDmode) && mode == HImode)
11793 opmode = HImode;
11794 op = gen_lowpart (HImode, op);
11797 /* In case the insn wants input operands in modes different from
11798 the result, abort. */
11800 gcc_assert (opmode == mode || opmode == VOIDmode);
11802 if (!insn_data[icode].operand[n+1].predicate (op, mode))
11803 op = copy_to_mode_reg (mode, op);
11805 xop[n] = op;
11808 switch (n_args)
11810 case 1: pat = GEN_FCN (icode) (target, xop[0]); break;
11811 case 2: pat = GEN_FCN (icode) (target, xop[0], xop[1]); break;
11812 case 3: pat = GEN_FCN (icode) (target, xop[0], xop[1], xop[2]); break;
11814 default:
11815 gcc_unreachable();
11818 if (pat == NULL_RTX)
11819 return NULL_RTX;
11821 emit_insn (pat);
11823 return target;
11827 /* Implement `TARGET_EXPAND_BUILTIN'. */
11828 /* Expand an expression EXP that calls a built-in function,
11829 with result going to TARGET if that's convenient
11830 (and in mode MODE if that's convenient).
11831 SUBTARGET may be used as the target for computing one of EXP's operands.
11832 IGNORE is nonzero if the value is to be ignored. */
11834 static rtx
11835 avr_expand_builtin (tree exp, rtx target,
11836 rtx subtarget ATTRIBUTE_UNUSED,
11837 enum machine_mode mode ATTRIBUTE_UNUSED,
11838 int ignore)
11840 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11841 const char *bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
11842 unsigned int id = DECL_FUNCTION_CODE (fndecl);
11843 const struct avr_builtin_description *d = &avr_bdesc[id];
11844 tree arg0;
11845 rtx op0;
11847 gcc_assert (id < AVR_BUILTIN_COUNT);
11849 switch (id)
11851 case AVR_BUILTIN_NOP:
11852 emit_insn (gen_nopv (GEN_INT(1)));
11853 return 0;
11855 case AVR_BUILTIN_DELAY_CYCLES:
11857 arg0 = CALL_EXPR_ARG (exp, 0);
11858 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
11860 if (!CONST_INT_P (op0))
11861 error ("%s expects a compile time integer constant", bname);
11862 else
11863 avr_expand_delay_cycles (op0);
11865 return NULL_RTX;
11868 case AVR_BUILTIN_INSERT_BITS:
11870 arg0 = CALL_EXPR_ARG (exp, 0);
11871 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
11873 if (!CONST_INT_P (op0))
11875 error ("%s expects a compile time long integer constant"
11876 " as first argument", bname);
11877 return target;
11880 break;
11883 case AVR_BUILTIN_ROUNDHR: case AVR_BUILTIN_ROUNDUHR:
11884 case AVR_BUILTIN_ROUNDR: case AVR_BUILTIN_ROUNDUR:
11885 case AVR_BUILTIN_ROUNDLR: case AVR_BUILTIN_ROUNDULR:
11886 case AVR_BUILTIN_ROUNDLLR: case AVR_BUILTIN_ROUNDULLR:
11888 case AVR_BUILTIN_ROUNDHK: case AVR_BUILTIN_ROUNDUHK:
11889 case AVR_BUILTIN_ROUNDK: case AVR_BUILTIN_ROUNDUK:
11890 case AVR_BUILTIN_ROUNDLK: case AVR_BUILTIN_ROUNDULK:
11891 case AVR_BUILTIN_ROUNDLLK: case AVR_BUILTIN_ROUNDULLK:
11893 /* Warn about odd rounding. Rounding points >= FBIT will have
11894 no effect. */
11896 if (TREE_CODE (CALL_EXPR_ARG (exp, 1)) != INTEGER_CST)
11897 break;
11899 int rbit = (int) TREE_INT_CST_LOW (CALL_EXPR_ARG (exp, 1));
11901 if (rbit >= (int) GET_MODE_FBIT (mode))
11903 warning (OPT_Wextra, "rounding to %d bits has no effect for "
11904 "fixed-point value with %d fractional bits",
11905 rbit, GET_MODE_FBIT (mode));
11907 return expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX, mode,
11908 EXPAND_NORMAL);
11910 else if (rbit <= - (int) GET_MODE_IBIT (mode))
11912 warning (0, "rounding result will always be 0");
11913 return CONST0_RTX (mode);
11916 /* The rounding points RP satisfies now: -IBIT < RP < FBIT.
11918 TR 18037 only specifies results for RP > 0. However, the
11919 remaining cases of -IBIT < RP <= 0 can easily be supported
11920 without any additional overhead. */
11922 break; /* round */
11925 /* No fold found and no insn: Call support function from libgcc. */
11927 if (d->icode == CODE_FOR_nothing
11928 && DECL_ASSEMBLER_NAME (get_callee_fndecl (exp)) != NULL_TREE)
11930 return expand_call (exp, target, ignore);
11933 /* No special treatment needed: vanilla expand. */
11935 gcc_assert (d->icode != CODE_FOR_nothing);
11936 gcc_assert (d->n_args == call_expr_nargs (exp));
11938 if (d->n_args == 0)
11940 emit_insn ((GEN_FCN (d->icode)) (target));
11941 return NULL_RTX;
11944 return avr_default_expand_builtin (d->icode, exp, target);
11948 /* Helper for `avr_fold_builtin' that folds absfx (FIXED_CST). */
11950 static tree
11951 avr_fold_absfx (tree tval)
11953 if (FIXED_CST != TREE_CODE (tval))
11954 return NULL_TREE;
11956 /* Our fixed-points have no padding: Use double_int payload directly. */
11958 FIXED_VALUE_TYPE fval = TREE_FIXED_CST (tval);
11959 unsigned int bits = GET_MODE_BITSIZE (fval.mode);
11960 double_int ival = fval.data.sext (bits);
11962 if (!ival.is_negative())
11963 return tval;
11965 /* ISO/IEC TR 18037, 7.18a.6.2: The absfx functions are saturating. */
11967 fval.data = (ival == double_int::min_value (bits, false).sext (bits))
11968 ? double_int::max_value (bits, false)
11969 : -ival;
11971 return build_fixed (TREE_TYPE (tval), fval);
11975 /* Implement `TARGET_FOLD_BUILTIN'. */
11977 static tree
11978 avr_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg,
11979 bool ignore ATTRIBUTE_UNUSED)
11981 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11982 tree val_type = TREE_TYPE (TREE_TYPE (fndecl));
11984 if (!optimize)
11985 return NULL_TREE;
11987 switch (fcode)
11989 default:
11990 break;
11992 case AVR_BUILTIN_SWAP:
11994 return fold_build2 (LROTATE_EXPR, val_type, arg[0],
11995 build_int_cst (val_type, 4));
11998 case AVR_BUILTIN_ABSHR:
11999 case AVR_BUILTIN_ABSR:
12000 case AVR_BUILTIN_ABSLR:
12001 case AVR_BUILTIN_ABSLLR:
12003 case AVR_BUILTIN_ABSHK:
12004 case AVR_BUILTIN_ABSK:
12005 case AVR_BUILTIN_ABSLK:
12006 case AVR_BUILTIN_ABSLLK:
12007 /* GCC is not good with folding ABS for fixed-point. Do it by hand. */
12009 return avr_fold_absfx (arg[0]);
12011 case AVR_BUILTIN_BITSHR: case AVR_BUILTIN_HRBITS:
12012 case AVR_BUILTIN_BITSHK: case AVR_BUILTIN_HKBITS:
12013 case AVR_BUILTIN_BITSUHR: case AVR_BUILTIN_UHRBITS:
12014 case AVR_BUILTIN_BITSUHK: case AVR_BUILTIN_UHKBITS:
12016 case AVR_BUILTIN_BITSR: case AVR_BUILTIN_RBITS:
12017 case AVR_BUILTIN_BITSK: case AVR_BUILTIN_KBITS:
12018 case AVR_BUILTIN_BITSUR: case AVR_BUILTIN_URBITS:
12019 case AVR_BUILTIN_BITSUK: case AVR_BUILTIN_UKBITS:
12021 case AVR_BUILTIN_BITSLR: case AVR_BUILTIN_LRBITS:
12022 case AVR_BUILTIN_BITSLK: case AVR_BUILTIN_LKBITS:
12023 case AVR_BUILTIN_BITSULR: case AVR_BUILTIN_ULRBITS:
12024 case AVR_BUILTIN_BITSULK: case AVR_BUILTIN_ULKBITS:
12026 case AVR_BUILTIN_BITSLLR: case AVR_BUILTIN_LLRBITS:
12027 case AVR_BUILTIN_BITSLLK: case AVR_BUILTIN_LLKBITS:
12028 case AVR_BUILTIN_BITSULLR: case AVR_BUILTIN_ULLRBITS:
12029 case AVR_BUILTIN_BITSULLK: case AVR_BUILTIN_ULLKBITS:
12031 gcc_assert (TYPE_PRECISION (val_type)
12032 == TYPE_PRECISION (TREE_TYPE (arg[0])));
12034 return build1 (VIEW_CONVERT_EXPR, val_type, arg[0]);
12036 case AVR_BUILTIN_INSERT_BITS:
12038 tree tbits = arg[1];
12039 tree tval = arg[2];
12040 tree tmap;
12041 tree map_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
12042 double_int map;
12043 bool changed = false;
12044 unsigned i;
12045 avr_map_op_t best_g;
12047 if (TREE_CODE (arg[0]) != INTEGER_CST)
12049 /* No constant as first argument: Don't fold this and run into
12050 error in avr_expand_builtin. */
12052 break;
12055 map = tree_to_double_int (arg[0]);
12056 tmap = double_int_to_tree (map_type, map);
12058 if (TREE_CODE (tval) != INTEGER_CST
12059 && 0 == avr_map_metric (map, MAP_MASK_PREIMAGE_F))
12061 /* There are no F in the map, i.e. 3rd operand is unused.
12062 Replace that argument with some constant to render
12063 respective input unused. */
12065 tval = build_int_cst (val_type, 0);
12066 changed = true;
12069 if (TREE_CODE (tbits) != INTEGER_CST
12070 && 0 == avr_map_metric (map, MAP_PREIMAGE_0_7))
12072 /* Similar for the bits to be inserted. If they are unused,
12073 we can just as well pass 0. */
12075 tbits = build_int_cst (val_type, 0);
12078 if (TREE_CODE (tbits) == INTEGER_CST)
12080 /* Inserting bits known at compile time is easy and can be
12081 performed by AND and OR with appropriate masks. */
12083 int bits = TREE_INT_CST_LOW (tbits);
12084 int mask_ior = 0, mask_and = 0xff;
12086 for (i = 0; i < 8; i++)
12088 int mi = avr_map (map, i);
12090 if (mi < 8)
12092 if (bits & (1 << mi)) mask_ior |= (1 << i);
12093 else mask_and &= ~(1 << i);
12097 tval = fold_build2 (BIT_IOR_EXPR, val_type, tval,
12098 build_int_cst (val_type, mask_ior));
12099 return fold_build2 (BIT_AND_EXPR, val_type, tval,
12100 build_int_cst (val_type, mask_and));
12103 if (changed)
12104 return build_call_expr (fndecl, 3, tmap, tbits, tval);
12106 /* If bits don't change their position we can use vanilla logic
12107 to merge the two arguments. */
12109 if (0 == avr_map_metric (map, MAP_NONFIXED_0_7))
12111 int mask_f = avr_map_metric (map, MAP_MASK_PREIMAGE_F);
12112 tree tres, tmask = build_int_cst (val_type, mask_f ^ 0xff);
12114 tres = fold_build2 (BIT_XOR_EXPR, val_type, tbits, tval);
12115 tres = fold_build2 (BIT_AND_EXPR, val_type, tres, tmask);
12116 return fold_build2 (BIT_XOR_EXPR, val_type, tres, tval);
12119 /* Try to decomposing map to reduce overall cost. */
12121 if (avr_log.builtin)
12122 avr_edump ("\n%?: %X\n%?: ROL cost: ", map);
12124 best_g = avr_map_op[0];
12125 best_g.cost = 1000;
12127 for (i = 0; i < sizeof (avr_map_op) / sizeof (*avr_map_op); i++)
12129 avr_map_op_t g
12130 = avr_map_decompose (map, avr_map_op + i,
12131 TREE_CODE (tval) == INTEGER_CST);
12133 if (g.cost >= 0 && g.cost < best_g.cost)
12134 best_g = g;
12137 if (avr_log.builtin)
12138 avr_edump ("\n");
12140 if (best_g.arg == 0)
12141 /* No optimization found */
12142 break;
12144 /* Apply operation G to the 2nd argument. */
12146 if (avr_log.builtin)
12147 avr_edump ("%?: using OP(%s%d, %X) cost %d\n",
12148 best_g.str, best_g.arg, best_g.map, best_g.cost);
12150 /* Do right-shifts arithmetically: They copy the MSB instead of
12151 shifting in a non-usable value (0) as with logic right-shift. */
12153 tbits = fold_convert (signed_char_type_node, tbits);
12154 tbits = fold_build2 (best_g.code, signed_char_type_node, tbits,
12155 build_int_cst (val_type, best_g.arg));
12156 tbits = fold_convert (val_type, tbits);
12158 /* Use map o G^-1 instead of original map to undo the effect of G. */
12160 tmap = double_int_to_tree (map_type, best_g.map);
12162 return build_call_expr (fndecl, 3, tmap, tbits, tval);
12163 } /* AVR_BUILTIN_INSERT_BITS */
12166 return NULL_TREE;
12171 /* Initialize the GCC target structure. */
12173 #undef TARGET_ASM_ALIGNED_HI_OP
12174 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
12175 #undef TARGET_ASM_ALIGNED_SI_OP
12176 #define TARGET_ASM_ALIGNED_SI_OP "\t.long\t"
12177 #undef TARGET_ASM_UNALIGNED_HI_OP
12178 #define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
12179 #undef TARGET_ASM_UNALIGNED_SI_OP
12180 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
12181 #undef TARGET_ASM_INTEGER
12182 #define TARGET_ASM_INTEGER avr_assemble_integer
12183 #undef TARGET_ASM_FILE_START
12184 #define TARGET_ASM_FILE_START avr_file_start
12185 #undef TARGET_ASM_FILE_END
12186 #define TARGET_ASM_FILE_END avr_file_end
12188 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
12189 #define TARGET_ASM_FUNCTION_END_PROLOGUE avr_asm_function_end_prologue
12190 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
12191 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE avr_asm_function_begin_epilogue
12193 #undef TARGET_FUNCTION_VALUE
12194 #define TARGET_FUNCTION_VALUE avr_function_value
12195 #undef TARGET_LIBCALL_VALUE
12196 #define TARGET_LIBCALL_VALUE avr_libcall_value
12197 #undef TARGET_FUNCTION_VALUE_REGNO_P
12198 #define TARGET_FUNCTION_VALUE_REGNO_P avr_function_value_regno_p
12200 #undef TARGET_ATTRIBUTE_TABLE
12201 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
12202 #undef TARGET_INSERT_ATTRIBUTES
12203 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
12204 #undef TARGET_SECTION_TYPE_FLAGS
12205 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
12207 #undef TARGET_ASM_NAMED_SECTION
12208 #define TARGET_ASM_NAMED_SECTION avr_asm_named_section
12209 #undef TARGET_ASM_INIT_SECTIONS
12210 #define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections
12211 #undef TARGET_ENCODE_SECTION_INFO
12212 #define TARGET_ENCODE_SECTION_INFO avr_encode_section_info
12213 #undef TARGET_ASM_SELECT_SECTION
12214 #define TARGET_ASM_SELECT_SECTION avr_asm_select_section
12216 #undef TARGET_REGISTER_MOVE_COST
12217 #define TARGET_REGISTER_MOVE_COST avr_register_move_cost
12218 #undef TARGET_MEMORY_MOVE_COST
12219 #define TARGET_MEMORY_MOVE_COST avr_memory_move_cost
12220 #undef TARGET_RTX_COSTS
12221 #define TARGET_RTX_COSTS avr_rtx_costs
12222 #undef TARGET_ADDRESS_COST
12223 #define TARGET_ADDRESS_COST avr_address_cost
12224 #undef TARGET_MACHINE_DEPENDENT_REORG
12225 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
12226 #undef TARGET_FUNCTION_ARG
12227 #define TARGET_FUNCTION_ARG avr_function_arg
12228 #undef TARGET_FUNCTION_ARG_ADVANCE
12229 #define TARGET_FUNCTION_ARG_ADVANCE avr_function_arg_advance
12231 #undef TARGET_SET_CURRENT_FUNCTION
12232 #define TARGET_SET_CURRENT_FUNCTION avr_set_current_function
12234 #undef TARGET_RETURN_IN_MEMORY
12235 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
12237 #undef TARGET_STRICT_ARGUMENT_NAMING
12238 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
12240 #undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
12241 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE avr_builtin_setjmp_frame_value
12243 #undef TARGET_HARD_REGNO_SCRATCH_OK
12244 #define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok
12245 #undef TARGET_CASE_VALUES_THRESHOLD
12246 #define TARGET_CASE_VALUES_THRESHOLD avr_case_values_threshold
12248 #undef TARGET_FRAME_POINTER_REQUIRED
12249 #define TARGET_FRAME_POINTER_REQUIRED avr_frame_pointer_required_p
12250 #undef TARGET_CAN_ELIMINATE
12251 #define TARGET_CAN_ELIMINATE avr_can_eliminate
12253 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
12254 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS avr_allocate_stack_slots_for_args
12256 #undef TARGET_WARN_FUNC_RETURN
12257 #define TARGET_WARN_FUNC_RETURN avr_warn_func_return
12259 #undef TARGET_CLASS_LIKELY_SPILLED_P
12260 #define TARGET_CLASS_LIKELY_SPILLED_P avr_class_likely_spilled_p
12262 #undef TARGET_OPTION_OVERRIDE
12263 #define TARGET_OPTION_OVERRIDE avr_option_override
12265 #undef TARGET_CANNOT_MODIFY_JUMPS_P
12266 #define TARGET_CANNOT_MODIFY_JUMPS_P avr_cannot_modify_jumps_p
12268 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
12269 #define TARGET_FUNCTION_OK_FOR_SIBCALL avr_function_ok_for_sibcall
12271 #undef TARGET_INIT_BUILTINS
12272 #define TARGET_INIT_BUILTINS avr_init_builtins
12274 #undef TARGET_BUILTIN_DECL
12275 #define TARGET_BUILTIN_DECL avr_builtin_decl
12277 #undef TARGET_EXPAND_BUILTIN
12278 #define TARGET_EXPAND_BUILTIN avr_expand_builtin
12280 #undef TARGET_FOLD_BUILTIN
12281 #define TARGET_FOLD_BUILTIN avr_fold_builtin
12283 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
12284 #define TARGET_ASM_FUNCTION_RODATA_SECTION avr_asm_function_rodata_section
12286 #undef TARGET_SCALAR_MODE_SUPPORTED_P
12287 #define TARGET_SCALAR_MODE_SUPPORTED_P avr_scalar_mode_supported_p
12289 #undef TARGET_BUILD_BUILTIN_VA_LIST
12290 #define TARGET_BUILD_BUILTIN_VA_LIST avr_build_builtin_va_list
12292 #undef TARGET_FIXED_POINT_SUPPORTED_P
12293 #define TARGET_FIXED_POINT_SUPPORTED_P hook_bool_void_true
12295 #undef TARGET_CONVERT_TO_TYPE
12296 #define TARGET_CONVERT_TO_TYPE avr_convert_to_type
12298 #undef TARGET_ADDR_SPACE_SUBSET_P
12299 #define TARGET_ADDR_SPACE_SUBSET_P avr_addr_space_subset_p
12301 #undef TARGET_ADDR_SPACE_CONVERT
12302 #define TARGET_ADDR_SPACE_CONVERT avr_addr_space_convert
12304 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
12305 #define TARGET_ADDR_SPACE_ADDRESS_MODE avr_addr_space_address_mode
12307 #undef TARGET_ADDR_SPACE_POINTER_MODE
12308 #define TARGET_ADDR_SPACE_POINTER_MODE avr_addr_space_pointer_mode
12310 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
12311 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
12312 avr_addr_space_legitimate_address_p
12314 #undef TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS
12315 #define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS avr_addr_space_legitimize_address
12317 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
12318 #define TARGET_MODE_DEPENDENT_ADDRESS_P avr_mode_dependent_address_p
12320 #undef TARGET_SECONDARY_RELOAD
12321 #define TARGET_SECONDARY_RELOAD avr_secondary_reload
12323 #undef TARGET_PRINT_OPERAND
12324 #define TARGET_PRINT_OPERAND avr_print_operand
12325 #undef TARGET_PRINT_OPERAND_ADDRESS
12326 #define TARGET_PRINT_OPERAND_ADDRESS avr_print_operand_address
12327 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
12328 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P avr_print_operand_punct_valid_p
12330 struct gcc_target targetm = TARGET_INITIALIZER;
12333 #include "gt-avr.h"