* config/avr/avr.c (avr_out_xload): No SBIS around LPM so that
[official-gcc.git] / gcc / config / avr / avr.c
blob14a3eee7c726eab64363e8e3b816f9d757604cea
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 /* Remove the leading '*' added in set_user_assembler_name. */
591 ? 1 + IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))
592 : IDENTIFIER_POINTER (DECL_NAME (decl));
594 /* Silently ignore 'signal' if 'interrupt' is present. AVR-LibC startet
595 using this when it switched from SIGNAL and INTERRUPT to ISR. */
597 if (cfun->machine->is_interrupt)
598 cfun->machine->is_signal = 0;
600 /* Interrupt handlers must be void __vector (void) functions. */
602 if (args && TREE_CODE (TREE_VALUE (args)) != VOID_TYPE)
603 error_at (loc, "%qs function cannot have arguments", isr);
605 if (TREE_CODE (ret) != VOID_TYPE)
606 error_at (loc, "%qs function cannot return a value", isr);
608 /* If the function has the 'signal' or 'interrupt' attribute, ensure
609 that the name of the function is "__vector_NN" so as to catch
610 when the user misspells the vector name. */
612 if (!STR_PREFIX_P (name, "__vector"))
613 warning_at (loc, 0, "%qs appears to be a misspelled %s handler",
614 name, isr);
617 /* Don't print the above diagnostics more than once. */
619 cfun->machine->attributes_checked_p = 1;
623 /* Implement `ACCUMULATE_OUTGOING_ARGS'. */
626 avr_accumulate_outgoing_args (void)
628 if (!cfun)
629 return TARGET_ACCUMULATE_OUTGOING_ARGS;
631 /* FIXME: For setjmp and in avr_builtin_setjmp_frame_value we don't know
632 what offset is correct. In some cases it is relative to
633 virtual_outgoing_args_rtx and in others it is relative to
634 virtual_stack_vars_rtx. For example code see
635 gcc.c-torture/execute/built-in-setjmp.c
636 gcc.c-torture/execute/builtins/sprintf-chk.c */
638 return (TARGET_ACCUMULATE_OUTGOING_ARGS
639 && !(cfun->calls_setjmp
640 || cfun->has_nonlocal_label));
644 /* Report contribution of accumulated outgoing arguments to stack size. */
646 static inline int
647 avr_outgoing_args_size (void)
649 return ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0;
653 /* Implement `STARTING_FRAME_OFFSET'. */
654 /* This is the offset from the frame pointer register to the first stack slot
655 that contains a variable living in the frame. */
658 avr_starting_frame_offset (void)
660 return 1 + avr_outgoing_args_size ();
664 /* Return the number of hard registers to push/pop in the prologue/epilogue
665 of the current function, and optionally store these registers in SET. */
667 static int
668 avr_regs_to_save (HARD_REG_SET *set)
670 int reg, count;
671 int int_or_sig_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
673 if (set)
674 CLEAR_HARD_REG_SET (*set);
675 count = 0;
677 /* No need to save any registers if the function never returns or
678 has the "OS_task" or "OS_main" attribute. */
680 if (TREE_THIS_VOLATILE (current_function_decl)
681 || cfun->machine->is_OS_task
682 || cfun->machine->is_OS_main)
683 return 0;
685 for (reg = 0; reg < 32; reg++)
687 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
688 any global register variables. */
690 if (fixed_regs[reg])
691 continue;
693 if ((int_or_sig_p && !crtl->is_leaf && call_used_regs[reg])
694 || (df_regs_ever_live_p (reg)
695 && (int_or_sig_p || !call_used_regs[reg])
696 /* Don't record frame pointer registers here. They are treated
697 indivitually in prologue. */
698 && !(frame_pointer_needed
699 && (reg == REG_Y || reg == (REG_Y+1)))))
701 if (set)
702 SET_HARD_REG_BIT (*set, reg);
703 count++;
706 return count;
710 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
712 static bool
713 avr_allocate_stack_slots_for_args (void)
715 return !cfun->machine->is_naked;
719 /* Return true if register FROM can be eliminated via register TO. */
721 static bool
722 avr_can_eliminate (const int from, const int to)
724 return ((from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
725 || (frame_pointer_needed && to == FRAME_POINTER_REGNUM)
726 || ((from == FRAME_POINTER_REGNUM
727 || from == FRAME_POINTER_REGNUM + 1)
728 && !frame_pointer_needed));
732 /* Implement `TARGET_WARN_FUNC_RETURN'. */
734 static bool
735 avr_warn_func_return (tree decl)
737 /* Naked functions are implemented entirely in assembly, including the
738 return sequence, so suppress warnings about this. */
740 return !avr_naked_function_p (decl);
743 /* Compute offset between arg_pointer and frame_pointer. */
746 avr_initial_elimination_offset (int from, int to)
748 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
749 return 0;
750 else
752 int offset = frame_pointer_needed ? 2 : 0;
753 int avr_pc_size = AVR_HAVE_EIJMP_EICALL ? 3 : 2;
755 offset += avr_regs_to_save (NULL);
756 return (get_frame_size () + avr_outgoing_args_size()
757 + avr_pc_size + 1 + offset);
762 /* Helper for the function below. */
764 static void
765 avr_adjust_type_node (tree *node, enum machine_mode mode, int sat_p)
767 *node = make_node (FIXED_POINT_TYPE);
768 TYPE_SATURATING (*node) = sat_p;
769 TYPE_UNSIGNED (*node) = UNSIGNED_FIXED_POINT_MODE_P (mode);
770 TYPE_IBIT (*node) = GET_MODE_IBIT (mode);
771 TYPE_FBIT (*node) = GET_MODE_FBIT (mode);
772 TYPE_PRECISION (*node) = GET_MODE_BITSIZE (mode);
773 TYPE_ALIGN (*node) = 8;
774 SET_TYPE_MODE (*node, mode);
776 layout_type (*node);
780 /* Implement `TARGET_BUILD_BUILTIN_VA_LIST'. */
782 static tree
783 avr_build_builtin_va_list (void)
785 /* avr-modes.def adjusts [U]TA to be 64-bit modes with 48 fractional bits.
786 This is more appropriate for the 8-bit machine AVR than 128-bit modes.
787 The ADJUST_IBIT/FBIT are handled in toplev:init_adjust_machine_modes()
788 which is auto-generated by genmodes, but the compiler assigns [U]DAmode
789 to the long long accum modes instead of the desired [U]TAmode.
791 Fix this now, right after node setup in tree.c:build_common_tree_nodes().
792 This must run before c-cppbuiltin.c:builtin_define_fixed_point_constants()
793 which built-in defines macros like __ULLACCUM_FBIT__ that are used by
794 libgcc to detect IBIT and FBIT. */
796 avr_adjust_type_node (&ta_type_node, TAmode, 0);
797 avr_adjust_type_node (&uta_type_node, UTAmode, 0);
798 avr_adjust_type_node (&sat_ta_type_node, TAmode, 1);
799 avr_adjust_type_node (&sat_uta_type_node, UTAmode, 1);
801 unsigned_long_long_accum_type_node = uta_type_node;
802 long_long_accum_type_node = ta_type_node;
803 sat_unsigned_long_long_accum_type_node = sat_uta_type_node;
804 sat_long_long_accum_type_node = sat_ta_type_node;
806 /* Dispatch to the default handler. */
808 return std_build_builtin_va_list ();
812 /* Implement `TARGET_BUILTIN_SETJMP_FRAME_VALUE'. */
813 /* Actual start of frame is virtual_stack_vars_rtx this is offset from
814 frame pointer by +STARTING_FRAME_OFFSET.
815 Using saved frame = virtual_stack_vars_rtx - STARTING_FRAME_OFFSET
816 avoids creating add/sub of offset in nonlocal goto and setjmp. */
818 static rtx
819 avr_builtin_setjmp_frame_value (void)
821 rtx xval = gen_reg_rtx (Pmode);
822 emit_insn (gen_subhi3 (xval, virtual_stack_vars_rtx,
823 gen_int_mode (STARTING_FRAME_OFFSET, Pmode)));
824 return xval;
828 /* Return contents of MEM at frame pointer + stack size + 1 (+2 if 3-byte PC).
829 This is return address of function. */
832 avr_return_addr_rtx (int count, rtx tem)
834 rtx r;
836 /* Can only return this function's return address. Others not supported. */
837 if (count)
838 return NULL;
840 if (AVR_3_BYTE_PC)
842 r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+2");
843 warning (0, "%<builtin_return_address%> contains only 2 bytes"
844 " of address");
846 else
847 r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+1");
849 r = gen_rtx_PLUS (Pmode, tem, r);
850 r = gen_frame_mem (Pmode, memory_address (Pmode, r));
851 r = gen_rtx_ROTATE (HImode, r, GEN_INT (8));
852 return r;
855 /* Return 1 if the function epilogue is just a single "ret". */
858 avr_simple_epilogue (void)
860 return (! frame_pointer_needed
861 && get_frame_size () == 0
862 && avr_outgoing_args_size() == 0
863 && avr_regs_to_save (NULL) == 0
864 && ! cfun->machine->is_interrupt
865 && ! cfun->machine->is_signal
866 && ! cfun->machine->is_naked
867 && ! TREE_THIS_VOLATILE (current_function_decl));
870 /* This function checks sequence of live registers. */
872 static int
873 sequent_regs_live (void)
875 int reg;
876 int live_seq = 0;
877 int cur_seq = 0;
879 for (reg = 0; reg < 18; ++reg)
881 if (fixed_regs[reg])
883 /* Don't recognize sequences that contain global register
884 variables. */
886 if (live_seq != 0)
887 return 0;
888 else
889 continue;
892 if (!call_used_regs[reg])
894 if (df_regs_ever_live_p (reg))
896 ++live_seq;
897 ++cur_seq;
899 else
900 cur_seq = 0;
904 if (!frame_pointer_needed)
906 if (df_regs_ever_live_p (REG_Y))
908 ++live_seq;
909 ++cur_seq;
911 else
912 cur_seq = 0;
914 if (df_regs_ever_live_p (REG_Y+1))
916 ++live_seq;
917 ++cur_seq;
919 else
920 cur_seq = 0;
922 else
924 cur_seq += 2;
925 live_seq += 2;
927 return (cur_seq == live_seq) ? live_seq : 0;
930 /* Obtain the length sequence of insns. */
933 get_sequence_length (rtx insns)
935 rtx insn;
936 int length;
938 for (insn = insns, length = 0; insn; insn = NEXT_INSN (insn))
939 length += get_attr_length (insn);
941 return length;
945 /* Implement `INCOMING_RETURN_ADDR_RTX'. */
948 avr_incoming_return_addr_rtx (void)
950 /* The return address is at the top of the stack. Note that the push
951 was via post-decrement, which means the actual address is off by one. */
952 return gen_frame_mem (HImode, plus_constant (Pmode, stack_pointer_rtx, 1));
955 /* Helper for expand_prologue. Emit a push of a byte register. */
957 static void
958 emit_push_byte (unsigned regno, bool frame_related_p)
960 rtx mem, reg, insn;
962 mem = gen_rtx_POST_DEC (HImode, stack_pointer_rtx);
963 mem = gen_frame_mem (QImode, mem);
964 reg = gen_rtx_REG (QImode, regno);
966 insn = emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
967 if (frame_related_p)
968 RTX_FRAME_RELATED_P (insn) = 1;
970 cfun->machine->stack_usage++;
974 /* Helper for expand_prologue. Emit a push of a SFR via tmp_reg.
975 SFR is a MEM representing the memory location of the SFR.
976 If CLR_P then clear the SFR after the push using zero_reg. */
978 static void
979 emit_push_sfr (rtx sfr, bool frame_related_p, bool clr_p)
981 rtx insn;
983 gcc_assert (MEM_P (sfr));
985 /* IN __tmp_reg__, IO(SFR) */
986 insn = emit_move_insn (tmp_reg_rtx, sfr);
987 if (frame_related_p)
988 RTX_FRAME_RELATED_P (insn) = 1;
990 /* PUSH __tmp_reg__ */
991 emit_push_byte (TMP_REGNO, frame_related_p);
993 if (clr_p)
995 /* OUT IO(SFR), __zero_reg__ */
996 insn = emit_move_insn (sfr, const0_rtx);
997 if (frame_related_p)
998 RTX_FRAME_RELATED_P (insn) = 1;
1002 static void
1003 avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set)
1005 rtx insn;
1006 bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
1007 int live_seq = sequent_regs_live ();
1009 HOST_WIDE_INT size_max
1010 = (HOST_WIDE_INT) GET_MODE_MASK (AVR_HAVE_8BIT_SP ? QImode : Pmode);
1012 bool minimize = (TARGET_CALL_PROLOGUES
1013 && size < size_max
1014 && live_seq
1015 && !isr_p
1016 && !cfun->machine->is_OS_task
1017 && !cfun->machine->is_OS_main);
1019 if (minimize
1020 && (frame_pointer_needed
1021 || avr_outgoing_args_size() > 8
1022 || (AVR_2_BYTE_PC && live_seq > 6)
1023 || live_seq > 7))
1025 rtx pattern;
1026 int first_reg, reg, offset;
1028 emit_move_insn (gen_rtx_REG (HImode, REG_X),
1029 gen_int_mode (size, HImode));
1031 pattern = gen_call_prologue_saves (gen_int_mode (live_seq, HImode),
1032 gen_int_mode (live_seq+size, HImode));
1033 insn = emit_insn (pattern);
1034 RTX_FRAME_RELATED_P (insn) = 1;
1036 /* Describe the effect of the unspec_volatile call to prologue_saves.
1037 Note that this formulation assumes that add_reg_note pushes the
1038 notes to the front. Thus we build them in the reverse order of
1039 how we want dwarf2out to process them. */
1041 /* The function does always set frame_pointer_rtx, but whether that
1042 is going to be permanent in the function is frame_pointer_needed. */
1044 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1045 gen_rtx_SET (VOIDmode, (frame_pointer_needed
1046 ? frame_pointer_rtx
1047 : stack_pointer_rtx),
1048 plus_constant (Pmode, stack_pointer_rtx,
1049 -(size + live_seq))));
1051 /* Note that live_seq always contains r28+r29, but the other
1052 registers to be saved are all below 18. */
1054 first_reg = 18 - (live_seq - 2);
1056 for (reg = 29, offset = -live_seq + 1;
1057 reg >= first_reg;
1058 reg = (reg == 28 ? 17 : reg - 1), ++offset)
1060 rtx m, r;
1062 m = gen_rtx_MEM (QImode, plus_constant (Pmode, stack_pointer_rtx,
1063 offset));
1064 r = gen_rtx_REG (QImode, reg);
1065 add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (VOIDmode, m, r));
1068 cfun->machine->stack_usage += size + live_seq;
1070 else /* !minimize */
1072 int reg;
1074 for (reg = 0; reg < 32; ++reg)
1075 if (TEST_HARD_REG_BIT (set, reg))
1076 emit_push_byte (reg, true);
1078 if (frame_pointer_needed
1079 && (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main)))
1081 /* Push frame pointer. Always be consistent about the
1082 ordering of pushes -- epilogue_restores expects the
1083 register pair to be pushed low byte first. */
1085 emit_push_byte (REG_Y, true);
1086 emit_push_byte (REG_Y + 1, true);
1089 if (frame_pointer_needed
1090 && size == 0)
1092 insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1093 RTX_FRAME_RELATED_P (insn) = 1;
1096 if (size != 0)
1098 /* Creating a frame can be done by direct manipulation of the
1099 stack or via the frame pointer. These two methods are:
1100 fp = sp
1101 fp -= size
1102 sp = fp
1104 sp -= size
1105 fp = sp (*)
1106 the optimum method depends on function type, stack and
1107 frame size. To avoid a complex logic, both methods are
1108 tested and shortest is selected.
1110 There is also the case where SIZE != 0 and no frame pointer is
1111 needed; this can occur if ACCUMULATE_OUTGOING_ARGS is on.
1112 In that case, insn (*) is not needed in that case.
1113 We use the X register as scratch. This is save because in X
1114 is call-clobbered.
1115 In an interrupt routine, the case of SIZE != 0 together with
1116 !frame_pointer_needed can only occur if the function is not a
1117 leaf function and thus X has already been saved. */
1119 int irq_state = -1;
1120 HOST_WIDE_INT size_cfa = size, neg_size;
1121 rtx fp_plus_insns, fp, my_fp;
1123 gcc_assert (frame_pointer_needed
1124 || !isr_p
1125 || !crtl->is_leaf);
1127 fp = my_fp = (frame_pointer_needed
1128 ? frame_pointer_rtx
1129 : gen_rtx_REG (Pmode, REG_X));
1131 if (AVR_HAVE_8BIT_SP)
1133 /* The high byte (r29) does not change:
1134 Prefer SUBI (1 cycle) over SBIW (2 cycles, same size). */
1136 my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
1139 /* Cut down size and avoid size = 0 so that we don't run
1140 into ICE like PR52488 in the remainder. */
1142 if (size > size_max)
1144 /* Don't error so that insane code from newlib still compiles
1145 and does not break building newlib. As PR51345 is implemented
1146 now, there are multilib variants with -msp8.
1148 If user wants sanity checks he can use -Wstack-usage=
1149 or similar options.
1151 For CFA we emit the original, non-saturated size so that
1152 the generic machinery is aware of the real stack usage and
1153 will print the above diagnostic as expected. */
1155 size = size_max;
1158 size = trunc_int_for_mode (size, GET_MODE (my_fp));
1159 neg_size = trunc_int_for_mode (-size, GET_MODE (my_fp));
1161 /************ Method 1: Adjust frame pointer ************/
1163 start_sequence ();
1165 /* Normally, the dwarf2out frame-related-expr interpreter does
1166 not expect to have the CFA change once the frame pointer is
1167 set up. Thus, we avoid marking the move insn below and
1168 instead indicate that the entire operation is complete after
1169 the frame pointer subtraction is done. */
1171 insn = emit_move_insn (fp, stack_pointer_rtx);
1172 if (frame_pointer_needed)
1174 RTX_FRAME_RELATED_P (insn) = 1;
1175 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1176 gen_rtx_SET (VOIDmode, fp, stack_pointer_rtx));
1179 insn = emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp),
1180 my_fp, neg_size));
1182 if (frame_pointer_needed)
1184 RTX_FRAME_RELATED_P (insn) = 1;
1185 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1186 gen_rtx_SET (VOIDmode, fp,
1187 plus_constant (Pmode, fp,
1188 -size_cfa)));
1191 /* Copy to stack pointer. Note that since we've already
1192 changed the CFA to the frame pointer this operation
1193 need not be annotated if frame pointer is needed.
1194 Always move through unspec, see PR50063.
1195 For meaning of irq_state see movhi_sp_r insn. */
1197 if (cfun->machine->is_interrupt)
1198 irq_state = 1;
1200 if (TARGET_NO_INTERRUPTS
1201 || cfun->machine->is_signal
1202 || cfun->machine->is_OS_main)
1203 irq_state = 0;
1205 if (AVR_HAVE_8BIT_SP)
1206 irq_state = 2;
1208 insn = emit_insn (gen_movhi_sp_r (stack_pointer_rtx,
1209 fp, GEN_INT (irq_state)));
1210 if (!frame_pointer_needed)
1212 RTX_FRAME_RELATED_P (insn) = 1;
1213 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1214 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
1215 plus_constant (Pmode,
1216 stack_pointer_rtx,
1217 -size_cfa)));
1220 fp_plus_insns = get_insns ();
1221 end_sequence ();
1223 /************ Method 2: Adjust Stack pointer ************/
1225 /* Stack adjustment by means of RCALL . and/or PUSH __TMP_REG__
1226 can only handle specific offsets. */
1228 if (avr_sp_immediate_operand (gen_int_mode (-size, HImode), HImode))
1230 rtx sp_plus_insns;
1232 start_sequence ();
1234 insn = emit_move_insn (stack_pointer_rtx,
1235 plus_constant (Pmode, stack_pointer_rtx,
1236 -size));
1237 RTX_FRAME_RELATED_P (insn) = 1;
1238 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1239 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
1240 plus_constant (Pmode,
1241 stack_pointer_rtx,
1242 -size_cfa)));
1243 if (frame_pointer_needed)
1245 insn = emit_move_insn (fp, stack_pointer_rtx);
1246 RTX_FRAME_RELATED_P (insn) = 1;
1249 sp_plus_insns = get_insns ();
1250 end_sequence ();
1252 /************ Use shortest method ************/
1254 emit_insn (get_sequence_length (sp_plus_insns)
1255 < get_sequence_length (fp_plus_insns)
1256 ? sp_plus_insns
1257 : fp_plus_insns);
1259 else
1261 emit_insn (fp_plus_insns);
1264 cfun->machine->stack_usage += size_cfa;
1265 } /* !minimize && size != 0 */
1266 } /* !minimize */
1270 /* Output function prologue. */
1272 void
1273 avr_expand_prologue (void)
1275 HARD_REG_SET set;
1276 HOST_WIDE_INT size;
1278 size = get_frame_size() + avr_outgoing_args_size();
1280 cfun->machine->stack_usage = 0;
1282 /* Prologue: naked. */
1283 if (cfun->machine->is_naked)
1285 return;
1288 avr_regs_to_save (&set);
1290 if (cfun->machine->is_interrupt || cfun->machine->is_signal)
1292 /* Enable interrupts. */
1293 if (cfun->machine->is_interrupt)
1294 emit_insn (gen_enable_interrupt ());
1296 /* Push zero reg. */
1297 emit_push_byte (ZERO_REGNO, true);
1299 /* Push tmp reg. */
1300 emit_push_byte (TMP_REGNO, true);
1302 /* Push SREG. */
1303 /* ??? There's no dwarf2 column reserved for SREG. */
1304 emit_push_sfr (sreg_rtx, false, false /* clr */);
1306 /* Clear zero reg. */
1307 emit_move_insn (zero_reg_rtx, const0_rtx);
1309 /* Prevent any attempt to delete the setting of ZERO_REG! */
1310 emit_use (zero_reg_rtx);
1312 /* Push and clear RAMPD/X/Y/Z if present and low-part register is used.
1313 ??? There are no dwarf2 columns reserved for RAMPD/X/Y/Z. */
1315 if (AVR_HAVE_RAMPD)
1316 emit_push_sfr (rampd_rtx, false /* frame-related */, true /* clr */);
1318 if (AVR_HAVE_RAMPX
1319 && TEST_HARD_REG_BIT (set, REG_X)
1320 && TEST_HARD_REG_BIT (set, REG_X + 1))
1322 emit_push_sfr (rampx_rtx, false /* frame-related */, true /* clr */);
1325 if (AVR_HAVE_RAMPY
1326 && (frame_pointer_needed
1327 || (TEST_HARD_REG_BIT (set, REG_Y)
1328 && TEST_HARD_REG_BIT (set, REG_Y + 1))))
1330 emit_push_sfr (rampy_rtx, false /* frame-related */, true /* clr */);
1333 if (AVR_HAVE_RAMPZ
1334 && TEST_HARD_REG_BIT (set, REG_Z)
1335 && TEST_HARD_REG_BIT (set, REG_Z + 1))
1337 emit_push_sfr (rampz_rtx, false /* frame-related */, AVR_HAVE_RAMPD);
1339 } /* is_interrupt is_signal */
1341 avr_prologue_setup_frame (size, set);
1343 if (flag_stack_usage_info)
1344 current_function_static_stack_size = cfun->machine->stack_usage;
1348 /* Implement `TARGET_ASM_FUNCTION_END_PROLOGUE'. */
1349 /* Output summary at end of function prologue. */
1351 static void
1352 avr_asm_function_end_prologue (FILE *file)
1354 if (cfun->machine->is_naked)
1356 fputs ("/* prologue: naked */\n", file);
1358 else
1360 if (cfun->machine->is_interrupt)
1362 fputs ("/* prologue: Interrupt */\n", file);
1364 else if (cfun->machine->is_signal)
1366 fputs ("/* prologue: Signal */\n", file);
1368 else
1369 fputs ("/* prologue: function */\n", file);
1372 if (ACCUMULATE_OUTGOING_ARGS)
1373 fprintf (file, "/* outgoing args size = %d */\n",
1374 avr_outgoing_args_size());
1376 fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n",
1377 get_frame_size());
1378 fprintf (file, "/* stack size = %d */\n",
1379 cfun->machine->stack_usage);
1380 /* Create symbol stack offset here so all functions have it. Add 1 to stack
1381 usage for offset so that SP + .L__stack_offset = return address. */
1382 fprintf (file, ".L__stack_usage = %d\n", cfun->machine->stack_usage);
1386 /* Implement `EPILOGUE_USES'. */
1389 avr_epilogue_uses (int regno ATTRIBUTE_UNUSED)
1391 if (reload_completed
1392 && cfun->machine
1393 && (cfun->machine->is_interrupt || cfun->machine->is_signal))
1394 return 1;
1395 return 0;
1398 /* Helper for avr_expand_epilogue. Emit a pop of a byte register. */
1400 static void
1401 emit_pop_byte (unsigned regno)
1403 rtx mem, reg;
1405 mem = gen_rtx_PRE_INC (HImode, stack_pointer_rtx);
1406 mem = gen_frame_mem (QImode, mem);
1407 reg = gen_rtx_REG (QImode, regno);
1409 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
1412 /* Output RTL epilogue. */
1414 void
1415 avr_expand_epilogue (bool sibcall_p)
1417 int reg;
1418 int live_seq;
1419 HARD_REG_SET set;
1420 int minimize;
1421 HOST_WIDE_INT size;
1422 bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
1424 size = get_frame_size() + avr_outgoing_args_size();
1426 /* epilogue: naked */
1427 if (cfun->machine->is_naked)
1429 gcc_assert (!sibcall_p);
1431 emit_jump_insn (gen_return ());
1432 return;
1435 avr_regs_to_save (&set);
1436 live_seq = sequent_regs_live ();
1438 minimize = (TARGET_CALL_PROLOGUES
1439 && live_seq
1440 && !isr_p
1441 && !cfun->machine->is_OS_task
1442 && !cfun->machine->is_OS_main);
1444 if (minimize
1445 && (live_seq > 4
1446 || frame_pointer_needed
1447 || size))
1449 /* Get rid of frame. */
1451 if (!frame_pointer_needed)
1453 emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1456 if (size)
1458 emit_move_insn (frame_pointer_rtx,
1459 plus_constant (Pmode, frame_pointer_rtx, size));
1462 emit_insn (gen_epilogue_restores (gen_int_mode (live_seq, HImode)));
1463 return;
1466 if (size)
1468 /* Try two methods to adjust stack and select shortest. */
1470 int irq_state = -1;
1471 rtx fp, my_fp;
1472 rtx fp_plus_insns;
1473 HOST_WIDE_INT size_max;
1475 gcc_assert (frame_pointer_needed
1476 || !isr_p
1477 || !crtl->is_leaf);
1479 fp = my_fp = (frame_pointer_needed
1480 ? frame_pointer_rtx
1481 : gen_rtx_REG (Pmode, REG_X));
1483 if (AVR_HAVE_8BIT_SP)
1485 /* The high byte (r29) does not change:
1486 Prefer SUBI (1 cycle) over SBIW (2 cycles). */
1488 my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
1491 /* For rationale see comment in prologue generation. */
1493 size_max = (HOST_WIDE_INT) GET_MODE_MASK (GET_MODE (my_fp));
1494 if (size > size_max)
1495 size = size_max;
1496 size = trunc_int_for_mode (size, GET_MODE (my_fp));
1498 /********** Method 1: Adjust fp register **********/
1500 start_sequence ();
1502 if (!frame_pointer_needed)
1503 emit_move_insn (fp, stack_pointer_rtx);
1505 emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp), my_fp, size));
1507 /* Copy to stack pointer. */
1509 if (TARGET_NO_INTERRUPTS)
1510 irq_state = 0;
1512 if (AVR_HAVE_8BIT_SP)
1513 irq_state = 2;
1515 emit_insn (gen_movhi_sp_r (stack_pointer_rtx, fp,
1516 GEN_INT (irq_state)));
1518 fp_plus_insns = get_insns ();
1519 end_sequence ();
1521 /********** Method 2: Adjust Stack pointer **********/
1523 if (avr_sp_immediate_operand (gen_int_mode (size, HImode), HImode))
1525 rtx sp_plus_insns;
1527 start_sequence ();
1529 emit_move_insn (stack_pointer_rtx,
1530 plus_constant (Pmode, stack_pointer_rtx, size));
1532 sp_plus_insns = get_insns ();
1533 end_sequence ();
1535 /************ Use shortest method ************/
1537 emit_insn (get_sequence_length (sp_plus_insns)
1538 < get_sequence_length (fp_plus_insns)
1539 ? sp_plus_insns
1540 : fp_plus_insns);
1542 else
1543 emit_insn (fp_plus_insns);
1544 } /* size != 0 */
1546 if (frame_pointer_needed
1547 && !(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
1549 /* Restore previous frame_pointer. See avr_expand_prologue for
1550 rationale for not using pophi. */
1552 emit_pop_byte (REG_Y + 1);
1553 emit_pop_byte (REG_Y);
1556 /* Restore used registers. */
1558 for (reg = 31; reg >= 0; --reg)
1559 if (TEST_HARD_REG_BIT (set, reg))
1560 emit_pop_byte (reg);
1562 if (isr_p)
1564 /* Restore RAMPZ/Y/X/D using tmp_reg as scratch.
1565 The conditions to restore them must be tha same as in prologue. */
1567 if (AVR_HAVE_RAMPZ
1568 && TEST_HARD_REG_BIT (set, REG_Z)
1569 && TEST_HARD_REG_BIT (set, REG_Z + 1))
1571 emit_pop_byte (TMP_REGNO);
1572 emit_move_insn (rampz_rtx, tmp_reg_rtx);
1575 if (AVR_HAVE_RAMPY
1576 && (frame_pointer_needed
1577 || (TEST_HARD_REG_BIT (set, REG_Y)
1578 && TEST_HARD_REG_BIT (set, REG_Y + 1))))
1580 emit_pop_byte (TMP_REGNO);
1581 emit_move_insn (rampy_rtx, tmp_reg_rtx);
1584 if (AVR_HAVE_RAMPX
1585 && TEST_HARD_REG_BIT (set, REG_X)
1586 && TEST_HARD_REG_BIT (set, REG_X + 1))
1588 emit_pop_byte (TMP_REGNO);
1589 emit_move_insn (rampx_rtx, tmp_reg_rtx);
1592 if (AVR_HAVE_RAMPD)
1594 emit_pop_byte (TMP_REGNO);
1595 emit_move_insn (rampd_rtx, tmp_reg_rtx);
1598 /* Restore SREG using tmp_reg as scratch. */
1600 emit_pop_byte (TMP_REGNO);
1601 emit_move_insn (sreg_rtx, tmp_reg_rtx);
1603 /* Restore tmp REG. */
1604 emit_pop_byte (TMP_REGNO);
1606 /* Restore zero REG. */
1607 emit_pop_byte (ZERO_REGNO);
1610 if (!sibcall_p)
1611 emit_jump_insn (gen_return ());
1615 /* Implement `TARGET_ASM_FUNCTION_BEGIN_EPILOGUE'. */
1617 static void
1618 avr_asm_function_begin_epilogue (FILE *file)
1620 fprintf (file, "/* epilogue start */\n");
1624 /* Implement `TARGET_CANNOT_MODITY_JUMPS_P'. */
1626 static bool
1627 avr_cannot_modify_jumps_p (void)
1630 /* Naked Functions must not have any instructions after
1631 their epilogue, see PR42240 */
1633 if (reload_completed
1634 && cfun->machine
1635 && cfun->machine->is_naked)
1637 return true;
1640 return false;
1644 /* Implement `TARGET_MODE_DEPENDENT_ADDRESS_P'. */
1646 static bool
1647 avr_mode_dependent_address_p (const_rtx addr ATTRIBUTE_UNUSED, addr_space_t as)
1649 /* FIXME: Non-generic addresses are not mode-dependent in themselves.
1650 This hook just serves to hack around PR rtl-optimization/52543 by
1651 claiming that non-generic addresses were mode-dependent so that
1652 lower-subreg.c will skip these addresses. lower-subreg.c sets up fake
1653 RTXes to probe SET and MEM costs and assumes that MEM is always in the
1654 generic address space which is not true. */
1656 return !ADDR_SPACE_GENERIC_P (as);
1660 /* Helper function for `avr_legitimate_address_p'. */
1662 static inline bool
1663 avr_reg_ok_for_addr_p (rtx reg, addr_space_t as,
1664 RTX_CODE outer_code, bool strict)
1666 return (REG_P (reg)
1667 && (avr_regno_mode_code_ok_for_base_p (REGNO (reg), QImode,
1668 as, outer_code, UNKNOWN)
1669 || (!strict
1670 && REGNO (reg) >= FIRST_PSEUDO_REGISTER)));
1674 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
1675 machine for a memory operand of mode MODE. */
1677 static bool
1678 avr_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
1680 bool ok = CONSTANT_ADDRESS_P (x);
1682 switch (GET_CODE (x))
1684 case REG:
1685 ok = avr_reg_ok_for_addr_p (x, ADDR_SPACE_GENERIC,
1686 MEM, strict);
1688 if (strict
1689 && GET_MODE_SIZE (mode) > 4
1690 && REG_X == REGNO (x))
1692 ok = false;
1694 break;
1696 case POST_INC:
1697 case PRE_DEC:
1698 ok = avr_reg_ok_for_addr_p (XEXP (x, 0), ADDR_SPACE_GENERIC,
1699 GET_CODE (x), strict);
1700 break;
1702 case PLUS:
1704 rtx reg = XEXP (x, 0);
1705 rtx op1 = XEXP (x, 1);
1707 if (REG_P (reg)
1708 && CONST_INT_P (op1)
1709 && INTVAL (op1) >= 0)
1711 bool fit = IN_RANGE (INTVAL (op1), 0, MAX_LD_OFFSET (mode));
1713 if (fit)
1715 ok = (! strict
1716 || avr_reg_ok_for_addr_p (reg, ADDR_SPACE_GENERIC,
1717 PLUS, strict));
1719 if (reg == frame_pointer_rtx
1720 || reg == arg_pointer_rtx)
1722 ok = true;
1725 else if (frame_pointer_needed
1726 && reg == frame_pointer_rtx)
1728 ok = true;
1732 break;
1734 default:
1735 break;
1738 if (avr_log.legitimate_address_p)
1740 avr_edump ("\n%?: ret=%d, mode=%m strict=%d "
1741 "reload_completed=%d reload_in_progress=%d %s:",
1742 ok, mode, strict, reload_completed, reload_in_progress,
1743 reg_renumber ? "(reg_renumber)" : "");
1745 if (GET_CODE (x) == PLUS
1746 && REG_P (XEXP (x, 0))
1747 && CONST_INT_P (XEXP (x, 1))
1748 && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
1749 && reg_renumber)
1751 avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
1752 true_regnum (XEXP (x, 0)));
1755 avr_edump ("\n%r\n", x);
1758 return ok;
1762 /* Former implementation of TARGET_LEGITIMIZE_ADDRESS,
1763 now only a helper for avr_addr_space_legitimize_address. */
1764 /* Attempts to replace X with a valid
1765 memory address for an operand of mode MODE */
1767 static rtx
1768 avr_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
1770 bool big_offset_p = false;
1772 x = oldx;
1774 if (GET_CODE (oldx) == PLUS
1775 && REG_P (XEXP (oldx, 0)))
1777 if (REG_P (XEXP (oldx, 1)))
1778 x = force_reg (GET_MODE (oldx), oldx);
1779 else if (CONST_INT_P (XEXP (oldx, 1)))
1781 int offs = INTVAL (XEXP (oldx, 1));
1782 if (frame_pointer_rtx != XEXP (oldx, 0)
1783 && offs > MAX_LD_OFFSET (mode))
1785 big_offset_p = true;
1786 x = force_reg (GET_MODE (oldx), oldx);
1791 if (avr_log.legitimize_address)
1793 avr_edump ("\n%?: mode=%m\n %r\n", mode, oldx);
1795 if (x != oldx)
1796 avr_edump (" %s --> %r\n", big_offset_p ? "(big offset)" : "", x);
1799 return x;
1803 /* Implement `LEGITIMIZE_RELOAD_ADDRESS'. */
1804 /* This will allow register R26/27 to be used where it is no worse than normal
1805 base pointers R28/29 or R30/31. For example, if base offset is greater
1806 than 63 bytes or for R++ or --R addressing. */
1809 avr_legitimize_reload_address (rtx *px, enum machine_mode mode,
1810 int opnum, int type, int addr_type,
1811 int ind_levels ATTRIBUTE_UNUSED,
1812 rtx (*mk_memloc)(rtx,int))
1814 rtx x = *px;
1816 if (avr_log.legitimize_reload_address)
1817 avr_edump ("\n%?:%m %r\n", mode, x);
1819 if (1 && (GET_CODE (x) == POST_INC
1820 || GET_CODE (x) == PRE_DEC))
1822 push_reload (XEXP (x, 0), XEXP (x, 0), &XEXP (x, 0), &XEXP (x, 0),
1823 POINTER_REGS, GET_MODE (x), GET_MODE (x), 0, 0,
1824 opnum, RELOAD_OTHER);
1826 if (avr_log.legitimize_reload_address)
1827 avr_edump (" RCLASS.1 = %R\n IN = %r\n OUT = %r\n",
1828 POINTER_REGS, XEXP (x, 0), XEXP (x, 0));
1830 return x;
1833 if (GET_CODE (x) == PLUS
1834 && REG_P (XEXP (x, 0))
1835 && 0 == reg_equiv_constant (REGNO (XEXP (x, 0)))
1836 && CONST_INT_P (XEXP (x, 1))
1837 && INTVAL (XEXP (x, 1)) >= 1)
1839 bool fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
1841 if (fit)
1843 if (reg_equiv_address (REGNO (XEXP (x, 0))) != 0)
1845 int regno = REGNO (XEXP (x, 0));
1846 rtx mem = mk_memloc (x, regno);
1848 push_reload (XEXP (mem, 0), NULL_RTX, &XEXP (mem, 0), NULL,
1849 POINTER_REGS, Pmode, VOIDmode, 0, 0,
1850 1, (enum reload_type) addr_type);
1852 if (avr_log.legitimize_reload_address)
1853 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
1854 POINTER_REGS, XEXP (mem, 0), NULL_RTX);
1856 push_reload (mem, NULL_RTX, &XEXP (x, 0), NULL,
1857 BASE_POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
1858 opnum, (enum reload_type) type);
1860 if (avr_log.legitimize_reload_address)
1861 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
1862 BASE_POINTER_REGS, mem, NULL_RTX);
1864 return x;
1867 else if (! (frame_pointer_needed
1868 && XEXP (x, 0) == frame_pointer_rtx))
1870 push_reload (x, NULL_RTX, px, NULL,
1871 POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
1872 opnum, (enum reload_type) type);
1874 if (avr_log.legitimize_reload_address)
1875 avr_edump (" RCLASS.3 = %R\n IN = %r\n OUT = %r\n",
1876 POINTER_REGS, x, NULL_RTX);
1878 return x;
1882 return NULL_RTX;
1886 /* Implement `TARGET_SECONDARY_RELOAD' */
1888 static reg_class_t
1889 avr_secondary_reload (bool in_p, rtx x,
1890 reg_class_t reload_class ATTRIBUTE_UNUSED,
1891 enum machine_mode mode, secondary_reload_info *sri)
1893 if (in_p
1894 && MEM_P (x)
1895 && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x))
1896 && ADDR_SPACE_MEMX != MEM_ADDR_SPACE (x))
1898 /* For the non-generic 16-bit spaces we need a d-class scratch. */
1900 switch (mode)
1902 default:
1903 gcc_unreachable();
1905 case QImode: sri->icode = CODE_FOR_reload_inqi; break;
1906 case QQmode: sri->icode = CODE_FOR_reload_inqq; break;
1907 case UQQmode: sri->icode = CODE_FOR_reload_inuqq; break;
1909 case HImode: sri->icode = CODE_FOR_reload_inhi; break;
1910 case HQmode: sri->icode = CODE_FOR_reload_inhq; break;
1911 case HAmode: sri->icode = CODE_FOR_reload_inha; break;
1912 case UHQmode: sri->icode = CODE_FOR_reload_inuhq; break;
1913 case UHAmode: sri->icode = CODE_FOR_reload_inuha; break;
1915 case PSImode: sri->icode = CODE_FOR_reload_inpsi; break;
1917 case SImode: sri->icode = CODE_FOR_reload_insi; break;
1918 case SFmode: sri->icode = CODE_FOR_reload_insf; break;
1919 case SQmode: sri->icode = CODE_FOR_reload_insq; break;
1920 case SAmode: sri->icode = CODE_FOR_reload_insa; break;
1921 case USQmode: sri->icode = CODE_FOR_reload_inusq; break;
1922 case USAmode: sri->icode = CODE_FOR_reload_inusa; break;
1926 return NO_REGS;
1930 /* Helper function to print assembler resp. track instruction
1931 sequence lengths. Always return "".
1933 If PLEN == NULL:
1934 Output assembler code from template TPL with operands supplied
1935 by OPERANDS. This is just forwarding to output_asm_insn.
1937 If PLEN != NULL:
1938 If N_WORDS >= 0 Add N_WORDS to *PLEN.
1939 If N_WORDS < 0 Set *PLEN to -N_WORDS.
1940 Don't output anything.
1943 static const char*
1944 avr_asm_len (const char* tpl, rtx* operands, int* plen, int n_words)
1946 if (NULL == plen)
1948 output_asm_insn (tpl, operands);
1950 else
1952 if (n_words < 0)
1953 *plen = -n_words;
1954 else
1955 *plen += n_words;
1958 return "";
1962 /* Return a pointer register name as a string. */
1964 static const char*
1965 ptrreg_to_str (int regno)
1967 switch (regno)
1969 case REG_X: return "X";
1970 case REG_Y: return "Y";
1971 case REG_Z: return "Z";
1972 default:
1973 output_operand_lossage ("address operand requires constraint for"
1974 " X, Y, or Z register");
1976 return NULL;
1979 /* Return the condition name as a string.
1980 Used in conditional jump constructing */
1982 static const char*
1983 cond_string (enum rtx_code code)
1985 switch (code)
1987 case NE:
1988 return "ne";
1989 case EQ:
1990 return "eq";
1991 case GE:
1992 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1993 return "pl";
1994 else
1995 return "ge";
1996 case LT:
1997 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1998 return "mi";
1999 else
2000 return "lt";
2001 case GEU:
2002 return "sh";
2003 case LTU:
2004 return "lo";
2005 default:
2006 gcc_unreachable ();
2009 return "";
2013 /* Implement `TARGET_PRINT_OPERAND_ADDRESS'. */
2014 /* Output ADDR to FILE as address. */
2016 static void
2017 avr_print_operand_address (FILE *file, rtx addr)
2019 switch (GET_CODE (addr))
2021 case REG:
2022 fprintf (file, ptrreg_to_str (REGNO (addr)));
2023 break;
2025 case PRE_DEC:
2026 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
2027 break;
2029 case POST_INC:
2030 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
2031 break;
2033 default:
2034 if (CONSTANT_ADDRESS_P (addr)
2035 && text_segment_operand (addr, VOIDmode))
2037 rtx x = addr;
2038 if (GET_CODE (x) == CONST)
2039 x = XEXP (x, 0);
2040 if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x,1)) == CONST_INT)
2042 /* Assembler gs() will implant word address. Make offset
2043 a byte offset inside gs() for assembler. This is
2044 needed because the more logical (constant+gs(sym)) is not
2045 accepted by gas. For 128K and smaller devices this is ok.
2046 For large devices it will create a trampoline to offset
2047 from symbol which may not be what the user really wanted. */
2049 fprintf (file, "gs(");
2050 output_addr_const (file, XEXP (x,0));
2051 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC ")",
2052 2 * INTVAL (XEXP (x, 1)));
2053 if (AVR_3_BYTE_PC)
2054 if (warning (0, "pointer offset from symbol maybe incorrect"))
2056 output_addr_const (stderr, addr);
2057 fprintf(stderr,"\n");
2060 else
2062 fprintf (file, "gs(");
2063 output_addr_const (file, addr);
2064 fprintf (file, ")");
2067 else
2068 output_addr_const (file, addr);
2073 /* Implement `TARGET_PRINT_OPERAND_PUNCT_VALID_P'. */
2075 static bool
2076 avr_print_operand_punct_valid_p (unsigned char code)
2078 return code == '~' || code == '!';
2082 /* Implement `TARGET_PRINT_OPERAND'. */
2083 /* Output X as assembler operand to file FILE.
2084 For a description of supported %-codes, see top of avr.md. */
2086 static void
2087 avr_print_operand (FILE *file, rtx x, int code)
2089 int abcd = 0;
2091 if (code >= 'A' && code <= 'D')
2092 abcd = code - 'A';
2094 if (code == '~')
2096 if (!AVR_HAVE_JMP_CALL)
2097 fputc ('r', file);
2099 else if (code == '!')
2101 if (AVR_HAVE_EIJMP_EICALL)
2102 fputc ('e', file);
2104 else if (code == 't'
2105 || code == 'T')
2107 static int t_regno = -1;
2108 static int t_nbits = -1;
2110 if (REG_P (x) && t_regno < 0 && code == 'T')
2112 t_regno = REGNO (x);
2113 t_nbits = GET_MODE_BITSIZE (GET_MODE (x));
2115 else if (CONST_INT_P (x) && t_regno >= 0
2116 && IN_RANGE (INTVAL (x), 0, t_nbits - 1))
2118 int bpos = INTVAL (x);
2120 fprintf (file, "%s", reg_names[t_regno + bpos / 8]);
2121 if (code == 'T')
2122 fprintf (file, ",%d", bpos % 8);
2124 t_regno = -1;
2126 else
2127 fatal_insn ("operands to %T/%t must be reg + const_int:", x);
2129 else if (REG_P (x))
2131 if (x == zero_reg_rtx)
2132 fprintf (file, "__zero_reg__");
2133 else if (code == 'r' && REGNO (x) < 32)
2134 fprintf (file, "%d", (int) REGNO (x));
2135 else
2136 fprintf (file, reg_names[REGNO (x) + abcd]);
2138 else if (CONST_INT_P (x))
2140 HOST_WIDE_INT ival = INTVAL (x);
2142 if ('i' != code)
2143 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival + abcd);
2144 else if (low_io_address_operand (x, VOIDmode)
2145 || high_io_address_operand (x, VOIDmode))
2147 if (AVR_HAVE_RAMPZ && ival == avr_addr.rampz)
2148 fprintf (file, "__RAMPZ__");
2149 else if (AVR_HAVE_RAMPY && ival == avr_addr.rampy)
2150 fprintf (file, "__RAMPY__");
2151 else if (AVR_HAVE_RAMPX && ival == avr_addr.rampx)
2152 fprintf (file, "__RAMPX__");
2153 else if (AVR_HAVE_RAMPD && ival == avr_addr.rampd)
2154 fprintf (file, "__RAMPD__");
2155 else if (AVR_XMEGA && ival == avr_addr.ccp)
2156 fprintf (file, "__CCP__");
2157 else if (ival == avr_addr.sreg) fprintf (file, "__SREG__");
2158 else if (ival == avr_addr.sp_l) fprintf (file, "__SP_L__");
2159 else if (ival == avr_addr.sp_h) fprintf (file, "__SP_H__");
2160 else
2162 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
2163 ival - avr_current_arch->sfr_offset);
2166 else
2167 fatal_insn ("bad address, not an I/O address:", x);
2169 else if (MEM_P (x))
2171 rtx addr = XEXP (x, 0);
2173 if (code == 'm')
2175 if (!CONSTANT_P (addr))
2176 fatal_insn ("bad address, not a constant:", addr);
2177 /* Assembler template with m-code is data - not progmem section */
2178 if (text_segment_operand (addr, VOIDmode))
2179 if (warning (0, "accessing data memory with"
2180 " program memory address"))
2182 output_addr_const (stderr, addr);
2183 fprintf(stderr,"\n");
2185 output_addr_const (file, addr);
2187 else if (code == 'i')
2189 avr_print_operand (file, addr, 'i');
2191 else if (code == 'o')
2193 if (GET_CODE (addr) != PLUS)
2194 fatal_insn ("bad address, not (reg+disp):", addr);
2196 avr_print_operand (file, XEXP (addr, 1), 0);
2198 else if (code == 'p' || code == 'r')
2200 if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
2201 fatal_insn ("bad address, not post_inc or pre_dec:", addr);
2203 if (code == 'p')
2204 avr_print_operand_address (file, XEXP (addr, 0)); /* X, Y, Z */
2205 else
2206 avr_print_operand (file, XEXP (addr, 0), 0); /* r26, r28, r30 */
2208 else if (GET_CODE (addr) == PLUS)
2210 avr_print_operand_address (file, XEXP (addr,0));
2211 if (REGNO (XEXP (addr, 0)) == REG_X)
2212 fatal_insn ("internal compiler error. Bad address:"
2213 ,addr);
2214 fputc ('+', file);
2215 avr_print_operand (file, XEXP (addr,1), code);
2217 else
2218 avr_print_operand_address (file, addr);
2220 else if (code == 'i')
2222 fatal_insn ("bad address, not an I/O address:", x);
2224 else if (code == 'x')
2226 /* Constant progmem address - like used in jmp or call */
2227 if (0 == text_segment_operand (x, VOIDmode))
2228 if (warning (0, "accessing program memory"
2229 " with data memory address"))
2231 output_addr_const (stderr, x);
2232 fprintf(stderr,"\n");
2234 /* Use normal symbol for direct address no linker trampoline needed */
2235 output_addr_const (file, x);
2237 else if (CONST_FIXED_P (x))
2239 HOST_WIDE_INT ival = INTVAL (avr_to_int_mode (x));
2240 if (code != 0)
2241 output_operand_lossage ("Unsupported code '%c' for fixed-point:",
2242 code);
2243 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival);
2245 else if (GET_CODE (x) == CONST_DOUBLE)
2247 long val;
2248 REAL_VALUE_TYPE rv;
2249 if (GET_MODE (x) != SFmode)
2250 fatal_insn ("internal compiler error. Unknown mode:", x);
2251 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
2252 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
2253 fprintf (file, "0x%lx", val);
2255 else if (GET_CODE (x) == CONST_STRING)
2256 fputs (XSTR (x, 0), file);
2257 else if (code == 'j')
2258 fputs (cond_string (GET_CODE (x)), file);
2259 else if (code == 'k')
2260 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
2261 else
2262 avr_print_operand_address (file, x);
2266 /* Worker function for `NOTICE_UPDATE_CC'. */
2267 /* Update the condition code in the INSN. */
2269 void
2270 avr_notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
2272 rtx set;
2273 enum attr_cc cc = get_attr_cc (insn);
2275 switch (cc)
2277 default:
2278 break;
2280 case CC_PLUS:
2281 case CC_LDI:
2283 rtx *op = recog_data.operand;
2284 int len_dummy, icc;
2286 /* Extract insn's operands. */
2287 extract_constrain_insn_cached (insn);
2289 switch (cc)
2291 default:
2292 gcc_unreachable();
2294 case CC_PLUS:
2295 avr_out_plus (insn, op, &len_dummy, &icc);
2296 cc = (enum attr_cc) icc;
2297 break;
2299 case CC_LDI:
2301 cc = (op[1] == CONST0_RTX (GET_MODE (op[0]))
2302 && reg_overlap_mentioned_p (op[0], zero_reg_rtx))
2303 /* Loading zero-reg with 0 uses CLR and thus clobbers cc0. */
2304 ? CC_CLOBBER
2305 /* Any other "r,rL" combination does not alter cc0. */
2306 : CC_NONE;
2308 break;
2309 } /* inner switch */
2311 break;
2313 } /* outer swicth */
2315 switch (cc)
2317 default:
2318 /* Special values like CC_OUT_PLUS from above have been
2319 mapped to "standard" CC_* values so we never come here. */
2321 gcc_unreachable();
2322 break;
2324 case CC_NONE:
2325 /* Insn does not affect CC at all. */
2326 break;
2328 case CC_SET_N:
2329 CC_STATUS_INIT;
2330 break;
2332 case CC_SET_ZN:
2333 set = single_set (insn);
2334 CC_STATUS_INIT;
2335 if (set)
2337 cc_status.flags |= CC_NO_OVERFLOW;
2338 cc_status.value1 = SET_DEST (set);
2340 break;
2342 case CC_SET_CZN:
2343 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
2344 The V flag may or may not be known but that's ok because
2345 alter_cond will change tests to use EQ/NE. */
2346 set = single_set (insn);
2347 CC_STATUS_INIT;
2348 if (set)
2350 cc_status.value1 = SET_DEST (set);
2351 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
2353 break;
2355 case CC_COMPARE:
2356 set = single_set (insn);
2357 CC_STATUS_INIT;
2358 if (set)
2359 cc_status.value1 = SET_SRC (set);
2360 break;
2362 case CC_CLOBBER:
2363 /* Insn doesn't leave CC in a usable state. */
2364 CC_STATUS_INIT;
2365 break;
2369 /* Choose mode for jump insn:
2370 1 - relative jump in range -63 <= x <= 62 ;
2371 2 - relative jump in range -2046 <= x <= 2045 ;
2372 3 - absolute jump (only for ATmega[16]03). */
2375 avr_jump_mode (rtx x, rtx insn)
2377 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_CODE (x) == LABEL_REF
2378 ? XEXP (x, 0) : x));
2379 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
2380 int jump_distance = cur_addr - dest_addr;
2382 if (-63 <= jump_distance && jump_distance <= 62)
2383 return 1;
2384 else if (-2046 <= jump_distance && jump_distance <= 2045)
2385 return 2;
2386 else if (AVR_HAVE_JMP_CALL)
2387 return 3;
2389 return 2;
2392 /* Return an AVR condition jump commands.
2393 X is a comparison RTX.
2394 LEN is a number returned by avr_jump_mode function.
2395 If REVERSE nonzero then condition code in X must be reversed. */
2397 const char*
2398 ret_cond_branch (rtx x, int len, int reverse)
2400 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
2402 switch (cond)
2404 case GT:
2405 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2406 return (len == 1 ? ("breq .+2" CR_TAB
2407 "brpl %0") :
2408 len == 2 ? ("breq .+4" CR_TAB
2409 "brmi .+2" CR_TAB
2410 "rjmp %0") :
2411 ("breq .+6" CR_TAB
2412 "brmi .+4" CR_TAB
2413 "jmp %0"));
2415 else
2416 return (len == 1 ? ("breq .+2" CR_TAB
2417 "brge %0") :
2418 len == 2 ? ("breq .+4" CR_TAB
2419 "brlt .+2" CR_TAB
2420 "rjmp %0") :
2421 ("breq .+6" CR_TAB
2422 "brlt .+4" CR_TAB
2423 "jmp %0"));
2424 case GTU:
2425 return (len == 1 ? ("breq .+2" CR_TAB
2426 "brsh %0") :
2427 len == 2 ? ("breq .+4" CR_TAB
2428 "brlo .+2" CR_TAB
2429 "rjmp %0") :
2430 ("breq .+6" CR_TAB
2431 "brlo .+4" CR_TAB
2432 "jmp %0"));
2433 case LE:
2434 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2435 return (len == 1 ? ("breq %0" CR_TAB
2436 "brmi %0") :
2437 len == 2 ? ("breq .+2" CR_TAB
2438 "brpl .+2" CR_TAB
2439 "rjmp %0") :
2440 ("breq .+2" CR_TAB
2441 "brpl .+4" CR_TAB
2442 "jmp %0"));
2443 else
2444 return (len == 1 ? ("breq %0" CR_TAB
2445 "brlt %0") :
2446 len == 2 ? ("breq .+2" CR_TAB
2447 "brge .+2" CR_TAB
2448 "rjmp %0") :
2449 ("breq .+2" CR_TAB
2450 "brge .+4" CR_TAB
2451 "jmp %0"));
2452 case LEU:
2453 return (len == 1 ? ("breq %0" CR_TAB
2454 "brlo %0") :
2455 len == 2 ? ("breq .+2" CR_TAB
2456 "brsh .+2" CR_TAB
2457 "rjmp %0") :
2458 ("breq .+2" CR_TAB
2459 "brsh .+4" CR_TAB
2460 "jmp %0"));
2461 default:
2462 if (reverse)
2464 switch (len)
2466 case 1:
2467 return "br%k1 %0";
2468 case 2:
2469 return ("br%j1 .+2" CR_TAB
2470 "rjmp %0");
2471 default:
2472 return ("br%j1 .+4" CR_TAB
2473 "jmp %0");
2476 else
2478 switch (len)
2480 case 1:
2481 return "br%j1 %0";
2482 case 2:
2483 return ("br%k1 .+2" CR_TAB
2484 "rjmp %0");
2485 default:
2486 return ("br%k1 .+4" CR_TAB
2487 "jmp %0");
2491 return "";
2495 /* Worker function for `FINAL_PRESCAN_INSN'. */
2496 /* Output insn cost for next insn. */
2498 void
2499 avr_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
2500 int num_operands ATTRIBUTE_UNUSED)
2502 if (avr_log.rtx_costs)
2504 rtx set = single_set (insn);
2506 if (set)
2507 fprintf (asm_out_file, "/* DEBUG: cost = %d. */\n",
2508 set_src_cost (SET_SRC (set), optimize_insn_for_speed_p ()));
2509 else
2510 fprintf (asm_out_file, "/* DEBUG: pattern-cost = %d. */\n",
2511 rtx_cost (PATTERN (insn), INSN, 0,
2512 optimize_insn_for_speed_p()));
2516 /* Return 0 if undefined, 1 if always true or always false. */
2519 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE op, rtx x)
2521 unsigned int max = (mode == QImode ? 0xff :
2522 mode == HImode ? 0xffff :
2523 mode == PSImode ? 0xffffff :
2524 mode == SImode ? 0xffffffff : 0);
2525 if (max && op && CONST_INT_P (x))
2527 if (unsigned_condition (op) != op)
2528 max >>= 1;
2530 if (max != (INTVAL (x) & max)
2531 && INTVAL (x) != 0xff)
2532 return 1;
2534 return 0;
2538 /* Worker function for `FUNCTION_ARG_REGNO_P'. */
2539 /* Returns nonzero if REGNO is the number of a hard
2540 register in which function arguments are sometimes passed. */
2543 avr_function_arg_regno_p(int r)
2545 return (r >= 8 && r <= 25);
2549 /* Worker function for `INIT_CUMULATIVE_ARGS'. */
2550 /* Initializing the variable cum for the state at the beginning
2551 of the argument list. */
2553 void
2554 avr_init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
2555 tree fndecl ATTRIBUTE_UNUSED)
2557 cum->nregs = 18;
2558 cum->regno = FIRST_CUM_REG;
2559 if (!libname && stdarg_p (fntype))
2560 cum->nregs = 0;
2562 /* Assume the calle may be tail called */
2564 cfun->machine->sibcall_fails = 0;
2567 /* Returns the number of registers to allocate for a function argument. */
2569 static int
2570 avr_num_arg_regs (enum machine_mode mode, const_tree type)
2572 int size;
2574 if (mode == BLKmode)
2575 size = int_size_in_bytes (type);
2576 else
2577 size = GET_MODE_SIZE (mode);
2579 /* Align all function arguments to start in even-numbered registers.
2580 Odd-sized arguments leave holes above them. */
2582 return (size + 1) & ~1;
2586 /* Implement `TARGET_FUNCTION_ARG'. */
2587 /* Controls whether a function argument is passed
2588 in a register, and which register. */
2590 static rtx
2591 avr_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
2592 const_tree type, bool named ATTRIBUTE_UNUSED)
2594 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2595 int bytes = avr_num_arg_regs (mode, type);
2597 if (cum->nregs && bytes <= cum->nregs)
2598 return gen_rtx_REG (mode, cum->regno - bytes);
2600 return NULL_RTX;
2604 /* Implement `TARGET_FUNCTION_ARG_ADVANCE'. */
2605 /* Update the summarizer variable CUM to advance past an argument
2606 in the argument list. */
2608 static void
2609 avr_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
2610 const_tree type, bool named ATTRIBUTE_UNUSED)
2612 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2613 int bytes = avr_num_arg_regs (mode, type);
2615 cum->nregs -= bytes;
2616 cum->regno -= bytes;
2618 /* A parameter is being passed in a call-saved register. As the original
2619 contents of these regs has to be restored before leaving the function,
2620 a function must not pass arguments in call-saved regs in order to get
2621 tail-called. */
2623 if (cum->regno >= 8
2624 && cum->nregs >= 0
2625 && !call_used_regs[cum->regno])
2627 /* FIXME: We ship info on failing tail-call in struct machine_function.
2628 This uses internals of calls.c:expand_call() and the way args_so_far
2629 is used. targetm.function_ok_for_sibcall() needs to be extended to
2630 pass &args_so_far, too. At present, CUMULATIVE_ARGS is target
2631 dependent so that such an extension is not wanted. */
2633 cfun->machine->sibcall_fails = 1;
2636 /* Test if all registers needed by the ABI are actually available. If the
2637 user has fixed a GPR needed to pass an argument, an (implicit) function
2638 call will clobber that fixed register. See PR45099 for an example. */
2640 if (cum->regno >= 8
2641 && cum->nregs >= 0)
2643 int regno;
2645 for (regno = cum->regno; regno < cum->regno + bytes; regno++)
2646 if (fixed_regs[regno])
2647 warning (0, "fixed register %s used to pass parameter to function",
2648 reg_names[regno]);
2651 if (cum->nregs <= 0)
2653 cum->nregs = 0;
2654 cum->regno = FIRST_CUM_REG;
2658 /* Implement `TARGET_FUNCTION_OK_FOR_SIBCALL' */
2659 /* Decide whether we can make a sibling call to a function. DECL is the
2660 declaration of the function being targeted by the call and EXP is the
2661 CALL_EXPR representing the call. */
2663 static bool
2664 avr_function_ok_for_sibcall (tree decl_callee, tree exp_callee)
2666 tree fntype_callee;
2668 /* Tail-calling must fail if callee-saved regs are used to pass
2669 function args. We must not tail-call when `epilogue_restores'
2670 is used. Unfortunately, we cannot tell at this point if that
2671 actually will happen or not, and we cannot step back from
2672 tail-calling. Thus, we inhibit tail-calling with -mcall-prologues. */
2674 if (cfun->machine->sibcall_fails
2675 || TARGET_CALL_PROLOGUES)
2677 return false;
2680 fntype_callee = TREE_TYPE (CALL_EXPR_FN (exp_callee));
2682 if (decl_callee)
2684 decl_callee = TREE_TYPE (decl_callee);
2686 else
2688 decl_callee = fntype_callee;
2690 while (FUNCTION_TYPE != TREE_CODE (decl_callee)
2691 && METHOD_TYPE != TREE_CODE (decl_callee))
2693 decl_callee = TREE_TYPE (decl_callee);
2697 /* Ensure that caller and callee have compatible epilogues */
2699 if (cfun->machine->is_interrupt
2700 || cfun->machine->is_signal
2701 || cfun->machine->is_naked
2702 || avr_naked_function_p (decl_callee)
2703 /* FIXME: For OS_task and OS_main, this might be over-conservative. */
2704 || (avr_OS_task_function_p (decl_callee)
2705 != cfun->machine->is_OS_task)
2706 || (avr_OS_main_function_p (decl_callee)
2707 != cfun->machine->is_OS_main))
2709 return false;
2712 return true;
2715 /***********************************************************************
2716 Functions for outputting various mov's for a various modes
2717 ************************************************************************/
2719 /* Return true if a value of mode MODE is read from flash by
2720 __load_* function from libgcc. */
2722 bool
2723 avr_load_libgcc_p (rtx op)
2725 enum machine_mode mode = GET_MODE (op);
2726 int n_bytes = GET_MODE_SIZE (mode);
2728 return (n_bytes > 2
2729 && !AVR_HAVE_LPMX
2730 && avr_mem_flash_p (op));
2733 /* Return true if a value of mode MODE is read by __xload_* function. */
2735 bool
2736 avr_xload_libgcc_p (enum machine_mode mode)
2738 int n_bytes = GET_MODE_SIZE (mode);
2740 return (n_bytes > 1
2741 || avr_current_device->n_flash > 1);
2745 /* Fixme: This is a hack because secondary reloads don't works as expected.
2747 Find an unused d-register to be used as scratch in INSN.
2748 EXCLUDE is either NULL_RTX or some register. In the case where EXCLUDE
2749 is a register, skip all possible return values that overlap EXCLUDE.
2750 The policy for the returned register is similar to that of
2751 `reg_unused_after', i.e. the returned register may overlap the SET_DEST
2752 of INSN.
2754 Return a QImode d-register or NULL_RTX if nothing found. */
2756 static rtx
2757 avr_find_unused_d_reg (rtx insn, rtx exclude)
2759 int regno;
2760 bool isr_p = (avr_interrupt_function_p (current_function_decl)
2761 || avr_signal_function_p (current_function_decl));
2763 for (regno = 16; regno < 32; regno++)
2765 rtx reg = all_regs_rtx[regno];
2767 if ((exclude
2768 && reg_overlap_mentioned_p (exclude, reg))
2769 || fixed_regs[regno])
2771 continue;
2774 /* Try non-live register */
2776 if (!df_regs_ever_live_p (regno)
2777 && (TREE_THIS_VOLATILE (current_function_decl)
2778 || cfun->machine->is_OS_task
2779 || cfun->machine->is_OS_main
2780 || (!isr_p && call_used_regs[regno])))
2782 return reg;
2785 /* Any live register can be used if it is unused after.
2786 Prologue/epilogue will care for it as needed. */
2788 if (df_regs_ever_live_p (regno)
2789 && reg_unused_after (insn, reg))
2791 return reg;
2795 return NULL_RTX;
2799 /* Helper function for the next function in the case where only restricted
2800 version of LPM instruction is available. */
2802 static const char*
2803 avr_out_lpm_no_lpmx (rtx insn, rtx *xop, int *plen)
2805 rtx dest = xop[0];
2806 rtx addr = xop[1];
2807 int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
2808 int regno_dest;
2810 regno_dest = REGNO (dest);
2812 /* The implicit target register of LPM. */
2813 xop[3] = lpm_reg_rtx;
2815 switch (GET_CODE (addr))
2817 default:
2818 gcc_unreachable();
2820 case REG:
2822 gcc_assert (REG_Z == REGNO (addr));
2824 switch (n_bytes)
2826 default:
2827 gcc_unreachable();
2829 case 1:
2830 avr_asm_len ("%4lpm", xop, plen, 1);
2832 if (regno_dest != LPM_REGNO)
2833 avr_asm_len ("mov %0,%3", xop, plen, 1);
2835 return "";
2837 case 2:
2838 if (REGNO (dest) == REG_Z)
2839 return avr_asm_len ("%4lpm" CR_TAB
2840 "push %3" CR_TAB
2841 "adiw %2,1" CR_TAB
2842 "%4lpm" CR_TAB
2843 "mov %B0,%3" CR_TAB
2844 "pop %A0", xop, plen, 6);
2846 avr_asm_len ("%4lpm" CR_TAB
2847 "mov %A0,%3" CR_TAB
2848 "adiw %2,1" CR_TAB
2849 "%4lpm" CR_TAB
2850 "mov %B0,%3", xop, plen, 5);
2852 if (!reg_unused_after (insn, addr))
2853 avr_asm_len ("sbiw %2,1", xop, plen, 1);
2855 break; /* 2 */
2858 break; /* REG */
2860 case POST_INC:
2862 gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
2863 && n_bytes <= 4);
2865 if (regno_dest == LPM_REGNO)
2866 avr_asm_len ("%4lpm" CR_TAB
2867 "adiw %2,1", xop, plen, 2);
2868 else
2869 avr_asm_len ("%4lpm" CR_TAB
2870 "mov %A0,%3" CR_TAB
2871 "adiw %2,1", xop, plen, 3);
2873 if (n_bytes >= 2)
2874 avr_asm_len ("%4lpm" CR_TAB
2875 "mov %B0,%3" CR_TAB
2876 "adiw %2,1", xop, plen, 3);
2878 if (n_bytes >= 3)
2879 avr_asm_len ("%4lpm" CR_TAB
2880 "mov %C0,%3" CR_TAB
2881 "adiw %2,1", xop, plen, 3);
2883 if (n_bytes >= 4)
2884 avr_asm_len ("%4lpm" CR_TAB
2885 "mov %D0,%3" CR_TAB
2886 "adiw %2,1", xop, plen, 3);
2888 break; /* POST_INC */
2890 } /* switch CODE (addr) */
2892 return "";
2896 /* If PLEN == NULL: Ouput instructions to load a value from a memory location
2897 OP[1] in AS1 to register OP[0].
2898 If PLEN != 0 set *PLEN to the length in words of the instruction sequence.
2899 Return "". */
2901 const char*
2902 avr_out_lpm (rtx insn, rtx *op, int *plen)
2904 rtx xop[7];
2905 rtx dest = op[0];
2906 rtx src = SET_SRC (single_set (insn));
2907 rtx addr;
2908 int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
2909 int segment;
2910 RTX_CODE code;
2911 addr_space_t as = MEM_ADDR_SPACE (src);
2913 if (plen)
2914 *plen = 0;
2916 if (MEM_P (dest))
2918 warning (0, "writing to address space %qs not supported",
2919 avr_addrspace[MEM_ADDR_SPACE (dest)].name);
2921 return "";
2924 addr = XEXP (src, 0);
2925 code = GET_CODE (addr);
2927 gcc_assert (REG_P (dest));
2928 gcc_assert (REG == code || POST_INC == code);
2930 xop[0] = dest;
2931 xop[1] = addr;
2932 xop[2] = lpm_addr_reg_rtx;
2933 xop[4] = xstring_empty;
2934 xop[5] = tmp_reg_rtx;
2935 xop[6] = XEXP (rampz_rtx, 0);
2937 segment = avr_addrspace[as].segment;
2939 /* Set RAMPZ as needed. */
2941 if (segment)
2943 xop[4] = GEN_INT (segment);
2944 xop[3] = avr_find_unused_d_reg (insn, lpm_addr_reg_rtx);
2946 if (xop[3] != NULL_RTX)
2948 avr_asm_len ("ldi %3,%4" CR_TAB
2949 "out %i6,%3", xop, plen, 2);
2951 else if (segment == 1)
2953 avr_asm_len ("clr %5" CR_TAB
2954 "inc %5" CR_TAB
2955 "out %i6,%5", xop, plen, 3);
2957 else
2959 avr_asm_len ("mov %5,%2" CR_TAB
2960 "ldi %2,%4" CR_TAB
2961 "out %i6,%2" CR_TAB
2962 "mov %2,%5", xop, plen, 4);
2965 xop[4] = xstring_e;
2967 if (!AVR_HAVE_ELPMX)
2968 return avr_out_lpm_no_lpmx (insn, xop, plen);
2970 else if (!AVR_HAVE_LPMX)
2972 return avr_out_lpm_no_lpmx (insn, xop, plen);
2975 /* We have [E]LPMX: Output reading from Flash the comfortable way. */
2977 switch (GET_CODE (addr))
2979 default:
2980 gcc_unreachable();
2982 case REG:
2984 gcc_assert (REG_Z == REGNO (addr));
2986 switch (n_bytes)
2988 default:
2989 gcc_unreachable();
2991 case 1:
2992 return avr_asm_len ("%4lpm %0,%a2", xop, plen, 1);
2994 case 2:
2995 if (REGNO (dest) == REG_Z)
2996 return avr_asm_len ("%4lpm %5,%a2+" CR_TAB
2997 "%4lpm %B0,%a2" CR_TAB
2998 "mov %A0,%5", xop, plen, 3);
2999 else
3001 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3002 "%4lpm %B0,%a2", xop, plen, 2);
3004 if (!reg_unused_after (insn, addr))
3005 avr_asm_len ("sbiw %2,1", xop, plen, 1);
3008 break; /* 2 */
3010 case 3:
3012 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3013 "%4lpm %B0,%a2+" CR_TAB
3014 "%4lpm %C0,%a2", xop, plen, 3);
3016 if (!reg_unused_after (insn, addr))
3017 avr_asm_len ("sbiw %2,2", xop, plen, 1);
3019 break; /* 3 */
3021 case 4:
3023 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3024 "%4lpm %B0,%a2+", xop, plen, 2);
3026 if (REGNO (dest) == REG_Z - 2)
3027 return avr_asm_len ("%4lpm %5,%a2+" CR_TAB
3028 "%4lpm %C0,%a2" CR_TAB
3029 "mov %D0,%5", xop, plen, 3);
3030 else
3032 avr_asm_len ("%4lpm %C0,%a2+" CR_TAB
3033 "%4lpm %D0,%a2", xop, plen, 2);
3035 if (!reg_unused_after (insn, addr))
3036 avr_asm_len ("sbiw %2,3", xop, plen, 1);
3039 break; /* 4 */
3040 } /* n_bytes */
3042 break; /* REG */
3044 case POST_INC:
3046 gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
3047 && n_bytes <= 4);
3049 avr_asm_len ("%4lpm %A0,%a2+", xop, plen, 1);
3050 if (n_bytes >= 2) avr_asm_len ("%4lpm %B0,%a2+", xop, plen, 1);
3051 if (n_bytes >= 3) avr_asm_len ("%4lpm %C0,%a2+", xop, plen, 1);
3052 if (n_bytes >= 4) avr_asm_len ("%4lpm %D0,%a2+", xop, plen, 1);
3054 break; /* POST_INC */
3056 } /* switch CODE (addr) */
3058 if (xop[4] == xstring_e && AVR_HAVE_RAMPD)
3060 /* Reset RAMPZ to 0 so that EBI devices don't read garbage from RAM. */
3062 xop[0] = zero_reg_rtx;
3063 avr_asm_len ("out %i6,%0", xop, plen, 1);
3066 return "";
3070 /* Worker function for xload_8 insn. */
3072 const char*
3073 avr_out_xload (rtx insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
3075 rtx xop[4];
3077 xop[0] = op[0];
3078 xop[1] = op[1];
3079 xop[2] = lpm_addr_reg_rtx;
3080 xop[3] = AVR_HAVE_LPMX ? op[0] : lpm_reg_rtx;
3082 avr_asm_len (AVR_HAVE_LPMX ? "lpm %3,%a2" : "lpm", xop, plen, -1);
3084 avr_asm_len ("sbrc %1,7" CR_TAB
3085 "ld %3,%a2", xop, plen, 2);
3087 if (REGNO (xop[0]) != REGNO (xop[3]))
3088 avr_asm_len ("mov %0,%3", xop, plen, 1);
3090 return "";
3094 const char*
3095 output_movqi (rtx insn, rtx operands[], int *plen)
3097 rtx dest = operands[0];
3098 rtx src = operands[1];
3100 if (avr_mem_flash_p (src)
3101 || avr_mem_flash_p (dest))
3103 return avr_out_lpm (insn, operands, plen);
3106 gcc_assert (1 == GET_MODE_SIZE (GET_MODE (dest)));
3108 if (REG_P (dest))
3110 if (REG_P (src)) /* mov r,r */
3112 if (test_hard_reg_class (STACK_REG, dest))
3113 return avr_asm_len ("out %0,%1", operands, plen, -1);
3114 else if (test_hard_reg_class (STACK_REG, src))
3115 return avr_asm_len ("in %0,%1", operands, plen, -1);
3117 return avr_asm_len ("mov %0,%1", operands, plen, -1);
3119 else if (CONSTANT_P (src))
3121 output_reload_in_const (operands, NULL_RTX, plen, false);
3122 return "";
3124 else if (MEM_P (src))
3125 return out_movqi_r_mr (insn, operands, plen); /* mov r,m */
3127 else if (MEM_P (dest))
3129 rtx xop[2];
3131 xop[0] = dest;
3132 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
3134 return out_movqi_mr_r (insn, xop, plen);
3137 return "";
3141 const char *
3142 output_movhi (rtx insn, rtx xop[], int *plen)
3144 rtx dest = xop[0];
3145 rtx src = xop[1];
3147 gcc_assert (GET_MODE_SIZE (GET_MODE (dest)) == 2);
3149 if (avr_mem_flash_p (src)
3150 || avr_mem_flash_p (dest))
3152 return avr_out_lpm (insn, xop, plen);
3155 gcc_assert (2 == GET_MODE_SIZE (GET_MODE (dest)));
3157 if (REG_P (dest))
3159 if (REG_P (src)) /* mov r,r */
3161 if (test_hard_reg_class (STACK_REG, dest))
3163 if (AVR_HAVE_8BIT_SP)
3164 return avr_asm_len ("out __SP_L__,%A1", xop, plen, -1);
3166 if (AVR_XMEGA)
3167 return avr_asm_len ("out __SP_L__,%A1" CR_TAB
3168 "out __SP_H__,%B1", xop, plen, -2);
3170 /* Use simple load of SP if no interrupts are used. */
3172 return TARGET_NO_INTERRUPTS
3173 ? avr_asm_len ("out __SP_H__,%B1" CR_TAB
3174 "out __SP_L__,%A1", xop, plen, -2)
3175 : avr_asm_len ("in __tmp_reg__,__SREG__" CR_TAB
3176 "cli" CR_TAB
3177 "out __SP_H__,%B1" CR_TAB
3178 "out __SREG__,__tmp_reg__" CR_TAB
3179 "out __SP_L__,%A1", xop, plen, -5);
3181 else if (test_hard_reg_class (STACK_REG, src))
3183 return !AVR_HAVE_SPH
3184 ? avr_asm_len ("in %A0,__SP_L__" CR_TAB
3185 "clr %B0", xop, plen, -2)
3187 : avr_asm_len ("in %A0,__SP_L__" CR_TAB
3188 "in %B0,__SP_H__", xop, plen, -2);
3191 return AVR_HAVE_MOVW
3192 ? avr_asm_len ("movw %0,%1", xop, plen, -1)
3194 : avr_asm_len ("mov %A0,%A1" CR_TAB
3195 "mov %B0,%B1", xop, plen, -2);
3196 } /* REG_P (src) */
3197 else if (CONSTANT_P (src))
3199 return output_reload_inhi (xop, NULL, plen);
3201 else if (MEM_P (src))
3203 return out_movhi_r_mr (insn, xop, plen); /* mov r,m */
3206 else if (MEM_P (dest))
3208 rtx xop[2];
3210 xop[0] = dest;
3211 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
3213 return out_movhi_mr_r (insn, xop, plen);
3216 fatal_insn ("invalid insn:", insn);
3218 return "";
3221 static const char*
3222 out_movqi_r_mr (rtx insn, rtx op[], int *plen)
3224 rtx dest = op[0];
3225 rtx src = op[1];
3226 rtx x = XEXP (src, 0);
3228 if (CONSTANT_ADDRESS_P (x))
3230 return optimize > 0 && io_address_operand (x, QImode)
3231 ? avr_asm_len ("in %0,%i1", op, plen, -1)
3232 : avr_asm_len ("lds %0,%m1", op, plen, -2);
3234 else if (GET_CODE (x) == PLUS
3235 && REG_P (XEXP (x, 0))
3236 && CONST_INT_P (XEXP (x, 1)))
3238 /* memory access by reg+disp */
3240 int disp = INTVAL (XEXP (x, 1));
3242 if (disp - GET_MODE_SIZE (GET_MODE (src)) >= 63)
3244 if (REGNO (XEXP (x, 0)) != REG_Y)
3245 fatal_insn ("incorrect insn:",insn);
3247 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
3248 return avr_asm_len ("adiw r28,%o1-63" CR_TAB
3249 "ldd %0,Y+63" CR_TAB
3250 "sbiw r28,%o1-63", op, plen, -3);
3252 return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
3253 "sbci r29,hi8(-%o1)" CR_TAB
3254 "ld %0,Y" CR_TAB
3255 "subi r28,lo8(%o1)" CR_TAB
3256 "sbci r29,hi8(%o1)", op, plen, -5);
3258 else if (REGNO (XEXP (x, 0)) == REG_X)
3260 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
3261 it but I have this situation with extremal optimizing options. */
3263 avr_asm_len ("adiw r26,%o1" CR_TAB
3264 "ld %0,X", op, plen, -2);
3266 if (!reg_overlap_mentioned_p (dest, XEXP (x,0))
3267 && !reg_unused_after (insn, XEXP (x,0)))
3269 avr_asm_len ("sbiw r26,%o1", op, plen, 1);
3272 return "";
3275 return avr_asm_len ("ldd %0,%1", op, plen, -1);
3278 return avr_asm_len ("ld %0,%1", op, plen, -1);
3281 static const char*
3282 out_movhi_r_mr (rtx insn, rtx op[], int *plen)
3284 rtx dest = op[0];
3285 rtx src = op[1];
3286 rtx base = XEXP (src, 0);
3287 int reg_dest = true_regnum (dest);
3288 int reg_base = true_regnum (base);
3289 /* "volatile" forces reading low byte first, even if less efficient,
3290 for correct operation with 16-bit I/O registers. */
3291 int mem_volatile_p = MEM_VOLATILE_P (src);
3293 if (reg_base > 0)
3295 if (reg_dest == reg_base) /* R = (R) */
3296 return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
3297 "ld %B0,%1" CR_TAB
3298 "mov %A0,__tmp_reg__", op, plen, -3);
3300 if (reg_base != REG_X)
3301 return avr_asm_len ("ld %A0,%1" CR_TAB
3302 "ldd %B0,%1+1", op, plen, -2);
3304 avr_asm_len ("ld %A0,X+" CR_TAB
3305 "ld %B0,X", op, plen, -2);
3307 if (!reg_unused_after (insn, base))
3308 avr_asm_len ("sbiw r26,1", op, plen, 1);
3310 return "";
3312 else if (GET_CODE (base) == PLUS) /* (R + i) */
3314 int disp = INTVAL (XEXP (base, 1));
3315 int reg_base = true_regnum (XEXP (base, 0));
3317 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3319 if (REGNO (XEXP (base, 0)) != REG_Y)
3320 fatal_insn ("incorrect insn:",insn);
3322 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (src))
3323 ? avr_asm_len ("adiw r28,%o1-62" CR_TAB
3324 "ldd %A0,Y+62" CR_TAB
3325 "ldd %B0,Y+63" CR_TAB
3326 "sbiw r28,%o1-62", op, plen, -4)
3328 : avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
3329 "sbci r29,hi8(-%o1)" CR_TAB
3330 "ld %A0,Y" CR_TAB
3331 "ldd %B0,Y+1" CR_TAB
3332 "subi r28,lo8(%o1)" CR_TAB
3333 "sbci r29,hi8(%o1)", op, plen, -6);
3336 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
3337 it but I have this situation with extremal
3338 optimization options. */
3340 if (reg_base == REG_X)
3341 return reg_base == reg_dest
3342 ? avr_asm_len ("adiw r26,%o1" CR_TAB
3343 "ld __tmp_reg__,X+" CR_TAB
3344 "ld %B0,X" CR_TAB
3345 "mov %A0,__tmp_reg__", op, plen, -4)
3347 : avr_asm_len ("adiw r26,%o1" CR_TAB
3348 "ld %A0,X+" CR_TAB
3349 "ld %B0,X" CR_TAB
3350 "sbiw r26,%o1+1", op, plen, -4);
3352 return reg_base == reg_dest
3353 ? avr_asm_len ("ldd __tmp_reg__,%A1" CR_TAB
3354 "ldd %B0,%B1" CR_TAB
3355 "mov %A0,__tmp_reg__", op, plen, -3)
3357 : avr_asm_len ("ldd %A0,%A1" CR_TAB
3358 "ldd %B0,%B1", op, plen, -2);
3360 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3362 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3363 fatal_insn ("incorrect insn:", insn);
3365 if (!mem_volatile_p)
3366 return avr_asm_len ("ld %B0,%1" CR_TAB
3367 "ld %A0,%1", op, plen, -2);
3369 return REGNO (XEXP (base, 0)) == REG_X
3370 ? avr_asm_len ("sbiw r26,2" CR_TAB
3371 "ld %A0,X+" CR_TAB
3372 "ld %B0,X" CR_TAB
3373 "sbiw r26,1", op, plen, -4)
3375 : avr_asm_len ("sbiw %r1,2" CR_TAB
3376 "ld %A0,%p1" CR_TAB
3377 "ldd %B0,%p1+1", op, plen, -3);
3379 else if (GET_CODE (base) == POST_INC) /* (R++) */
3381 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3382 fatal_insn ("incorrect insn:", insn);
3384 return avr_asm_len ("ld %A0,%1" CR_TAB
3385 "ld %B0,%1", op, plen, -2);
3387 else if (CONSTANT_ADDRESS_P (base))
3389 return optimize > 0 && io_address_operand (base, HImode)
3390 ? avr_asm_len ("in %A0,%i1" CR_TAB
3391 "in %B0,%i1+1", op, plen, -2)
3393 : avr_asm_len ("lds %A0,%m1" CR_TAB
3394 "lds %B0,%m1+1", op, plen, -4);
3397 fatal_insn ("unknown move insn:",insn);
3398 return "";
3401 static const char*
3402 out_movsi_r_mr (rtx insn, rtx op[], int *l)
3404 rtx dest = op[0];
3405 rtx src = op[1];
3406 rtx base = XEXP (src, 0);
3407 int reg_dest = true_regnum (dest);
3408 int reg_base = true_regnum (base);
3409 int tmp;
3411 if (!l)
3412 l = &tmp;
3414 if (reg_base > 0)
3416 if (reg_base == REG_X) /* (R26) */
3418 if (reg_dest == REG_X)
3419 /* "ld r26,-X" is undefined */
3420 return *l=7, ("adiw r26,3" CR_TAB
3421 "ld r29,X" CR_TAB
3422 "ld r28,-X" CR_TAB
3423 "ld __tmp_reg__,-X" CR_TAB
3424 "sbiw r26,1" CR_TAB
3425 "ld r26,X" CR_TAB
3426 "mov r27,__tmp_reg__");
3427 else if (reg_dest == REG_X - 2)
3428 return *l=5, ("ld %A0,X+" CR_TAB
3429 "ld %B0,X+" CR_TAB
3430 "ld __tmp_reg__,X+" CR_TAB
3431 "ld %D0,X" CR_TAB
3432 "mov %C0,__tmp_reg__");
3433 else if (reg_unused_after (insn, base))
3434 return *l=4, ("ld %A0,X+" CR_TAB
3435 "ld %B0,X+" CR_TAB
3436 "ld %C0,X+" CR_TAB
3437 "ld %D0,X");
3438 else
3439 return *l=5, ("ld %A0,X+" CR_TAB
3440 "ld %B0,X+" CR_TAB
3441 "ld %C0,X+" CR_TAB
3442 "ld %D0,X" CR_TAB
3443 "sbiw r26,3");
3445 else
3447 if (reg_dest == reg_base)
3448 return *l=5, ("ldd %D0,%1+3" CR_TAB
3449 "ldd %C0,%1+2" CR_TAB
3450 "ldd __tmp_reg__,%1+1" CR_TAB
3451 "ld %A0,%1" CR_TAB
3452 "mov %B0,__tmp_reg__");
3453 else if (reg_base == reg_dest + 2)
3454 return *l=5, ("ld %A0,%1" CR_TAB
3455 "ldd %B0,%1+1" CR_TAB
3456 "ldd __tmp_reg__,%1+2" CR_TAB
3457 "ldd %D0,%1+3" CR_TAB
3458 "mov %C0,__tmp_reg__");
3459 else
3460 return *l=4, ("ld %A0,%1" CR_TAB
3461 "ldd %B0,%1+1" CR_TAB
3462 "ldd %C0,%1+2" CR_TAB
3463 "ldd %D0,%1+3");
3466 else if (GET_CODE (base) == PLUS) /* (R + i) */
3468 int disp = INTVAL (XEXP (base, 1));
3470 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3472 if (REGNO (XEXP (base, 0)) != REG_Y)
3473 fatal_insn ("incorrect insn:",insn);
3475 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
3476 return *l = 6, ("adiw r28,%o1-60" CR_TAB
3477 "ldd %A0,Y+60" CR_TAB
3478 "ldd %B0,Y+61" CR_TAB
3479 "ldd %C0,Y+62" CR_TAB
3480 "ldd %D0,Y+63" CR_TAB
3481 "sbiw r28,%o1-60");
3483 return *l = 8, ("subi r28,lo8(-%o1)" CR_TAB
3484 "sbci r29,hi8(-%o1)" CR_TAB
3485 "ld %A0,Y" CR_TAB
3486 "ldd %B0,Y+1" CR_TAB
3487 "ldd %C0,Y+2" CR_TAB
3488 "ldd %D0,Y+3" CR_TAB
3489 "subi r28,lo8(%o1)" CR_TAB
3490 "sbci r29,hi8(%o1)");
3493 reg_base = true_regnum (XEXP (base, 0));
3494 if (reg_base == REG_X)
3496 /* R = (X + d) */
3497 if (reg_dest == REG_X)
3499 *l = 7;
3500 /* "ld r26,-X" is undefined */
3501 return ("adiw r26,%o1+3" CR_TAB
3502 "ld r29,X" CR_TAB
3503 "ld r28,-X" CR_TAB
3504 "ld __tmp_reg__,-X" CR_TAB
3505 "sbiw r26,1" CR_TAB
3506 "ld r26,X" CR_TAB
3507 "mov r27,__tmp_reg__");
3509 *l = 6;
3510 if (reg_dest == REG_X - 2)
3511 return ("adiw r26,%o1" CR_TAB
3512 "ld r24,X+" CR_TAB
3513 "ld r25,X+" CR_TAB
3514 "ld __tmp_reg__,X+" CR_TAB
3515 "ld r27,X" CR_TAB
3516 "mov r26,__tmp_reg__");
3518 return ("adiw r26,%o1" CR_TAB
3519 "ld %A0,X+" CR_TAB
3520 "ld %B0,X+" CR_TAB
3521 "ld %C0,X+" CR_TAB
3522 "ld %D0,X" CR_TAB
3523 "sbiw r26,%o1+3");
3525 if (reg_dest == reg_base)
3526 return *l=5, ("ldd %D0,%D1" CR_TAB
3527 "ldd %C0,%C1" CR_TAB
3528 "ldd __tmp_reg__,%B1" CR_TAB
3529 "ldd %A0,%A1" CR_TAB
3530 "mov %B0,__tmp_reg__");
3531 else if (reg_dest == reg_base - 2)
3532 return *l=5, ("ldd %A0,%A1" CR_TAB
3533 "ldd %B0,%B1" CR_TAB
3534 "ldd __tmp_reg__,%C1" CR_TAB
3535 "ldd %D0,%D1" CR_TAB
3536 "mov %C0,__tmp_reg__");
3537 return *l=4, ("ldd %A0,%A1" CR_TAB
3538 "ldd %B0,%B1" CR_TAB
3539 "ldd %C0,%C1" CR_TAB
3540 "ldd %D0,%D1");
3542 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3543 return *l=4, ("ld %D0,%1" CR_TAB
3544 "ld %C0,%1" CR_TAB
3545 "ld %B0,%1" CR_TAB
3546 "ld %A0,%1");
3547 else if (GET_CODE (base) == POST_INC) /* (R++) */
3548 return *l=4, ("ld %A0,%1" CR_TAB
3549 "ld %B0,%1" CR_TAB
3550 "ld %C0,%1" CR_TAB
3551 "ld %D0,%1");
3552 else if (CONSTANT_ADDRESS_P (base))
3553 return *l=8, ("lds %A0,%m1" CR_TAB
3554 "lds %B0,%m1+1" CR_TAB
3555 "lds %C0,%m1+2" CR_TAB
3556 "lds %D0,%m1+3");
3558 fatal_insn ("unknown move insn:",insn);
3559 return "";
3562 static const char*
3563 out_movsi_mr_r (rtx insn, rtx op[], int *l)
3565 rtx dest = op[0];
3566 rtx src = op[1];
3567 rtx base = XEXP (dest, 0);
3568 int reg_base = true_regnum (base);
3569 int reg_src = true_regnum (src);
3570 int tmp;
3572 if (!l)
3573 l = &tmp;
3575 if (CONSTANT_ADDRESS_P (base))
3576 return *l=8,("sts %m0,%A1" CR_TAB
3577 "sts %m0+1,%B1" CR_TAB
3578 "sts %m0+2,%C1" CR_TAB
3579 "sts %m0+3,%D1");
3580 if (reg_base > 0) /* (r) */
3582 if (reg_base == REG_X) /* (R26) */
3584 if (reg_src == REG_X)
3586 /* "st X+,r26" is undefined */
3587 if (reg_unused_after (insn, base))
3588 return *l=6, ("mov __tmp_reg__,r27" CR_TAB
3589 "st X,r26" CR_TAB
3590 "adiw r26,1" CR_TAB
3591 "st X+,__tmp_reg__" CR_TAB
3592 "st X+,r28" CR_TAB
3593 "st X,r29");
3594 else
3595 return *l=7, ("mov __tmp_reg__,r27" CR_TAB
3596 "st X,r26" CR_TAB
3597 "adiw r26,1" CR_TAB
3598 "st X+,__tmp_reg__" CR_TAB
3599 "st X+,r28" CR_TAB
3600 "st X,r29" CR_TAB
3601 "sbiw r26,3");
3603 else if (reg_base == reg_src + 2)
3605 if (reg_unused_after (insn, base))
3606 return *l=7, ("mov __zero_reg__,%C1" CR_TAB
3607 "mov __tmp_reg__,%D1" CR_TAB
3608 "st %0+,%A1" CR_TAB
3609 "st %0+,%B1" CR_TAB
3610 "st %0+,__zero_reg__" CR_TAB
3611 "st %0,__tmp_reg__" CR_TAB
3612 "clr __zero_reg__");
3613 else
3614 return *l=8, ("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__" CR_TAB
3621 "sbiw r26,3");
3623 return *l=5, ("st %0+,%A1" CR_TAB
3624 "st %0+,%B1" CR_TAB
3625 "st %0+,%C1" CR_TAB
3626 "st %0,%D1" CR_TAB
3627 "sbiw r26,3");
3629 else
3630 return *l=4, ("st %0,%A1" CR_TAB
3631 "std %0+1,%B1" CR_TAB
3632 "std %0+2,%C1" CR_TAB
3633 "std %0+3,%D1");
3635 else if (GET_CODE (base) == PLUS) /* (R + i) */
3637 int disp = INTVAL (XEXP (base, 1));
3638 reg_base = REGNO (XEXP (base, 0));
3639 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
3641 if (reg_base != REG_Y)
3642 fatal_insn ("incorrect insn:",insn);
3644 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
3645 return *l = 6, ("adiw r28,%o0-60" CR_TAB
3646 "std Y+60,%A1" CR_TAB
3647 "std Y+61,%B1" CR_TAB
3648 "std Y+62,%C1" CR_TAB
3649 "std Y+63,%D1" CR_TAB
3650 "sbiw r28,%o0-60");
3652 return *l = 8, ("subi r28,lo8(-%o0)" CR_TAB
3653 "sbci r29,hi8(-%o0)" CR_TAB
3654 "st Y,%A1" CR_TAB
3655 "std Y+1,%B1" CR_TAB
3656 "std Y+2,%C1" CR_TAB
3657 "std Y+3,%D1" CR_TAB
3658 "subi r28,lo8(%o0)" CR_TAB
3659 "sbci r29,hi8(%o0)");
3661 if (reg_base == REG_X)
3663 /* (X + d) = R */
3664 if (reg_src == REG_X)
3666 *l = 9;
3667 return ("mov __tmp_reg__,r26" CR_TAB
3668 "mov __zero_reg__,r27" CR_TAB
3669 "adiw r26,%o0" CR_TAB
3670 "st X+,__tmp_reg__" CR_TAB
3671 "st X+,__zero_reg__" CR_TAB
3672 "st X+,r28" CR_TAB
3673 "st X,r29" CR_TAB
3674 "clr __zero_reg__" CR_TAB
3675 "sbiw r26,%o0+3");
3677 else if (reg_src == REG_X - 2)
3679 *l = 9;
3680 return ("mov __tmp_reg__,r26" CR_TAB
3681 "mov __zero_reg__,r27" CR_TAB
3682 "adiw r26,%o0" CR_TAB
3683 "st X+,r24" CR_TAB
3684 "st X+,r25" CR_TAB
3685 "st X+,__tmp_reg__" CR_TAB
3686 "st X,__zero_reg__" CR_TAB
3687 "clr __zero_reg__" CR_TAB
3688 "sbiw r26,%o0+3");
3690 *l = 6;
3691 return ("adiw r26,%o0" CR_TAB
3692 "st X+,%A1" CR_TAB
3693 "st X+,%B1" CR_TAB
3694 "st X+,%C1" CR_TAB
3695 "st X,%D1" CR_TAB
3696 "sbiw r26,%o0+3");
3698 return *l=4, ("std %A0,%A1" CR_TAB
3699 "std %B0,%B1" CR_TAB
3700 "std %C0,%C1" CR_TAB
3701 "std %D0,%D1");
3703 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3704 return *l=4, ("st %0,%D1" CR_TAB
3705 "st %0,%C1" CR_TAB
3706 "st %0,%B1" CR_TAB
3707 "st %0,%A1");
3708 else if (GET_CODE (base) == POST_INC) /* (R++) */
3709 return *l=4, ("st %0,%A1" CR_TAB
3710 "st %0,%B1" CR_TAB
3711 "st %0,%C1" CR_TAB
3712 "st %0,%D1");
3713 fatal_insn ("unknown move insn:",insn);
3714 return "";
3717 const char *
3718 output_movsisf (rtx insn, rtx operands[], int *l)
3720 int dummy;
3721 rtx dest = operands[0];
3722 rtx src = operands[1];
3723 int *real_l = l;
3725 if (avr_mem_flash_p (src)
3726 || avr_mem_flash_p (dest))
3728 return avr_out_lpm (insn, operands, real_l);
3731 if (!l)
3732 l = &dummy;
3734 gcc_assert (4 == GET_MODE_SIZE (GET_MODE (dest)));
3735 if (REG_P (dest))
3737 if (REG_P (src)) /* mov r,r */
3739 if (true_regnum (dest) > true_regnum (src))
3741 if (AVR_HAVE_MOVW)
3743 *l = 2;
3744 return ("movw %C0,%C1" CR_TAB
3745 "movw %A0,%A1");
3747 *l = 4;
3748 return ("mov %D0,%D1" CR_TAB
3749 "mov %C0,%C1" CR_TAB
3750 "mov %B0,%B1" CR_TAB
3751 "mov %A0,%A1");
3753 else
3755 if (AVR_HAVE_MOVW)
3757 *l = 2;
3758 return ("movw %A0,%A1" CR_TAB
3759 "movw %C0,%C1");
3761 *l = 4;
3762 return ("mov %A0,%A1" CR_TAB
3763 "mov %B0,%B1" CR_TAB
3764 "mov %C0,%C1" CR_TAB
3765 "mov %D0,%D1");
3768 else if (CONSTANT_P (src))
3770 return output_reload_insisf (operands, NULL_RTX, real_l);
3772 else if (MEM_P (src))
3773 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
3775 else if (MEM_P (dest))
3777 const char *templ;
3779 if (src == CONST0_RTX (GET_MODE (dest)))
3780 operands[1] = zero_reg_rtx;
3782 templ = out_movsi_mr_r (insn, operands, real_l);
3784 if (!real_l)
3785 output_asm_insn (templ, operands);
3787 operands[1] = src;
3788 return "";
3790 fatal_insn ("invalid insn:", insn);
3791 return "";
3795 /* Handle loads of 24-bit types from memory to register. */
3797 static const char*
3798 avr_out_load_psi (rtx insn, rtx *op, int *plen)
3800 rtx dest = op[0];
3801 rtx src = op[1];
3802 rtx base = XEXP (src, 0);
3803 int reg_dest = true_regnum (dest);
3804 int reg_base = true_regnum (base);
3806 if (reg_base > 0)
3808 if (reg_base == REG_X) /* (R26) */
3810 if (reg_dest == REG_X)
3811 /* "ld r26,-X" is undefined */
3812 return avr_asm_len ("adiw r26,2" CR_TAB
3813 "ld r28,X" CR_TAB
3814 "ld __tmp_reg__,-X" CR_TAB
3815 "sbiw r26,1" CR_TAB
3816 "ld r26,X" CR_TAB
3817 "mov r27,__tmp_reg__", op, plen, -6);
3818 else
3820 avr_asm_len ("ld %A0,X+" CR_TAB
3821 "ld %B0,X+" CR_TAB
3822 "ld %C0,X", op, plen, -3);
3824 if (reg_dest != REG_X - 2
3825 && !reg_unused_after (insn, base))
3827 avr_asm_len ("sbiw r26,2", op, plen, 1);
3830 return "";
3833 else /* reg_base != REG_X */
3835 if (reg_dest == reg_base)
3836 return avr_asm_len ("ldd %C0,%1+2" CR_TAB
3837 "ldd __tmp_reg__,%1+1" CR_TAB
3838 "ld %A0,%1" CR_TAB
3839 "mov %B0,__tmp_reg__", op, plen, -4);
3840 else
3841 return avr_asm_len ("ld %A0,%1" CR_TAB
3842 "ldd %B0,%1+1" CR_TAB
3843 "ldd %C0,%1+2", op, plen, -3);
3846 else if (GET_CODE (base) == PLUS) /* (R + i) */
3848 int disp = INTVAL (XEXP (base, 1));
3850 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3852 if (REGNO (XEXP (base, 0)) != REG_Y)
3853 fatal_insn ("incorrect insn:",insn);
3855 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
3856 return avr_asm_len ("adiw r28,%o1-61" CR_TAB
3857 "ldd %A0,Y+61" CR_TAB
3858 "ldd %B0,Y+62" CR_TAB
3859 "ldd %C0,Y+63" CR_TAB
3860 "sbiw r28,%o1-61", op, plen, -5);
3862 return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
3863 "sbci r29,hi8(-%o1)" CR_TAB
3864 "ld %A0,Y" CR_TAB
3865 "ldd %B0,Y+1" CR_TAB
3866 "ldd %C0,Y+2" CR_TAB
3867 "subi r28,lo8(%o1)" CR_TAB
3868 "sbci r29,hi8(%o1)", op, plen, -7);
3871 reg_base = true_regnum (XEXP (base, 0));
3872 if (reg_base == REG_X)
3874 /* R = (X + d) */
3875 if (reg_dest == REG_X)
3877 /* "ld r26,-X" is undefined */
3878 return avr_asm_len ("adiw r26,%o1+2" CR_TAB
3879 "ld r28,X" CR_TAB
3880 "ld __tmp_reg__,-X" CR_TAB
3881 "sbiw r26,1" CR_TAB
3882 "ld r26,X" CR_TAB
3883 "mov r27,__tmp_reg__", op, plen, -6);
3886 avr_asm_len ("adiw r26,%o1" CR_TAB
3887 "ld %A0,X+" CR_TAB
3888 "ld %B0,X+" CR_TAB
3889 "ld %C0,X", op, plen, -4);
3891 if (reg_dest != REG_W
3892 && !reg_unused_after (insn, XEXP (base, 0)))
3893 avr_asm_len ("sbiw r26,%o1+2", op, plen, 1);
3895 return "";
3898 if (reg_dest == reg_base)
3899 return avr_asm_len ("ldd %C0,%C1" CR_TAB
3900 "ldd __tmp_reg__,%B1" CR_TAB
3901 "ldd %A0,%A1" CR_TAB
3902 "mov %B0,__tmp_reg__", op, plen, -4);
3904 return avr_asm_len ("ldd %A0,%A1" CR_TAB
3905 "ldd %B0,%B1" CR_TAB
3906 "ldd %C0,%C1", op, plen, -3);
3908 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3909 return avr_asm_len ("ld %C0,%1" CR_TAB
3910 "ld %B0,%1" CR_TAB
3911 "ld %A0,%1", op, plen, -3);
3912 else if (GET_CODE (base) == POST_INC) /* (R++) */
3913 return avr_asm_len ("ld %A0,%1" CR_TAB
3914 "ld %B0,%1" CR_TAB
3915 "ld %C0,%1", op, plen, -3);
3917 else if (CONSTANT_ADDRESS_P (base))
3918 return avr_asm_len ("lds %A0,%m1" CR_TAB
3919 "lds %B0,%m1+1" CR_TAB
3920 "lds %C0,%m1+2", op, plen , -6);
3922 fatal_insn ("unknown move insn:",insn);
3923 return "";
3926 /* Handle store of 24-bit type from register or zero to memory. */
3928 static const char*
3929 avr_out_store_psi (rtx insn, rtx *op, int *plen)
3931 rtx dest = op[0];
3932 rtx src = op[1];
3933 rtx base = XEXP (dest, 0);
3934 int reg_base = true_regnum (base);
3936 if (CONSTANT_ADDRESS_P (base))
3937 return avr_asm_len ("sts %m0,%A1" CR_TAB
3938 "sts %m0+1,%B1" CR_TAB
3939 "sts %m0+2,%C1", op, plen, -6);
3941 if (reg_base > 0) /* (r) */
3943 if (reg_base == REG_X) /* (R26) */
3945 gcc_assert (!reg_overlap_mentioned_p (base, src));
3947 avr_asm_len ("st %0+,%A1" CR_TAB
3948 "st %0+,%B1" CR_TAB
3949 "st %0,%C1", op, plen, -3);
3951 if (!reg_unused_after (insn, base))
3952 avr_asm_len ("sbiw r26,2", op, plen, 1);
3954 return "";
3956 else
3957 return avr_asm_len ("st %0,%A1" CR_TAB
3958 "std %0+1,%B1" CR_TAB
3959 "std %0+2,%C1", op, plen, -3);
3961 else if (GET_CODE (base) == PLUS) /* (R + i) */
3963 int disp = INTVAL (XEXP (base, 1));
3964 reg_base = REGNO (XEXP (base, 0));
3966 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
3968 if (reg_base != REG_Y)
3969 fatal_insn ("incorrect insn:",insn);
3971 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
3972 return avr_asm_len ("adiw r28,%o0-61" CR_TAB
3973 "std Y+61,%A1" CR_TAB
3974 "std Y+62,%B1" CR_TAB
3975 "std Y+63,%C1" CR_TAB
3976 "sbiw r28,%o0-60", op, plen, -5);
3978 return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
3979 "sbci r29,hi8(-%o0)" CR_TAB
3980 "st Y,%A1" CR_TAB
3981 "std Y+1,%B1" CR_TAB
3982 "std Y+2,%C1" CR_TAB
3983 "subi r28,lo8(%o0)" CR_TAB
3984 "sbci r29,hi8(%o0)", op, plen, -7);
3986 if (reg_base == REG_X)
3988 /* (X + d) = R */
3989 gcc_assert (!reg_overlap_mentioned_p (XEXP (base, 0), src));
3991 avr_asm_len ("adiw r26,%o0" CR_TAB
3992 "st X+,%A1" CR_TAB
3993 "st X+,%B1" CR_TAB
3994 "st X,%C1", op, plen, -4);
3996 if (!reg_unused_after (insn, XEXP (base, 0)))
3997 avr_asm_len ("sbiw r26,%o0+2", op, plen, 1);
3999 return "";
4002 return avr_asm_len ("std %A0,%A1" CR_TAB
4003 "std %B0,%B1" CR_TAB
4004 "std %C0,%C1", op, plen, -3);
4006 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4007 return avr_asm_len ("st %0,%C1" CR_TAB
4008 "st %0,%B1" CR_TAB
4009 "st %0,%A1", op, plen, -3);
4010 else if (GET_CODE (base) == POST_INC) /* (R++) */
4011 return avr_asm_len ("st %0,%A1" CR_TAB
4012 "st %0,%B1" CR_TAB
4013 "st %0,%C1", op, plen, -3);
4015 fatal_insn ("unknown move insn:",insn);
4016 return "";
4020 /* Move around 24-bit stuff. */
4022 const char *
4023 avr_out_movpsi (rtx insn, rtx *op, int *plen)
4025 rtx dest = op[0];
4026 rtx src = op[1];
4028 if (avr_mem_flash_p (src)
4029 || avr_mem_flash_p (dest))
4031 return avr_out_lpm (insn, op, plen);
4034 if (register_operand (dest, VOIDmode))
4036 if (register_operand (src, VOIDmode)) /* mov r,r */
4038 if (true_regnum (dest) > true_regnum (src))
4040 avr_asm_len ("mov %C0,%C1", op, plen, -1);
4042 if (AVR_HAVE_MOVW)
4043 return avr_asm_len ("movw %A0,%A1", op, plen, 1);
4044 else
4045 return avr_asm_len ("mov %B0,%B1" CR_TAB
4046 "mov %A0,%A1", op, plen, 2);
4048 else
4050 if (AVR_HAVE_MOVW)
4051 avr_asm_len ("movw %A0,%A1", op, plen, -1);
4052 else
4053 avr_asm_len ("mov %A0,%A1" CR_TAB
4054 "mov %B0,%B1", op, plen, -2);
4056 return avr_asm_len ("mov %C0,%C1", op, plen, 1);
4059 else if (CONSTANT_P (src))
4061 return avr_out_reload_inpsi (op, NULL_RTX, plen);
4063 else if (MEM_P (src))
4064 return avr_out_load_psi (insn, op, plen); /* mov r,m */
4066 else if (MEM_P (dest))
4068 rtx xop[2];
4070 xop[0] = dest;
4071 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
4073 return avr_out_store_psi (insn, xop, plen);
4076 fatal_insn ("invalid insn:", insn);
4077 return "";
4081 static const char*
4082 out_movqi_mr_r (rtx insn, rtx op[], int *plen)
4084 rtx dest = op[0];
4085 rtx src = op[1];
4086 rtx x = XEXP (dest, 0);
4088 if (CONSTANT_ADDRESS_P (x))
4090 return optimize > 0 && io_address_operand (x, QImode)
4091 ? avr_asm_len ("out %i0,%1", op, plen, -1)
4092 : avr_asm_len ("sts %m0,%1", op, plen, -2);
4094 else if (GET_CODE (x) == PLUS
4095 && REG_P (XEXP (x, 0))
4096 && CONST_INT_P (XEXP (x, 1)))
4098 /* memory access by reg+disp */
4100 int disp = INTVAL (XEXP (x, 1));
4102 if (disp - GET_MODE_SIZE (GET_MODE (dest)) >= 63)
4104 if (REGNO (XEXP (x, 0)) != REG_Y)
4105 fatal_insn ("incorrect insn:",insn);
4107 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
4108 return avr_asm_len ("adiw r28,%o0-63" CR_TAB
4109 "std Y+63,%1" CR_TAB
4110 "sbiw r28,%o0-63", op, plen, -3);
4112 return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
4113 "sbci r29,hi8(-%o0)" CR_TAB
4114 "st Y,%1" CR_TAB
4115 "subi r28,lo8(%o0)" CR_TAB
4116 "sbci r29,hi8(%o0)", op, plen, -5);
4118 else if (REGNO (XEXP (x,0)) == REG_X)
4120 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
4122 avr_asm_len ("mov __tmp_reg__,%1" CR_TAB
4123 "adiw r26,%o0" CR_TAB
4124 "st X,__tmp_reg__", op, plen, -3);
4126 else
4128 avr_asm_len ("adiw r26,%o0" CR_TAB
4129 "st X,%1", op, plen, -2);
4132 if (!reg_unused_after (insn, XEXP (x,0)))
4133 avr_asm_len ("sbiw r26,%o0", op, plen, 1);
4135 return "";
4138 return avr_asm_len ("std %0,%1", op, plen, -1);
4141 return avr_asm_len ("st %0,%1", op, plen, -1);
4145 /* Helper for the next function for XMEGA. It does the same
4146 but with low byte first. */
4148 static const char*
4149 avr_out_movhi_mr_r_xmega (rtx insn, rtx op[], int *plen)
4151 rtx dest = op[0];
4152 rtx src = op[1];
4153 rtx base = XEXP (dest, 0);
4154 int reg_base = true_regnum (base);
4155 int reg_src = true_regnum (src);
4157 /* "volatile" forces writing low byte first, even if less efficient,
4158 for correct operation with 16-bit I/O registers like SP. */
4159 int mem_volatile_p = MEM_VOLATILE_P (dest);
4161 if (CONSTANT_ADDRESS_P (base))
4162 return optimize > 0 && io_address_operand (base, HImode)
4163 ? avr_asm_len ("out %i0,%A1" CR_TAB
4164 "out %i0+1,%B1", op, plen, -2)
4166 : avr_asm_len ("sts %m0,%A1" CR_TAB
4167 "sts %m0+1,%B1", op, plen, -4);
4169 if (reg_base > 0)
4171 if (reg_base != REG_X)
4172 return avr_asm_len ("st %0,%A1" CR_TAB
4173 "std %0+1,%B1", op, plen, -2);
4175 if (reg_src == REG_X)
4176 /* "st X+,r26" and "st -X,r26" are undefined. */
4177 avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
4178 "st X,r26" CR_TAB
4179 "adiw r26,1" CR_TAB
4180 "st X,__tmp_reg__", op, plen, -4);
4181 else
4182 avr_asm_len ("st X+,%A1" CR_TAB
4183 "st X,%B1", op, plen, -2);
4185 return reg_unused_after (insn, base)
4186 ? ""
4187 : avr_asm_len ("sbiw r26,1", op, plen, 1);
4189 else if (GET_CODE (base) == PLUS)
4191 int disp = INTVAL (XEXP (base, 1));
4192 reg_base = REGNO (XEXP (base, 0));
4193 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
4195 if (reg_base != REG_Y)
4196 fatal_insn ("incorrect insn:",insn);
4198 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))
4199 ? avr_asm_len ("adiw r28,%o0-62" CR_TAB
4200 "std Y+62,%A1" CR_TAB
4201 "std Y+63,%B1" CR_TAB
4202 "sbiw r28,%o0-62", op, plen, -4)
4204 : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
4205 "sbci r29,hi8(-%o0)" CR_TAB
4206 "st Y,%A1" CR_TAB
4207 "std Y+1,%B1" CR_TAB
4208 "subi r28,lo8(%o0)" CR_TAB
4209 "sbci r29,hi8(%o0)", op, plen, -6);
4212 if (reg_base != REG_X)
4213 return avr_asm_len ("std %A0,%A1" CR_TAB
4214 "std %B0,%B1", op, plen, -2);
4215 /* (X + d) = R */
4216 return reg_src == REG_X
4217 ? avr_asm_len ("mov __tmp_reg__,r26" CR_TAB
4218 "mov __zero_reg__,r27" CR_TAB
4219 "adiw r26,%o0" CR_TAB
4220 "st X+,__tmp_reg__" CR_TAB
4221 "st X,__zero_reg__" CR_TAB
4222 "clr __zero_reg__" CR_TAB
4223 "sbiw r26,%o0+1", op, plen, -7)
4225 : avr_asm_len ("adiw r26,%o0" CR_TAB
4226 "st X+,%A1" CR_TAB
4227 "st X,%B1" CR_TAB
4228 "sbiw r26,%o0+1", op, plen, -4);
4230 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4232 if (!mem_volatile_p)
4233 return avr_asm_len ("st %0,%B1" CR_TAB
4234 "st %0,%A1", op, plen, -2);
4236 return REGNO (XEXP (base, 0)) == REG_X
4237 ? avr_asm_len ("sbiw r26,2" CR_TAB
4238 "st X+,%A1" CR_TAB
4239 "st X,%B1" CR_TAB
4240 "sbiw r26,1", op, plen, -4)
4242 : avr_asm_len ("sbiw %r0,2" CR_TAB
4243 "st %p0,%A1" CR_TAB
4244 "std %p0+1,%B1", op, plen, -3);
4246 else if (GET_CODE (base) == POST_INC) /* (R++) */
4248 return avr_asm_len ("st %0,%A1" CR_TAB
4249 "st %0,%B1", op, plen, -2);
4252 fatal_insn ("unknown move insn:",insn);
4253 return "";
4257 static const char*
4258 out_movhi_mr_r (rtx insn, rtx op[], int *plen)
4260 rtx dest = op[0];
4261 rtx src = op[1];
4262 rtx base = XEXP (dest, 0);
4263 int reg_base = true_regnum (base);
4264 int reg_src = true_regnum (src);
4265 int mem_volatile_p;
4267 /* "volatile" forces writing high-byte first (no-xmega) resp.
4268 low-byte first (xmega) even if less efficient, for correct
4269 operation with 16-bit I/O registers like. */
4271 if (AVR_XMEGA)
4272 return avr_out_movhi_mr_r_xmega (insn, op, plen);
4274 mem_volatile_p = MEM_VOLATILE_P (dest);
4276 if (CONSTANT_ADDRESS_P (base))
4277 return optimize > 0 && io_address_operand (base, HImode)
4278 ? avr_asm_len ("out %i0+1,%B1" CR_TAB
4279 "out %i0,%A1", op, plen, -2)
4281 : avr_asm_len ("sts %m0+1,%B1" CR_TAB
4282 "sts %m0,%A1", op, plen, -4);
4284 if (reg_base > 0)
4286 if (reg_base != REG_X)
4287 return avr_asm_len ("std %0+1,%B1" CR_TAB
4288 "st %0,%A1", op, plen, -2);
4290 if (reg_src == REG_X)
4291 /* "st X+,r26" and "st -X,r26" are undefined. */
4292 return !mem_volatile_p && reg_unused_after (insn, src)
4293 ? avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
4294 "st X,r26" CR_TAB
4295 "adiw r26,1" CR_TAB
4296 "st X,__tmp_reg__", op, plen, -4)
4298 : avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
4299 "adiw r26,1" CR_TAB
4300 "st X,__tmp_reg__" CR_TAB
4301 "sbiw r26,1" CR_TAB
4302 "st X,r26", op, plen, -5);
4304 return !mem_volatile_p && reg_unused_after (insn, base)
4305 ? avr_asm_len ("st X+,%A1" CR_TAB
4306 "st X,%B1", op, plen, -2)
4307 : avr_asm_len ("adiw r26,1" CR_TAB
4308 "st X,%B1" CR_TAB
4309 "st -X,%A1", op, plen, -3);
4311 else if (GET_CODE (base) == PLUS)
4313 int disp = INTVAL (XEXP (base, 1));
4314 reg_base = REGNO (XEXP (base, 0));
4315 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
4317 if (reg_base != REG_Y)
4318 fatal_insn ("incorrect insn:",insn);
4320 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))
4321 ? avr_asm_len ("adiw r28,%o0-62" CR_TAB
4322 "std Y+63,%B1" CR_TAB
4323 "std Y+62,%A1" CR_TAB
4324 "sbiw r28,%o0-62", op, plen, -4)
4326 : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
4327 "sbci r29,hi8(-%o0)" CR_TAB
4328 "std Y+1,%B1" CR_TAB
4329 "st Y,%A1" CR_TAB
4330 "subi r28,lo8(%o0)" CR_TAB
4331 "sbci r29,hi8(%o0)", op, plen, -6);
4334 if (reg_base != REG_X)
4335 return avr_asm_len ("std %B0,%B1" CR_TAB
4336 "std %A0,%A1", op, plen, -2);
4337 /* (X + d) = R */
4338 return reg_src == REG_X
4339 ? avr_asm_len ("mov __tmp_reg__,r26" CR_TAB
4340 "mov __zero_reg__,r27" CR_TAB
4341 "adiw r26,%o0+1" CR_TAB
4342 "st X,__zero_reg__" CR_TAB
4343 "st -X,__tmp_reg__" CR_TAB
4344 "clr __zero_reg__" CR_TAB
4345 "sbiw r26,%o0", op, plen, -7)
4347 : avr_asm_len ("adiw r26,%o0+1" CR_TAB
4348 "st X,%B1" CR_TAB
4349 "st -X,%A1" CR_TAB
4350 "sbiw r26,%o0", op, plen, -4);
4352 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4354 return avr_asm_len ("st %0,%B1" CR_TAB
4355 "st %0,%A1", op, plen, -2);
4357 else if (GET_CODE (base) == POST_INC) /* (R++) */
4359 if (!mem_volatile_p)
4360 return avr_asm_len ("st %0,%A1" CR_TAB
4361 "st %0,%B1", op, plen, -2);
4363 return REGNO (XEXP (base, 0)) == REG_X
4364 ? avr_asm_len ("adiw r26,1" CR_TAB
4365 "st X,%B1" CR_TAB
4366 "st -X,%A1" CR_TAB
4367 "adiw r26,2", op, plen, -4)
4369 : avr_asm_len ("std %p0+1,%B1" CR_TAB
4370 "st %p0,%A1" CR_TAB
4371 "adiw %r0,2", op, plen, -3);
4373 fatal_insn ("unknown move insn:",insn);
4374 return "";
4377 /* Return 1 if frame pointer for current function required. */
4379 static bool
4380 avr_frame_pointer_required_p (void)
4382 return (cfun->calls_alloca
4383 || cfun->calls_setjmp
4384 || cfun->has_nonlocal_label
4385 || crtl->args.info.nregs == 0
4386 || get_frame_size () > 0);
4389 /* Returns the condition of compare insn INSN, or UNKNOWN. */
4391 static RTX_CODE
4392 compare_condition (rtx insn)
4394 rtx next = next_real_insn (insn);
4396 if (next && JUMP_P (next))
4398 rtx pat = PATTERN (next);
4399 rtx src = SET_SRC (pat);
4401 if (IF_THEN_ELSE == GET_CODE (src))
4402 return GET_CODE (XEXP (src, 0));
4405 return UNKNOWN;
4409 /* Returns true iff INSN is a tst insn that only tests the sign. */
4411 static bool
4412 compare_sign_p (rtx insn)
4414 RTX_CODE cond = compare_condition (insn);
4415 return (cond == GE || cond == LT);
4419 /* Returns true iff the next insn is a JUMP_INSN with a condition
4420 that needs to be swapped (GT, GTU, LE, LEU). */
4422 static bool
4423 compare_diff_p (rtx insn)
4425 RTX_CODE cond = compare_condition (insn);
4426 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
4429 /* Returns true iff INSN is a compare insn with the EQ or NE condition. */
4431 static bool
4432 compare_eq_p (rtx insn)
4434 RTX_CODE cond = compare_condition (insn);
4435 return (cond == EQ || cond == NE);
4439 /* Output compare instruction
4441 compare (XOP[0], XOP[1])
4443 for a register XOP[0] and a compile-time constant XOP[1]. Return "".
4444 XOP[2] is an 8-bit scratch register as needed.
4446 PLEN == NULL: Output instructions.
4447 PLEN != NULL: Set *PLEN to the length (in words) of the sequence.
4448 Don't output anything. */
4450 const char*
4451 avr_out_compare (rtx insn, rtx *xop, int *plen)
4453 /* Register to compare and value to compare against. */
4454 rtx xreg = xop[0];
4455 rtx xval = xop[1];
4457 /* MODE of the comparison. */
4458 enum machine_mode mode;
4460 /* Number of bytes to operate on. */
4461 int i, n_bytes = GET_MODE_SIZE (GET_MODE (xreg));
4463 /* Value (0..0xff) held in clobber register xop[2] or -1 if unknown. */
4464 int clobber_val = -1;
4466 /* Map fixed mode operands to integer operands with the same binary
4467 representation. They are easier to handle in the remainder. */
4469 if (CONST_FIXED_P (xval))
4471 xreg = avr_to_int_mode (xop[0]);
4472 xval = avr_to_int_mode (xop[1]);
4475 mode = GET_MODE (xreg);
4477 gcc_assert (REG_P (xreg));
4478 gcc_assert ((CONST_INT_P (xval) && n_bytes <= 4)
4479 || (const_double_operand (xval, VOIDmode) && n_bytes == 8));
4481 if (plen)
4482 *plen = 0;
4484 /* Comparisons == +/-1 and != +/-1 can be done similar to camparing
4485 against 0 by ORing the bytes. This is one instruction shorter.
4486 Notice that 64-bit comparisons are always against reg:ALL8 18 (ACC_A)
4487 and therefore don't use this. */
4489 if (!test_hard_reg_class (LD_REGS, xreg)
4490 && compare_eq_p (insn)
4491 && reg_unused_after (insn, xreg))
4493 if (xval == const1_rtx)
4495 avr_asm_len ("dec %A0" CR_TAB
4496 "or %A0,%B0", xop, plen, 2);
4498 if (n_bytes >= 3)
4499 avr_asm_len ("or %A0,%C0", xop, plen, 1);
4501 if (n_bytes >= 4)
4502 avr_asm_len ("or %A0,%D0", xop, plen, 1);
4504 return "";
4506 else if (xval == constm1_rtx)
4508 if (n_bytes >= 4)
4509 avr_asm_len ("and %A0,%D0", xop, plen, 1);
4511 if (n_bytes >= 3)
4512 avr_asm_len ("and %A0,%C0", xop, plen, 1);
4514 return avr_asm_len ("and %A0,%B0" CR_TAB
4515 "com %A0", xop, plen, 2);
4519 for (i = 0; i < n_bytes; i++)
4521 /* We compare byte-wise. */
4522 rtx reg8 = simplify_gen_subreg (QImode, xreg, mode, i);
4523 rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
4525 /* 8-bit value to compare with this byte. */
4526 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
4528 /* Registers R16..R31 can operate with immediate. */
4529 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
4531 xop[0] = reg8;
4532 xop[1] = gen_int_mode (val8, QImode);
4534 /* Word registers >= R24 can use SBIW/ADIW with 0..63. */
4536 if (i == 0
4537 && test_hard_reg_class (ADDW_REGS, reg8))
4539 int val16 = trunc_int_for_mode (INTVAL (xval), HImode);
4541 if (IN_RANGE (val16, 0, 63)
4542 && (val8 == 0
4543 || reg_unused_after (insn, xreg)))
4545 avr_asm_len ("sbiw %0,%1", xop, plen, 1);
4546 i++;
4547 continue;
4550 if (n_bytes == 2
4551 && IN_RANGE (val16, -63, -1)
4552 && compare_eq_p (insn)
4553 && reg_unused_after (insn, xreg))
4555 return avr_asm_len ("adiw %0,%n1", xop, plen, 1);
4559 /* Comparing against 0 is easy. */
4561 if (val8 == 0)
4563 avr_asm_len (i == 0
4564 ? "cp %0,__zero_reg__"
4565 : "cpc %0,__zero_reg__", xop, plen, 1);
4566 continue;
4569 /* Upper registers can compare and subtract-with-carry immediates.
4570 Notice that compare instructions do the same as respective subtract
4571 instruction; the only difference is that comparisons don't write
4572 the result back to the target register. */
4574 if (ld_reg_p)
4576 if (i == 0)
4578 avr_asm_len ("cpi %0,%1", xop, plen, 1);
4579 continue;
4581 else if (reg_unused_after (insn, xreg))
4583 avr_asm_len ("sbci %0,%1", xop, plen, 1);
4584 continue;
4588 /* Must load the value into the scratch register. */
4590 gcc_assert (REG_P (xop[2]));
4592 if (clobber_val != (int) val8)
4593 avr_asm_len ("ldi %2,%1", xop, plen, 1);
4594 clobber_val = (int) val8;
4596 avr_asm_len (i == 0
4597 ? "cp %0,%2"
4598 : "cpc %0,%2", xop, plen, 1);
4601 return "";
4605 /* Prepare operands of compare_const_di2 to be used with avr_out_compare. */
4607 const char*
4608 avr_out_compare64 (rtx insn, rtx *op, int *plen)
4610 rtx xop[3];
4612 xop[0] = gen_rtx_REG (DImode, 18);
4613 xop[1] = op[0];
4614 xop[2] = op[1];
4616 return avr_out_compare (insn, xop, plen);
4619 /* Output test instruction for HImode. */
4621 const char*
4622 avr_out_tsthi (rtx insn, rtx *op, int *plen)
4624 if (compare_sign_p (insn))
4626 avr_asm_len ("tst %B0", op, plen, -1);
4628 else if (reg_unused_after (insn, op[0])
4629 && compare_eq_p (insn))
4631 /* Faster than sbiw if we can clobber the operand. */
4632 avr_asm_len ("or %A0,%B0", op, plen, -1);
4634 else
4636 avr_out_compare (insn, op, plen);
4639 return "";
4643 /* Output test instruction for PSImode. */
4645 const char*
4646 avr_out_tstpsi (rtx insn, rtx *op, int *plen)
4648 if (compare_sign_p (insn))
4650 avr_asm_len ("tst %C0", op, plen, -1);
4652 else if (reg_unused_after (insn, op[0])
4653 && compare_eq_p (insn))
4655 /* Faster than sbiw if we can clobber the operand. */
4656 avr_asm_len ("or %A0,%B0" CR_TAB
4657 "or %A0,%C0", op, plen, -2);
4659 else
4661 avr_out_compare (insn, op, plen);
4664 return "";
4668 /* Output test instruction for SImode. */
4670 const char*
4671 avr_out_tstsi (rtx insn, rtx *op, int *plen)
4673 if (compare_sign_p (insn))
4675 avr_asm_len ("tst %D0", op, plen, -1);
4677 else if (reg_unused_after (insn, op[0])
4678 && compare_eq_p (insn))
4680 /* Faster than sbiw if we can clobber the operand. */
4681 avr_asm_len ("or %A0,%B0" CR_TAB
4682 "or %A0,%C0" CR_TAB
4683 "or %A0,%D0", op, plen, -3);
4685 else
4687 avr_out_compare (insn, op, plen);
4690 return "";
4694 /* Generate asm equivalent for various shifts. This only handles cases
4695 that are not already carefully hand-optimized in ?sh??i3_out.
4697 OPERANDS[0] resp. %0 in TEMPL is the operand to be shifted.
4698 OPERANDS[2] is the shift count as CONST_INT, MEM or REG.
4699 OPERANDS[3] is a QImode scratch register from LD regs if
4700 available and SCRATCH, otherwise (no scratch available)
4702 TEMPL is an assembler template that shifts by one position.
4703 T_LEN is the length of this template. */
4705 void
4706 out_shift_with_cnt (const char *templ, rtx insn, rtx operands[],
4707 int *plen, int t_len)
4709 bool second_label = true;
4710 bool saved_in_tmp = false;
4711 bool use_zero_reg = false;
4712 rtx op[5];
4714 op[0] = operands[0];
4715 op[1] = operands[1];
4716 op[2] = operands[2];
4717 op[3] = operands[3];
4719 if (plen)
4720 *plen = 0;
4722 if (CONST_INT_P (operands[2]))
4724 bool scratch = (GET_CODE (PATTERN (insn)) == PARALLEL
4725 && REG_P (operands[3]));
4726 int count = INTVAL (operands[2]);
4727 int max_len = 10; /* If larger than this, always use a loop. */
4729 if (count <= 0)
4730 return;
4732 if (count < 8 && !scratch)
4733 use_zero_reg = true;
4735 if (optimize_size)
4736 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
4738 if (t_len * count <= max_len)
4740 /* Output shifts inline with no loop - faster. */
4742 while (count-- > 0)
4743 avr_asm_len (templ, op, plen, t_len);
4745 return;
4748 if (scratch)
4750 avr_asm_len ("ldi %3,%2", op, plen, 1);
4752 else if (use_zero_reg)
4754 /* Hack to save one word: use __zero_reg__ as loop counter.
4755 Set one bit, then shift in a loop until it is 0 again. */
4757 op[3] = zero_reg_rtx;
4759 avr_asm_len ("set" CR_TAB
4760 "bld %3,%2-1", op, plen, 2);
4762 else
4764 /* No scratch register available, use one from LD_REGS (saved in
4765 __tmp_reg__) that doesn't overlap with registers to shift. */
4767 op[3] = all_regs_rtx[((REGNO (op[0]) - 1) & 15) + 16];
4768 op[4] = tmp_reg_rtx;
4769 saved_in_tmp = true;
4771 avr_asm_len ("mov %4,%3" CR_TAB
4772 "ldi %3,%2", op, plen, 2);
4775 second_label = false;
4777 else if (MEM_P (op[2]))
4779 rtx op_mov[2];
4781 op_mov[0] = op[3] = tmp_reg_rtx;
4782 op_mov[1] = op[2];
4784 out_movqi_r_mr (insn, op_mov, plen);
4786 else if (register_operand (op[2], QImode))
4788 op[3] = op[2];
4790 if (!reg_unused_after (insn, op[2])
4791 || reg_overlap_mentioned_p (op[0], op[2]))
4793 op[3] = tmp_reg_rtx;
4794 avr_asm_len ("mov %3,%2", op, plen, 1);
4797 else
4798 fatal_insn ("bad shift insn:", insn);
4800 if (second_label)
4801 avr_asm_len ("rjmp 2f", op, plen, 1);
4803 avr_asm_len ("1:", op, plen, 0);
4804 avr_asm_len (templ, op, plen, t_len);
4806 if (second_label)
4807 avr_asm_len ("2:", op, plen, 0);
4809 avr_asm_len (use_zero_reg ? "lsr %3" : "dec %3", op, plen, 1);
4810 avr_asm_len (second_label ? "brpl 1b" : "brne 1b", op, plen, 1);
4812 if (saved_in_tmp)
4813 avr_asm_len ("mov %3,%4", op, plen, 1);
4817 /* 8bit shift left ((char)x << i) */
4819 const char *
4820 ashlqi3_out (rtx insn, rtx operands[], int *len)
4822 if (GET_CODE (operands[2]) == CONST_INT)
4824 int k;
4826 if (!len)
4827 len = &k;
4829 switch (INTVAL (operands[2]))
4831 default:
4832 if (INTVAL (operands[2]) < 8)
4833 break;
4835 *len = 1;
4836 return "clr %0";
4838 case 1:
4839 *len = 1;
4840 return "lsl %0";
4842 case 2:
4843 *len = 2;
4844 return ("lsl %0" CR_TAB
4845 "lsl %0");
4847 case 3:
4848 *len = 3;
4849 return ("lsl %0" CR_TAB
4850 "lsl %0" CR_TAB
4851 "lsl %0");
4853 case 4:
4854 if (test_hard_reg_class (LD_REGS, operands[0]))
4856 *len = 2;
4857 return ("swap %0" CR_TAB
4858 "andi %0,0xf0");
4860 *len = 4;
4861 return ("lsl %0" CR_TAB
4862 "lsl %0" CR_TAB
4863 "lsl %0" CR_TAB
4864 "lsl %0");
4866 case 5:
4867 if (test_hard_reg_class (LD_REGS, operands[0]))
4869 *len = 3;
4870 return ("swap %0" CR_TAB
4871 "lsl %0" CR_TAB
4872 "andi %0,0xe0");
4874 *len = 5;
4875 return ("lsl %0" CR_TAB
4876 "lsl %0" CR_TAB
4877 "lsl %0" CR_TAB
4878 "lsl %0" CR_TAB
4879 "lsl %0");
4881 case 6:
4882 if (test_hard_reg_class (LD_REGS, operands[0]))
4884 *len = 4;
4885 return ("swap %0" CR_TAB
4886 "lsl %0" CR_TAB
4887 "lsl %0" CR_TAB
4888 "andi %0,0xc0");
4890 *len = 6;
4891 return ("lsl %0" CR_TAB
4892 "lsl %0" CR_TAB
4893 "lsl %0" CR_TAB
4894 "lsl %0" CR_TAB
4895 "lsl %0" CR_TAB
4896 "lsl %0");
4898 case 7:
4899 *len = 3;
4900 return ("ror %0" CR_TAB
4901 "clr %0" CR_TAB
4902 "ror %0");
4905 else if (CONSTANT_P (operands[2]))
4906 fatal_insn ("internal compiler error. Incorrect shift:", insn);
4908 out_shift_with_cnt ("lsl %0",
4909 insn, operands, len, 1);
4910 return "";
4914 /* 16bit shift left ((short)x << i) */
4916 const char *
4917 ashlhi3_out (rtx insn, rtx operands[], int *len)
4919 if (GET_CODE (operands[2]) == CONST_INT)
4921 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
4922 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
4923 int k;
4924 int *t = len;
4926 if (!len)
4927 len = &k;
4929 switch (INTVAL (operands[2]))
4931 default:
4932 if (INTVAL (operands[2]) < 16)
4933 break;
4935 *len = 2;
4936 return ("clr %B0" CR_TAB
4937 "clr %A0");
4939 case 4:
4940 if (optimize_size && scratch)
4941 break; /* 5 */
4942 if (ldi_ok)
4944 *len = 6;
4945 return ("swap %A0" CR_TAB
4946 "swap %B0" CR_TAB
4947 "andi %B0,0xf0" CR_TAB
4948 "eor %B0,%A0" CR_TAB
4949 "andi %A0,0xf0" CR_TAB
4950 "eor %B0,%A0");
4952 if (scratch)
4954 *len = 7;
4955 return ("swap %A0" CR_TAB
4956 "swap %B0" CR_TAB
4957 "ldi %3,0xf0" CR_TAB
4958 "and %B0,%3" CR_TAB
4959 "eor %B0,%A0" CR_TAB
4960 "and %A0,%3" CR_TAB
4961 "eor %B0,%A0");
4963 break; /* optimize_size ? 6 : 8 */
4965 case 5:
4966 if (optimize_size)
4967 break; /* scratch ? 5 : 6 */
4968 if (ldi_ok)
4970 *len = 8;
4971 return ("lsl %A0" CR_TAB
4972 "rol %B0" CR_TAB
4973 "swap %A0" CR_TAB
4974 "swap %B0" CR_TAB
4975 "andi %B0,0xf0" CR_TAB
4976 "eor %B0,%A0" CR_TAB
4977 "andi %A0,0xf0" CR_TAB
4978 "eor %B0,%A0");
4980 if (scratch)
4982 *len = 9;
4983 return ("lsl %A0" CR_TAB
4984 "rol %B0" CR_TAB
4985 "swap %A0" CR_TAB
4986 "swap %B0" CR_TAB
4987 "ldi %3,0xf0" CR_TAB
4988 "and %B0,%3" CR_TAB
4989 "eor %B0,%A0" CR_TAB
4990 "and %A0,%3" CR_TAB
4991 "eor %B0,%A0");
4993 break; /* 10 */
4995 case 6:
4996 if (optimize_size)
4997 break; /* scratch ? 5 : 6 */
4998 *len = 9;
4999 return ("clr __tmp_reg__" CR_TAB
5000 "lsr %B0" CR_TAB
5001 "ror %A0" CR_TAB
5002 "ror __tmp_reg__" CR_TAB
5003 "lsr %B0" CR_TAB
5004 "ror %A0" CR_TAB
5005 "ror __tmp_reg__" CR_TAB
5006 "mov %B0,%A0" CR_TAB
5007 "mov %A0,__tmp_reg__");
5009 case 7:
5010 *len = 5;
5011 return ("lsr %B0" CR_TAB
5012 "mov %B0,%A0" CR_TAB
5013 "clr %A0" CR_TAB
5014 "ror %B0" CR_TAB
5015 "ror %A0");
5017 case 8:
5018 return *len = 2, ("mov %B0,%A1" CR_TAB
5019 "clr %A0");
5021 case 9:
5022 *len = 3;
5023 return ("mov %B0,%A0" CR_TAB
5024 "clr %A0" CR_TAB
5025 "lsl %B0");
5027 case 10:
5028 *len = 4;
5029 return ("mov %B0,%A0" CR_TAB
5030 "clr %A0" CR_TAB
5031 "lsl %B0" CR_TAB
5032 "lsl %B0");
5034 case 11:
5035 *len = 5;
5036 return ("mov %B0,%A0" CR_TAB
5037 "clr %A0" CR_TAB
5038 "lsl %B0" CR_TAB
5039 "lsl %B0" CR_TAB
5040 "lsl %B0");
5042 case 12:
5043 if (ldi_ok)
5045 *len = 4;
5046 return ("mov %B0,%A0" CR_TAB
5047 "clr %A0" CR_TAB
5048 "swap %B0" CR_TAB
5049 "andi %B0,0xf0");
5051 if (scratch)
5053 *len = 5;
5054 return ("mov %B0,%A0" CR_TAB
5055 "clr %A0" CR_TAB
5056 "swap %B0" CR_TAB
5057 "ldi %3,0xf0" CR_TAB
5058 "and %B0,%3");
5060 *len = 6;
5061 return ("mov %B0,%A0" CR_TAB
5062 "clr %A0" CR_TAB
5063 "lsl %B0" CR_TAB
5064 "lsl %B0" CR_TAB
5065 "lsl %B0" CR_TAB
5066 "lsl %B0");
5068 case 13:
5069 if (ldi_ok)
5071 *len = 5;
5072 return ("mov %B0,%A0" CR_TAB
5073 "clr %A0" CR_TAB
5074 "swap %B0" CR_TAB
5075 "lsl %B0" CR_TAB
5076 "andi %B0,0xe0");
5078 if (AVR_HAVE_MUL && scratch)
5080 *len = 5;
5081 return ("ldi %3,0x20" CR_TAB
5082 "mul %A0,%3" CR_TAB
5083 "mov %B0,r0" CR_TAB
5084 "clr %A0" CR_TAB
5085 "clr __zero_reg__");
5087 if (optimize_size && scratch)
5088 break; /* 5 */
5089 if (scratch)
5091 *len = 6;
5092 return ("mov %B0,%A0" CR_TAB
5093 "clr %A0" CR_TAB
5094 "swap %B0" CR_TAB
5095 "lsl %B0" CR_TAB
5096 "ldi %3,0xe0" CR_TAB
5097 "and %B0,%3");
5099 if (AVR_HAVE_MUL)
5101 *len = 6;
5102 return ("set" CR_TAB
5103 "bld r1,5" CR_TAB
5104 "mul %A0,r1" CR_TAB
5105 "mov %B0,r0" CR_TAB
5106 "clr %A0" CR_TAB
5107 "clr __zero_reg__");
5109 *len = 7;
5110 return ("mov %B0,%A0" CR_TAB
5111 "clr %A0" CR_TAB
5112 "lsl %B0" CR_TAB
5113 "lsl %B0" CR_TAB
5114 "lsl %B0" CR_TAB
5115 "lsl %B0" CR_TAB
5116 "lsl %B0");
5118 case 14:
5119 if (AVR_HAVE_MUL && ldi_ok)
5121 *len = 5;
5122 return ("ldi %B0,0x40" CR_TAB
5123 "mul %A0,%B0" CR_TAB
5124 "mov %B0,r0" CR_TAB
5125 "clr %A0" CR_TAB
5126 "clr __zero_reg__");
5128 if (AVR_HAVE_MUL && scratch)
5130 *len = 5;
5131 return ("ldi %3,0x40" CR_TAB
5132 "mul %A0,%3" CR_TAB
5133 "mov %B0,r0" CR_TAB
5134 "clr %A0" CR_TAB
5135 "clr __zero_reg__");
5137 if (optimize_size && ldi_ok)
5139 *len = 5;
5140 return ("mov %B0,%A0" CR_TAB
5141 "ldi %A0,6" "\n1:\t"
5142 "lsl %B0" CR_TAB
5143 "dec %A0" CR_TAB
5144 "brne 1b");
5146 if (optimize_size && scratch)
5147 break; /* 5 */
5148 *len = 6;
5149 return ("clr %B0" CR_TAB
5150 "lsr %A0" CR_TAB
5151 "ror %B0" CR_TAB
5152 "lsr %A0" CR_TAB
5153 "ror %B0" CR_TAB
5154 "clr %A0");
5156 case 15:
5157 *len = 4;
5158 return ("clr %B0" CR_TAB
5159 "lsr %A0" CR_TAB
5160 "ror %B0" CR_TAB
5161 "clr %A0");
5163 len = t;
5165 out_shift_with_cnt ("lsl %A0" CR_TAB
5166 "rol %B0", insn, operands, len, 2);
5167 return "";
5171 /* 24-bit shift left */
5173 const char*
5174 avr_out_ashlpsi3 (rtx insn, rtx *op, int *plen)
5176 if (plen)
5177 *plen = 0;
5179 if (CONST_INT_P (op[2]))
5181 switch (INTVAL (op[2]))
5183 default:
5184 if (INTVAL (op[2]) < 24)
5185 break;
5187 return avr_asm_len ("clr %A0" CR_TAB
5188 "clr %B0" CR_TAB
5189 "clr %C0", op, plen, 3);
5191 case 8:
5193 int reg0 = REGNO (op[0]);
5194 int reg1 = REGNO (op[1]);
5196 if (reg0 >= reg1)
5197 return avr_asm_len ("mov %C0,%B1" CR_TAB
5198 "mov %B0,%A1" CR_TAB
5199 "clr %A0", op, plen, 3);
5200 else
5201 return avr_asm_len ("clr %A0" CR_TAB
5202 "mov %B0,%A1" CR_TAB
5203 "mov %C0,%B1", op, plen, 3);
5206 case 16:
5208 int reg0 = REGNO (op[0]);
5209 int reg1 = REGNO (op[1]);
5211 if (reg0 + 2 != reg1)
5212 avr_asm_len ("mov %C0,%A0", op, plen, 1);
5214 return avr_asm_len ("clr %B0" CR_TAB
5215 "clr %A0", op, plen, 2);
5218 case 23:
5219 return avr_asm_len ("clr %C0" CR_TAB
5220 "lsr %A0" CR_TAB
5221 "ror %C0" CR_TAB
5222 "clr %B0" CR_TAB
5223 "clr %A0", op, plen, 5);
5227 out_shift_with_cnt ("lsl %A0" CR_TAB
5228 "rol %B0" CR_TAB
5229 "rol %C0", insn, op, plen, 3);
5230 return "";
5234 /* 32bit shift left ((long)x << i) */
5236 const char *
5237 ashlsi3_out (rtx insn, rtx operands[], int *len)
5239 if (GET_CODE (operands[2]) == CONST_INT)
5241 int k;
5242 int *t = len;
5244 if (!len)
5245 len = &k;
5247 switch (INTVAL (operands[2]))
5249 default:
5250 if (INTVAL (operands[2]) < 32)
5251 break;
5253 if (AVR_HAVE_MOVW)
5254 return *len = 3, ("clr %D0" CR_TAB
5255 "clr %C0" CR_TAB
5256 "movw %A0,%C0");
5257 *len = 4;
5258 return ("clr %D0" CR_TAB
5259 "clr %C0" CR_TAB
5260 "clr %B0" CR_TAB
5261 "clr %A0");
5263 case 8:
5265 int reg0 = true_regnum (operands[0]);
5266 int reg1 = true_regnum (operands[1]);
5267 *len = 4;
5268 if (reg0 >= reg1)
5269 return ("mov %D0,%C1" CR_TAB
5270 "mov %C0,%B1" CR_TAB
5271 "mov %B0,%A1" CR_TAB
5272 "clr %A0");
5273 else
5274 return ("clr %A0" CR_TAB
5275 "mov %B0,%A1" CR_TAB
5276 "mov %C0,%B1" CR_TAB
5277 "mov %D0,%C1");
5280 case 16:
5282 int reg0 = true_regnum (operands[0]);
5283 int reg1 = true_regnum (operands[1]);
5284 if (reg0 + 2 == reg1)
5285 return *len = 2, ("clr %B0" CR_TAB
5286 "clr %A0");
5287 if (AVR_HAVE_MOVW)
5288 return *len = 3, ("movw %C0,%A1" CR_TAB
5289 "clr %B0" CR_TAB
5290 "clr %A0");
5291 else
5292 return *len = 4, ("mov %C0,%A1" CR_TAB
5293 "mov %D0,%B1" CR_TAB
5294 "clr %B0" CR_TAB
5295 "clr %A0");
5298 case 24:
5299 *len = 4;
5300 return ("mov %D0,%A1" CR_TAB
5301 "clr %C0" CR_TAB
5302 "clr %B0" CR_TAB
5303 "clr %A0");
5305 case 31:
5306 *len = 6;
5307 return ("clr %D0" CR_TAB
5308 "lsr %A0" CR_TAB
5309 "ror %D0" CR_TAB
5310 "clr %C0" CR_TAB
5311 "clr %B0" CR_TAB
5312 "clr %A0");
5314 len = t;
5316 out_shift_with_cnt ("lsl %A0" CR_TAB
5317 "rol %B0" CR_TAB
5318 "rol %C0" CR_TAB
5319 "rol %D0", insn, operands, len, 4);
5320 return "";
5323 /* 8bit arithmetic shift right ((signed char)x >> i) */
5325 const char *
5326 ashrqi3_out (rtx insn, rtx operands[], int *len)
5328 if (GET_CODE (operands[2]) == CONST_INT)
5330 int k;
5332 if (!len)
5333 len = &k;
5335 switch (INTVAL (operands[2]))
5337 case 1:
5338 *len = 1;
5339 return "asr %0";
5341 case 2:
5342 *len = 2;
5343 return ("asr %0" CR_TAB
5344 "asr %0");
5346 case 3:
5347 *len = 3;
5348 return ("asr %0" CR_TAB
5349 "asr %0" CR_TAB
5350 "asr %0");
5352 case 4:
5353 *len = 4;
5354 return ("asr %0" CR_TAB
5355 "asr %0" CR_TAB
5356 "asr %0" CR_TAB
5357 "asr %0");
5359 case 5:
5360 *len = 5;
5361 return ("asr %0" CR_TAB
5362 "asr %0" CR_TAB
5363 "asr %0" CR_TAB
5364 "asr %0" CR_TAB
5365 "asr %0");
5367 case 6:
5368 *len = 4;
5369 return ("bst %0,6" CR_TAB
5370 "lsl %0" CR_TAB
5371 "sbc %0,%0" CR_TAB
5372 "bld %0,0");
5374 default:
5375 if (INTVAL (operands[2]) < 8)
5376 break;
5378 /* fall through */
5380 case 7:
5381 *len = 2;
5382 return ("lsl %0" CR_TAB
5383 "sbc %0,%0");
5386 else if (CONSTANT_P (operands[2]))
5387 fatal_insn ("internal compiler error. Incorrect shift:", insn);
5389 out_shift_with_cnt ("asr %0",
5390 insn, operands, len, 1);
5391 return "";
5395 /* 16bit arithmetic shift right ((signed short)x >> i) */
5397 const char *
5398 ashrhi3_out (rtx insn, rtx operands[], int *len)
5400 if (GET_CODE (operands[2]) == CONST_INT)
5402 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
5403 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
5404 int k;
5405 int *t = len;
5407 if (!len)
5408 len = &k;
5410 switch (INTVAL (operands[2]))
5412 case 4:
5413 case 5:
5414 /* XXX try to optimize this too? */
5415 break;
5417 case 6:
5418 if (optimize_size)
5419 break; /* scratch ? 5 : 6 */
5420 *len = 8;
5421 return ("mov __tmp_reg__,%A0" CR_TAB
5422 "mov %A0,%B0" CR_TAB
5423 "lsl __tmp_reg__" CR_TAB
5424 "rol %A0" CR_TAB
5425 "sbc %B0,%B0" CR_TAB
5426 "lsl __tmp_reg__" CR_TAB
5427 "rol %A0" CR_TAB
5428 "rol %B0");
5430 case 7:
5431 *len = 4;
5432 return ("lsl %A0" CR_TAB
5433 "mov %A0,%B0" CR_TAB
5434 "rol %A0" CR_TAB
5435 "sbc %B0,%B0");
5437 case 8:
5439 int reg0 = true_regnum (operands[0]);
5440 int reg1 = true_regnum (operands[1]);
5442 if (reg0 == reg1)
5443 return *len = 3, ("mov %A0,%B0" CR_TAB
5444 "lsl %B0" CR_TAB
5445 "sbc %B0,%B0");
5446 else
5447 return *len = 4, ("mov %A0,%B1" CR_TAB
5448 "clr %B0" CR_TAB
5449 "sbrc %A0,7" CR_TAB
5450 "dec %B0");
5453 case 9:
5454 *len = 4;
5455 return ("mov %A0,%B0" CR_TAB
5456 "lsl %B0" CR_TAB
5457 "sbc %B0,%B0" CR_TAB
5458 "asr %A0");
5460 case 10:
5461 *len = 5;
5462 return ("mov %A0,%B0" CR_TAB
5463 "lsl %B0" CR_TAB
5464 "sbc %B0,%B0" CR_TAB
5465 "asr %A0" CR_TAB
5466 "asr %A0");
5468 case 11:
5469 if (AVR_HAVE_MUL && ldi_ok)
5471 *len = 5;
5472 return ("ldi %A0,0x20" CR_TAB
5473 "muls %B0,%A0" CR_TAB
5474 "mov %A0,r1" CR_TAB
5475 "sbc %B0,%B0" CR_TAB
5476 "clr __zero_reg__");
5478 if (optimize_size && scratch)
5479 break; /* 5 */
5480 *len = 6;
5481 return ("mov %A0,%B0" CR_TAB
5482 "lsl %B0" CR_TAB
5483 "sbc %B0,%B0" CR_TAB
5484 "asr %A0" CR_TAB
5485 "asr %A0" CR_TAB
5486 "asr %A0");
5488 case 12:
5489 if (AVR_HAVE_MUL && ldi_ok)
5491 *len = 5;
5492 return ("ldi %A0,0x10" CR_TAB
5493 "muls %B0,%A0" CR_TAB
5494 "mov %A0,r1" CR_TAB
5495 "sbc %B0,%B0" CR_TAB
5496 "clr __zero_reg__");
5498 if (optimize_size && scratch)
5499 break; /* 5 */
5500 *len = 7;
5501 return ("mov %A0,%B0" CR_TAB
5502 "lsl %B0" CR_TAB
5503 "sbc %B0,%B0" CR_TAB
5504 "asr %A0" CR_TAB
5505 "asr %A0" CR_TAB
5506 "asr %A0" CR_TAB
5507 "asr %A0");
5509 case 13:
5510 if (AVR_HAVE_MUL && ldi_ok)
5512 *len = 5;
5513 return ("ldi %A0,0x08" CR_TAB
5514 "muls %B0,%A0" CR_TAB
5515 "mov %A0,r1" CR_TAB
5516 "sbc %B0,%B0" CR_TAB
5517 "clr __zero_reg__");
5519 if (optimize_size)
5520 break; /* scratch ? 5 : 7 */
5521 *len = 8;
5522 return ("mov %A0,%B0" CR_TAB
5523 "lsl %B0" CR_TAB
5524 "sbc %B0,%B0" CR_TAB
5525 "asr %A0" CR_TAB
5526 "asr %A0" CR_TAB
5527 "asr %A0" CR_TAB
5528 "asr %A0" CR_TAB
5529 "asr %A0");
5531 case 14:
5532 *len = 5;
5533 return ("lsl %B0" CR_TAB
5534 "sbc %A0,%A0" CR_TAB
5535 "lsl %B0" CR_TAB
5536 "mov %B0,%A0" CR_TAB
5537 "rol %A0");
5539 default:
5540 if (INTVAL (operands[2]) < 16)
5541 break;
5543 /* fall through */
5545 case 15:
5546 return *len = 3, ("lsl %B0" CR_TAB
5547 "sbc %A0,%A0" CR_TAB
5548 "mov %B0,%A0");
5550 len = t;
5552 out_shift_with_cnt ("asr %B0" CR_TAB
5553 "ror %A0", insn, operands, len, 2);
5554 return "";
5558 /* 24-bit arithmetic shift right */
5560 const char*
5561 avr_out_ashrpsi3 (rtx insn, rtx *op, int *plen)
5563 int dest = REGNO (op[0]);
5564 int src = REGNO (op[1]);
5566 if (CONST_INT_P (op[2]))
5568 if (plen)
5569 *plen = 0;
5571 switch (INTVAL (op[2]))
5573 case 8:
5574 if (dest <= src)
5575 return avr_asm_len ("mov %A0,%B1" CR_TAB
5576 "mov %B0,%C1" CR_TAB
5577 "clr %C0" CR_TAB
5578 "sbrc %B0,7" CR_TAB
5579 "dec %C0", op, plen, 5);
5580 else
5581 return avr_asm_len ("clr %C0" CR_TAB
5582 "sbrc %C1,7" CR_TAB
5583 "dec %C0" CR_TAB
5584 "mov %B0,%C1" CR_TAB
5585 "mov %A0,%B1", op, plen, 5);
5587 case 16:
5588 if (dest != src + 2)
5589 avr_asm_len ("mov %A0,%C1", op, plen, 1);
5591 return avr_asm_len ("clr %B0" CR_TAB
5592 "sbrc %A0,7" CR_TAB
5593 "com %B0" CR_TAB
5594 "mov %C0,%B0", op, plen, 4);
5596 default:
5597 if (INTVAL (op[2]) < 24)
5598 break;
5600 /* fall through */
5602 case 23:
5603 return avr_asm_len ("lsl %C0" CR_TAB
5604 "sbc %A0,%A0" CR_TAB
5605 "mov %B0,%A0" CR_TAB
5606 "mov %C0,%A0", op, plen, 4);
5607 } /* switch */
5610 out_shift_with_cnt ("asr %C0" CR_TAB
5611 "ror %B0" CR_TAB
5612 "ror %A0", insn, op, plen, 3);
5613 return "";
5617 /* 32-bit arithmetic shift right ((signed long)x >> i) */
5619 const char *
5620 ashrsi3_out (rtx insn, rtx operands[], int *len)
5622 if (GET_CODE (operands[2]) == CONST_INT)
5624 int k;
5625 int *t = len;
5627 if (!len)
5628 len = &k;
5630 switch (INTVAL (operands[2]))
5632 case 8:
5634 int reg0 = true_regnum (operands[0]);
5635 int reg1 = true_regnum (operands[1]);
5636 *len=6;
5637 if (reg0 <= reg1)
5638 return ("mov %A0,%B1" CR_TAB
5639 "mov %B0,%C1" CR_TAB
5640 "mov %C0,%D1" CR_TAB
5641 "clr %D0" CR_TAB
5642 "sbrc %C0,7" CR_TAB
5643 "dec %D0");
5644 else
5645 return ("clr %D0" CR_TAB
5646 "sbrc %D1,7" CR_TAB
5647 "dec %D0" CR_TAB
5648 "mov %C0,%D1" CR_TAB
5649 "mov %B0,%C1" CR_TAB
5650 "mov %A0,%B1");
5653 case 16:
5655 int reg0 = true_regnum (operands[0]);
5656 int reg1 = true_regnum (operands[1]);
5658 if (reg0 == reg1 + 2)
5659 return *len = 4, ("clr %D0" CR_TAB
5660 "sbrc %B0,7" CR_TAB
5661 "com %D0" CR_TAB
5662 "mov %C0,%D0");
5663 if (AVR_HAVE_MOVW)
5664 return *len = 5, ("movw %A0,%C1" CR_TAB
5665 "clr %D0" CR_TAB
5666 "sbrc %B0,7" CR_TAB
5667 "com %D0" CR_TAB
5668 "mov %C0,%D0");
5669 else
5670 return *len = 6, ("mov %B0,%D1" CR_TAB
5671 "mov %A0,%C1" CR_TAB
5672 "clr %D0" CR_TAB
5673 "sbrc %B0,7" CR_TAB
5674 "com %D0" CR_TAB
5675 "mov %C0,%D0");
5678 case 24:
5679 return *len = 6, ("mov %A0,%D1" CR_TAB
5680 "clr %D0" CR_TAB
5681 "sbrc %A0,7" CR_TAB
5682 "com %D0" CR_TAB
5683 "mov %B0,%D0" CR_TAB
5684 "mov %C0,%D0");
5686 default:
5687 if (INTVAL (operands[2]) < 32)
5688 break;
5690 /* fall through */
5692 case 31:
5693 if (AVR_HAVE_MOVW)
5694 return *len = 4, ("lsl %D0" CR_TAB
5695 "sbc %A0,%A0" CR_TAB
5696 "mov %B0,%A0" CR_TAB
5697 "movw %C0,%A0");
5698 else
5699 return *len = 5, ("lsl %D0" CR_TAB
5700 "sbc %A0,%A0" CR_TAB
5701 "mov %B0,%A0" CR_TAB
5702 "mov %C0,%A0" CR_TAB
5703 "mov %D0,%A0");
5705 len = t;
5707 out_shift_with_cnt ("asr %D0" CR_TAB
5708 "ror %C0" CR_TAB
5709 "ror %B0" CR_TAB
5710 "ror %A0", insn, operands, len, 4);
5711 return "";
5714 /* 8-bit logic shift right ((unsigned char)x >> i) */
5716 const char *
5717 lshrqi3_out (rtx insn, rtx operands[], int *len)
5719 if (GET_CODE (operands[2]) == CONST_INT)
5721 int k;
5723 if (!len)
5724 len = &k;
5726 switch (INTVAL (operands[2]))
5728 default:
5729 if (INTVAL (operands[2]) < 8)
5730 break;
5732 *len = 1;
5733 return "clr %0";
5735 case 1:
5736 *len = 1;
5737 return "lsr %0";
5739 case 2:
5740 *len = 2;
5741 return ("lsr %0" CR_TAB
5742 "lsr %0");
5743 case 3:
5744 *len = 3;
5745 return ("lsr %0" CR_TAB
5746 "lsr %0" CR_TAB
5747 "lsr %0");
5749 case 4:
5750 if (test_hard_reg_class (LD_REGS, operands[0]))
5752 *len=2;
5753 return ("swap %0" CR_TAB
5754 "andi %0,0x0f");
5756 *len = 4;
5757 return ("lsr %0" CR_TAB
5758 "lsr %0" CR_TAB
5759 "lsr %0" CR_TAB
5760 "lsr %0");
5762 case 5:
5763 if (test_hard_reg_class (LD_REGS, operands[0]))
5765 *len = 3;
5766 return ("swap %0" CR_TAB
5767 "lsr %0" CR_TAB
5768 "andi %0,0x7");
5770 *len = 5;
5771 return ("lsr %0" CR_TAB
5772 "lsr %0" CR_TAB
5773 "lsr %0" CR_TAB
5774 "lsr %0" CR_TAB
5775 "lsr %0");
5777 case 6:
5778 if (test_hard_reg_class (LD_REGS, operands[0]))
5780 *len = 4;
5781 return ("swap %0" CR_TAB
5782 "lsr %0" CR_TAB
5783 "lsr %0" CR_TAB
5784 "andi %0,0x3");
5786 *len = 6;
5787 return ("lsr %0" CR_TAB
5788 "lsr %0" CR_TAB
5789 "lsr %0" CR_TAB
5790 "lsr %0" CR_TAB
5791 "lsr %0" CR_TAB
5792 "lsr %0");
5794 case 7:
5795 *len = 3;
5796 return ("rol %0" CR_TAB
5797 "clr %0" CR_TAB
5798 "rol %0");
5801 else if (CONSTANT_P (operands[2]))
5802 fatal_insn ("internal compiler error. Incorrect shift:", insn);
5804 out_shift_with_cnt ("lsr %0",
5805 insn, operands, len, 1);
5806 return "";
5809 /* 16-bit logic shift right ((unsigned short)x >> i) */
5811 const char *
5812 lshrhi3_out (rtx insn, rtx operands[], int *len)
5814 if (GET_CODE (operands[2]) == CONST_INT)
5816 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
5817 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
5818 int k;
5819 int *t = len;
5821 if (!len)
5822 len = &k;
5824 switch (INTVAL (operands[2]))
5826 default:
5827 if (INTVAL (operands[2]) < 16)
5828 break;
5830 *len = 2;
5831 return ("clr %B0" CR_TAB
5832 "clr %A0");
5834 case 4:
5835 if (optimize_size && scratch)
5836 break; /* 5 */
5837 if (ldi_ok)
5839 *len = 6;
5840 return ("swap %B0" CR_TAB
5841 "swap %A0" CR_TAB
5842 "andi %A0,0x0f" CR_TAB
5843 "eor %A0,%B0" CR_TAB
5844 "andi %B0,0x0f" CR_TAB
5845 "eor %A0,%B0");
5847 if (scratch)
5849 *len = 7;
5850 return ("swap %B0" CR_TAB
5851 "swap %A0" CR_TAB
5852 "ldi %3,0x0f" CR_TAB
5853 "and %A0,%3" CR_TAB
5854 "eor %A0,%B0" CR_TAB
5855 "and %B0,%3" CR_TAB
5856 "eor %A0,%B0");
5858 break; /* optimize_size ? 6 : 8 */
5860 case 5:
5861 if (optimize_size)
5862 break; /* scratch ? 5 : 6 */
5863 if (ldi_ok)
5865 *len = 8;
5866 return ("lsr %B0" CR_TAB
5867 "ror %A0" CR_TAB
5868 "swap %B0" CR_TAB
5869 "swap %A0" CR_TAB
5870 "andi %A0,0x0f" CR_TAB
5871 "eor %A0,%B0" CR_TAB
5872 "andi %B0,0x0f" CR_TAB
5873 "eor %A0,%B0");
5875 if (scratch)
5877 *len = 9;
5878 return ("lsr %B0" CR_TAB
5879 "ror %A0" CR_TAB
5880 "swap %B0" CR_TAB
5881 "swap %A0" CR_TAB
5882 "ldi %3,0x0f" CR_TAB
5883 "and %A0,%3" CR_TAB
5884 "eor %A0,%B0" CR_TAB
5885 "and %B0,%3" CR_TAB
5886 "eor %A0,%B0");
5888 break; /* 10 */
5890 case 6:
5891 if (optimize_size)
5892 break; /* scratch ? 5 : 6 */
5893 *len = 9;
5894 return ("clr __tmp_reg__" CR_TAB
5895 "lsl %A0" CR_TAB
5896 "rol %B0" CR_TAB
5897 "rol __tmp_reg__" CR_TAB
5898 "lsl %A0" CR_TAB
5899 "rol %B0" CR_TAB
5900 "rol __tmp_reg__" CR_TAB
5901 "mov %A0,%B0" CR_TAB
5902 "mov %B0,__tmp_reg__");
5904 case 7:
5905 *len = 5;
5906 return ("lsl %A0" CR_TAB
5907 "mov %A0,%B0" CR_TAB
5908 "rol %A0" CR_TAB
5909 "sbc %B0,%B0" CR_TAB
5910 "neg %B0");
5912 case 8:
5913 return *len = 2, ("mov %A0,%B1" CR_TAB
5914 "clr %B0");
5916 case 9:
5917 *len = 3;
5918 return ("mov %A0,%B0" CR_TAB
5919 "clr %B0" CR_TAB
5920 "lsr %A0");
5922 case 10:
5923 *len = 4;
5924 return ("mov %A0,%B0" CR_TAB
5925 "clr %B0" CR_TAB
5926 "lsr %A0" CR_TAB
5927 "lsr %A0");
5929 case 11:
5930 *len = 5;
5931 return ("mov %A0,%B0" CR_TAB
5932 "clr %B0" CR_TAB
5933 "lsr %A0" CR_TAB
5934 "lsr %A0" CR_TAB
5935 "lsr %A0");
5937 case 12:
5938 if (ldi_ok)
5940 *len = 4;
5941 return ("mov %A0,%B0" CR_TAB
5942 "clr %B0" CR_TAB
5943 "swap %A0" CR_TAB
5944 "andi %A0,0x0f");
5946 if (scratch)
5948 *len = 5;
5949 return ("mov %A0,%B0" CR_TAB
5950 "clr %B0" CR_TAB
5951 "swap %A0" CR_TAB
5952 "ldi %3,0x0f" CR_TAB
5953 "and %A0,%3");
5955 *len = 6;
5956 return ("mov %A0,%B0" CR_TAB
5957 "clr %B0" CR_TAB
5958 "lsr %A0" CR_TAB
5959 "lsr %A0" CR_TAB
5960 "lsr %A0" CR_TAB
5961 "lsr %A0");
5963 case 13:
5964 if (ldi_ok)
5966 *len = 5;
5967 return ("mov %A0,%B0" CR_TAB
5968 "clr %B0" CR_TAB
5969 "swap %A0" CR_TAB
5970 "lsr %A0" CR_TAB
5971 "andi %A0,0x07");
5973 if (AVR_HAVE_MUL && scratch)
5975 *len = 5;
5976 return ("ldi %3,0x08" CR_TAB
5977 "mul %B0,%3" CR_TAB
5978 "mov %A0,r1" CR_TAB
5979 "clr %B0" CR_TAB
5980 "clr __zero_reg__");
5982 if (optimize_size && scratch)
5983 break; /* 5 */
5984 if (scratch)
5986 *len = 6;
5987 return ("mov %A0,%B0" CR_TAB
5988 "clr %B0" CR_TAB
5989 "swap %A0" CR_TAB
5990 "lsr %A0" CR_TAB
5991 "ldi %3,0x07" CR_TAB
5992 "and %A0,%3");
5994 if (AVR_HAVE_MUL)
5996 *len = 6;
5997 return ("set" CR_TAB
5998 "bld r1,3" CR_TAB
5999 "mul %B0,r1" CR_TAB
6000 "mov %A0,r1" CR_TAB
6001 "clr %B0" CR_TAB
6002 "clr __zero_reg__");
6004 *len = 7;
6005 return ("mov %A0,%B0" CR_TAB
6006 "clr %B0" CR_TAB
6007 "lsr %A0" CR_TAB
6008 "lsr %A0" CR_TAB
6009 "lsr %A0" CR_TAB
6010 "lsr %A0" CR_TAB
6011 "lsr %A0");
6013 case 14:
6014 if (AVR_HAVE_MUL && ldi_ok)
6016 *len = 5;
6017 return ("ldi %A0,0x04" CR_TAB
6018 "mul %B0,%A0" CR_TAB
6019 "mov %A0,r1" CR_TAB
6020 "clr %B0" CR_TAB
6021 "clr __zero_reg__");
6023 if (AVR_HAVE_MUL && scratch)
6025 *len = 5;
6026 return ("ldi %3,0x04" CR_TAB
6027 "mul %B0,%3" CR_TAB
6028 "mov %A0,r1" CR_TAB
6029 "clr %B0" CR_TAB
6030 "clr __zero_reg__");
6032 if (optimize_size && ldi_ok)
6034 *len = 5;
6035 return ("mov %A0,%B0" CR_TAB
6036 "ldi %B0,6" "\n1:\t"
6037 "lsr %A0" CR_TAB
6038 "dec %B0" CR_TAB
6039 "brne 1b");
6041 if (optimize_size && scratch)
6042 break; /* 5 */
6043 *len = 6;
6044 return ("clr %A0" CR_TAB
6045 "lsl %B0" CR_TAB
6046 "rol %A0" CR_TAB
6047 "lsl %B0" CR_TAB
6048 "rol %A0" CR_TAB
6049 "clr %B0");
6051 case 15:
6052 *len = 4;
6053 return ("clr %A0" CR_TAB
6054 "lsl %B0" CR_TAB
6055 "rol %A0" CR_TAB
6056 "clr %B0");
6058 len = t;
6060 out_shift_with_cnt ("lsr %B0" CR_TAB
6061 "ror %A0", insn, operands, len, 2);
6062 return "";
6066 /* 24-bit logic shift right */
6068 const char*
6069 avr_out_lshrpsi3 (rtx insn, rtx *op, int *plen)
6071 int dest = REGNO (op[0]);
6072 int src = REGNO (op[1]);
6074 if (CONST_INT_P (op[2]))
6076 if (plen)
6077 *plen = 0;
6079 switch (INTVAL (op[2]))
6081 case 8:
6082 if (dest <= src)
6083 return avr_asm_len ("mov %A0,%B1" CR_TAB
6084 "mov %B0,%C1" CR_TAB
6085 "clr %C0", op, plen, 3);
6086 else
6087 return avr_asm_len ("clr %C0" CR_TAB
6088 "mov %B0,%C1" CR_TAB
6089 "mov %A0,%B1", op, plen, 3);
6091 case 16:
6092 if (dest != src + 2)
6093 avr_asm_len ("mov %A0,%C1", op, plen, 1);
6095 return avr_asm_len ("clr %B0" CR_TAB
6096 "clr %C0", op, plen, 2);
6098 default:
6099 if (INTVAL (op[2]) < 24)
6100 break;
6102 /* fall through */
6104 case 23:
6105 return avr_asm_len ("clr %A0" CR_TAB
6106 "sbrc %C0,7" CR_TAB
6107 "inc %A0" CR_TAB
6108 "clr %B0" CR_TAB
6109 "clr %C0", op, plen, 5);
6110 } /* switch */
6113 out_shift_with_cnt ("lsr %C0" CR_TAB
6114 "ror %B0" CR_TAB
6115 "ror %A0", insn, op, plen, 3);
6116 return "";
6120 /* 32-bit logic shift right ((unsigned int)x >> i) */
6122 const char *
6123 lshrsi3_out (rtx insn, rtx operands[], int *len)
6125 if (GET_CODE (operands[2]) == CONST_INT)
6127 int k;
6128 int *t = len;
6130 if (!len)
6131 len = &k;
6133 switch (INTVAL (operands[2]))
6135 default:
6136 if (INTVAL (operands[2]) < 32)
6137 break;
6139 if (AVR_HAVE_MOVW)
6140 return *len = 3, ("clr %D0" CR_TAB
6141 "clr %C0" CR_TAB
6142 "movw %A0,%C0");
6143 *len = 4;
6144 return ("clr %D0" CR_TAB
6145 "clr %C0" CR_TAB
6146 "clr %B0" CR_TAB
6147 "clr %A0");
6149 case 8:
6151 int reg0 = true_regnum (operands[0]);
6152 int reg1 = true_regnum (operands[1]);
6153 *len = 4;
6154 if (reg0 <= reg1)
6155 return ("mov %A0,%B1" CR_TAB
6156 "mov %B0,%C1" CR_TAB
6157 "mov %C0,%D1" CR_TAB
6158 "clr %D0");
6159 else
6160 return ("clr %D0" CR_TAB
6161 "mov %C0,%D1" CR_TAB
6162 "mov %B0,%C1" CR_TAB
6163 "mov %A0,%B1");
6166 case 16:
6168 int reg0 = true_regnum (operands[0]);
6169 int reg1 = true_regnum (operands[1]);
6171 if (reg0 == reg1 + 2)
6172 return *len = 2, ("clr %C0" CR_TAB
6173 "clr %D0");
6174 if (AVR_HAVE_MOVW)
6175 return *len = 3, ("movw %A0,%C1" CR_TAB
6176 "clr %C0" CR_TAB
6177 "clr %D0");
6178 else
6179 return *len = 4, ("mov %B0,%D1" CR_TAB
6180 "mov %A0,%C1" CR_TAB
6181 "clr %C0" CR_TAB
6182 "clr %D0");
6185 case 24:
6186 return *len = 4, ("mov %A0,%D1" CR_TAB
6187 "clr %B0" CR_TAB
6188 "clr %C0" CR_TAB
6189 "clr %D0");
6191 case 31:
6192 *len = 6;
6193 return ("clr %A0" CR_TAB
6194 "sbrc %D0,7" CR_TAB
6195 "inc %A0" CR_TAB
6196 "clr %B0" CR_TAB
6197 "clr %C0" CR_TAB
6198 "clr %D0");
6200 len = t;
6202 out_shift_with_cnt ("lsr %D0" CR_TAB
6203 "ror %C0" CR_TAB
6204 "ror %B0" CR_TAB
6205 "ror %A0", insn, operands, len, 4);
6206 return "";
6210 /* Output addition of register XOP[0] and compile time constant XOP[2].
6211 CODE == PLUS: perform addition by using ADD instructions or
6212 CODE == MINUS: perform addition by using SUB instructions:
6214 XOP[0] = XOP[0] + XOP[2]
6216 Or perform addition/subtraction with register XOP[2] depending on CODE:
6218 XOP[0] = XOP[0] +/- XOP[2]
6220 If PLEN == NULL, print assembler instructions to perform the operation;
6221 otherwise, set *PLEN to the length of the instruction sequence (in words)
6222 printed with PLEN == NULL. XOP[3] is an 8-bit scratch register or NULL_RTX.
6223 Set *PCC to effect on cc0 according to respective CC_* insn attribute.
6225 CODE_SAT == UNKNOWN: Perform ordinary, non-saturating operation.
6226 CODE_SAT != UNKNOWN: Perform operation and saturate according to CODE_SAT.
6227 If CODE_SAT != UNKNOWN then SIGN contains the sign of the summand resp.
6228 the subtrahend in the original insn, provided it is a compile time constant.
6229 In all other cases, SIGN is 0.
6231 If OUT_LABEL is true, print the final 0: label which is needed for
6232 saturated addition / subtraction. The only case where OUT_LABEL = false
6233 is useful is for saturated addition / subtraction performed during
6234 fixed-point rounding, cf. `avr_out_round'. */
6236 static void
6237 avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc,
6238 enum rtx_code code_sat, int sign, bool out_label)
6240 /* MODE of the operation. */
6241 enum machine_mode mode = GET_MODE (xop[0]);
6243 /* INT_MODE of the same size. */
6244 enum machine_mode imode = int_mode_for_mode (mode);
6246 /* Number of bytes to operate on. */
6247 int i, n_bytes = GET_MODE_SIZE (mode);
6249 /* Value (0..0xff) held in clobber register op[3] or -1 if unknown. */
6250 int clobber_val = -1;
6252 /* op[0]: 8-bit destination register
6253 op[1]: 8-bit const int
6254 op[2]: 8-bit scratch register */
6255 rtx op[3];
6257 /* Started the operation? Before starting the operation we may skip
6258 adding 0. This is no more true after the operation started because
6259 carry must be taken into account. */
6260 bool started = false;
6262 /* Value to add. There are two ways to add VAL: R += VAL and R -= -VAL. */
6263 rtx xval = xop[2];
6265 /* Output a BRVC instruction. Only needed with saturation. */
6266 bool out_brvc = true;
6268 if (plen)
6269 *plen = 0;
6271 if (REG_P (xop[2]))
6273 *pcc = MINUS == code ? (int) CC_SET_CZN : (int) CC_SET_N;
6275 for (i = 0; i < n_bytes; i++)
6277 /* We operate byte-wise on the destination. */
6278 op[0] = simplify_gen_subreg (QImode, xop[0], mode, i);
6279 op[1] = simplify_gen_subreg (QImode, xop[2], mode, i);
6281 if (i == 0)
6282 avr_asm_len (code == PLUS ? "add %0,%1" : "sub %0,%1",
6283 op, plen, 1);
6284 else
6285 avr_asm_len (code == PLUS ? "adc %0,%1" : "sbc %0,%1",
6286 op, plen, 1);
6289 if (reg_overlap_mentioned_p (xop[0], xop[2]))
6291 gcc_assert (REGNO (xop[0]) == REGNO (xop[2]));
6293 if (MINUS == code)
6294 return;
6297 goto saturate;
6300 /* Except in the case of ADIW with 16-bit register (see below)
6301 addition does not set cc0 in a usable way. */
6303 *pcc = (MINUS == code) ? CC_SET_CZN : CC_CLOBBER;
6305 if (CONST_FIXED_P (xval))
6306 xval = avr_to_int_mode (xval);
6308 /* Adding/Subtracting zero is a no-op. */
6310 if (xval == const0_rtx)
6312 *pcc = CC_NONE;
6313 return;
6316 if (MINUS == code)
6317 xval = simplify_unary_operation (NEG, imode, xval, imode);
6319 op[2] = xop[3];
6321 if (SS_PLUS == code_sat && MINUS == code
6322 && sign < 0
6323 && 0x80 == (INTVAL (simplify_gen_subreg (QImode, xval, imode, n_bytes-1))
6324 & GET_MODE_MASK (QImode)))
6326 /* We compute x + 0x80 by means of SUB instructions. We negated the
6327 constant subtrahend above and are left with x - (-128) so that we
6328 need something like SUBI r,128 which does not exist because SUBI sets
6329 V according to the sign of the subtrahend. Notice the only case
6330 where this must be done is when NEG overflowed in case [2s] because
6331 the V computation needs the right sign of the subtrahend. */
6333 rtx msb = simplify_gen_subreg (QImode, xop[0], mode, n_bytes-1);
6335 avr_asm_len ("subi %0,128" CR_TAB
6336 "brmi 0f", &msb, plen, 2);
6337 out_brvc = false;
6339 goto saturate;
6342 for (i = 0; i < n_bytes; i++)
6344 /* We operate byte-wise on the destination. */
6345 rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
6346 rtx xval8 = simplify_gen_subreg (QImode, xval, imode, i);
6348 /* 8-bit value to operate with this byte. */
6349 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
6351 /* Registers R16..R31 can operate with immediate. */
6352 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
6354 op[0] = reg8;
6355 op[1] = gen_int_mode (val8, QImode);
6357 /* To get usable cc0 no low-bytes must have been skipped. */
6359 if (i && !started)
6360 *pcc = CC_CLOBBER;
6362 if (!started
6363 && i % 2 == 0
6364 && i + 2 <= n_bytes
6365 && test_hard_reg_class (ADDW_REGS, reg8))
6367 rtx xval16 = simplify_gen_subreg (HImode, xval, imode, i);
6368 unsigned int val16 = UINTVAL (xval16) & GET_MODE_MASK (HImode);
6370 /* Registers R24, X, Y, Z can use ADIW/SBIW with constants < 64
6371 i.e. operate word-wise. */
6373 if (val16 < 64)
6375 if (val16 != 0)
6377 started = true;
6378 avr_asm_len (code == PLUS ? "adiw %0,%1" : "sbiw %0,%1",
6379 op, plen, 1);
6381 if (n_bytes == 2 && PLUS == code)
6382 *pcc = CC_SET_ZN;
6385 i++;
6386 continue;
6390 if (val8 == 0)
6392 if (started)
6393 avr_asm_len (code == PLUS
6394 ? "adc %0,__zero_reg__" : "sbc %0,__zero_reg__",
6395 op, plen, 1);
6396 continue;
6398 else if ((val8 == 1 || val8 == 0xff)
6399 && UNKNOWN == code_sat
6400 && !started
6401 && i == n_bytes - 1)
6403 avr_asm_len ((code == PLUS) ^ (val8 == 1) ? "dec %0" : "inc %0",
6404 op, plen, 1);
6405 break;
6408 switch (code)
6410 case PLUS:
6412 gcc_assert (plen != NULL || (op[2] && REG_P (op[2])));
6414 if (plen != NULL && UNKNOWN != code_sat)
6416 /* This belongs to the x + 0x80 corner case. The code with
6417 ADD instruction is not smaller, thus make this case
6418 expensive so that the caller won't pick it. */
6420 *plen += 10;
6421 break;
6424 if (clobber_val != (int) val8)
6425 avr_asm_len ("ldi %2,%1", op, plen, 1);
6426 clobber_val = (int) val8;
6428 avr_asm_len (started ? "adc %0,%2" : "add %0,%2", op, plen, 1);
6430 break; /* PLUS */
6432 case MINUS:
6434 if (ld_reg_p)
6435 avr_asm_len (started ? "sbci %0,%1" : "subi %0,%1", op, plen, 1);
6436 else
6438 gcc_assert (plen != NULL || REG_P (op[2]));
6440 if (clobber_val != (int) val8)
6441 avr_asm_len ("ldi %2,%1", op, plen, 1);
6442 clobber_val = (int) val8;
6444 avr_asm_len (started ? "sbc %0,%2" : "sub %0,%2", op, plen, 1);
6447 break; /* MINUS */
6449 default:
6450 /* Unknown code */
6451 gcc_unreachable();
6454 started = true;
6456 } /* for all sub-bytes */
6458 saturate:
6460 if (UNKNOWN == code_sat)
6461 return;
6463 *pcc = (int) CC_CLOBBER;
6465 /* Vanilla addition/subtraction is done. We are left with saturation.
6467 We have to compute A = A <op> B where A is a register and
6468 B is a register or a non-zero compile time constant CONST.
6469 A is register class "r" if unsigned && B is REG. Otherwise, A is in "d".
6470 B stands for the original operand $2 in INSN. In the case of B = CONST,
6471 SIGN in { -1, 1 } is the sign of B. Otherwise, SIGN is 0.
6473 CODE is the instruction flavor we use in the asm sequence to perform <op>.
6476 unsigned
6477 operation | code | sat if | b is | sat value | case
6478 -----------------+-------+----------+--------------+-----------+-------
6479 + as a + b | add | C == 1 | const, reg | u+ = 0xff | [1u]
6480 + as a - (-b) | sub | C == 0 | const | u+ = 0xff | [2u]
6481 - as a - b | sub | C == 1 | const, reg | u- = 0 | [3u]
6482 - as a + (-b) | add | C == 0 | const | u- = 0 | [4u]
6485 signed
6486 operation | code | sat if | b is | sat value | case
6487 -----------------+-------+----------+--------------+-----------+-------
6488 + as a + b | add | V == 1 | const, reg | s+ | [1s]
6489 + as a - (-b) | sub | V == 1 | const | s+ | [2s]
6490 - as a - b | sub | V == 1 | const, reg | s- | [3s]
6491 - as a + (-b) | add | V == 1 | const | s- | [4s]
6493 s+ = b < 0 ? -0x80 : 0x7f
6494 s- = b < 0 ? 0x7f : -0x80
6496 The cases a - b actually perform a - (-(-b)) if B is CONST.
6499 op[0] = simplify_gen_subreg (QImode, xop[0], mode, n_bytes-1);
6500 op[1] = n_bytes > 1
6501 ? simplify_gen_subreg (QImode, xop[0], mode, n_bytes-2)
6502 : NULL_RTX;
6504 bool need_copy = true;
6505 int len_call = 1 + AVR_HAVE_JMP_CALL;
6507 switch (code_sat)
6509 default:
6510 gcc_unreachable();
6512 case SS_PLUS:
6513 case SS_MINUS:
6515 if (out_brvc)
6516 avr_asm_len ("brvc 0f", op, plen, 1);
6518 if (reg_overlap_mentioned_p (xop[0], xop[2]))
6520 /* [1s,reg] */
6522 if (n_bytes == 1)
6523 avr_asm_len ("ldi %0,0x7f" CR_TAB
6524 "adc %0,__zero_reg__", op, plen, 2);
6525 else
6526 avr_asm_len ("ldi %0,0x7f" CR_TAB
6527 "ldi %1,0xff" CR_TAB
6528 "adc %1,__zero_reg__" CR_TAB
6529 "adc %0,__zero_reg__", op, plen, 4);
6531 else if (sign == 0 && PLUS == code)
6533 /* [1s,reg] */
6535 op[2] = simplify_gen_subreg (QImode, xop[2], mode, n_bytes-1);
6537 if (n_bytes == 1)
6538 avr_asm_len ("ldi %0,0x80" CR_TAB
6539 "sbrs %2,7" CR_TAB
6540 "dec %0", op, plen, 3);
6541 else
6542 avr_asm_len ("ldi %0,0x80" CR_TAB
6543 "cp %2,%0" CR_TAB
6544 "sbc %1,%1" CR_TAB
6545 "sbci %0,0", op, plen, 4);
6547 else if (sign == 0 && MINUS == code)
6549 /* [3s,reg] */
6551 op[2] = simplify_gen_subreg (QImode, xop[2], mode, n_bytes-1);
6553 if (n_bytes == 1)
6554 avr_asm_len ("ldi %0,0x7f" CR_TAB
6555 "sbrs %2,7" CR_TAB
6556 "inc %0", op, plen, 3);
6557 else
6558 avr_asm_len ("ldi %0,0x7f" CR_TAB
6559 "cp %0,%2" CR_TAB
6560 "sbc %1,%1" CR_TAB
6561 "sbci %0,-1", op, plen, 4);
6563 else if ((sign < 0) ^ (SS_MINUS == code_sat))
6565 /* [1s,const,B < 0] [2s,B < 0] */
6566 /* [3s,const,B > 0] [4s,B > 0] */
6568 if (n_bytes == 8)
6570 avr_asm_len ("%~call __clr_8", op, plen, len_call);
6571 need_copy = false;
6574 avr_asm_len ("ldi %0,0x80", op, plen, 1);
6575 if (n_bytes > 1 && need_copy)
6576 avr_asm_len ("clr %1", op, plen, 1);
6578 else if ((sign > 0) ^ (SS_MINUS == code_sat))
6580 /* [1s,const,B > 0] [2s,B > 0] */
6581 /* [3s,const,B < 0] [4s,B < 0] */
6583 if (n_bytes == 8)
6585 avr_asm_len ("sec" CR_TAB
6586 "%~call __sbc_8", op, plen, 1 + len_call);
6587 need_copy = false;
6590 avr_asm_len ("ldi %0,0x7f", op, plen, 1);
6591 if (n_bytes > 1 && need_copy)
6592 avr_asm_len ("ldi %1,0xff", op, plen, 1);
6594 else
6595 gcc_unreachable();
6597 break;
6599 case US_PLUS:
6600 /* [1u] : [2u] */
6602 avr_asm_len (PLUS == code ? "brcc 0f" : "brcs 0f", op, plen, 1);
6604 if (n_bytes == 8)
6606 if (MINUS == code)
6607 avr_asm_len ("sec", op, plen, 1);
6608 avr_asm_len ("%~call __sbc_8", op, plen, len_call);
6610 need_copy = false;
6612 else
6614 if (MINUS == code && !test_hard_reg_class (LD_REGS, op[0]))
6615 avr_asm_len ("sec" CR_TAB "sbc %0,%0", op, plen, 2);
6616 else
6617 avr_asm_len (PLUS == code ? "sbc %0,%0" : "ldi %0,0xff",
6618 op, plen, 1);
6620 break; /* US_PLUS */
6622 case US_MINUS:
6623 /* [4u] : [3u] */
6625 avr_asm_len (PLUS == code ? "brcs 0f" : "brcc 0f", op, plen, 1);
6627 if (n_bytes == 8)
6629 avr_asm_len ("%~call __clr_8", op, plen, len_call);
6630 need_copy = false;
6632 else
6633 avr_asm_len ("clr %0", op, plen, 1);
6635 break;
6638 /* We set the MSB in the unsigned case and the 2 MSBs in the signed case.
6639 Now copy the right value to the LSBs. */
6641 if (need_copy && n_bytes > 1)
6643 if (US_MINUS == code_sat || US_PLUS == code_sat)
6645 avr_asm_len ("mov %1,%0", op, plen, 1);
6647 if (n_bytes > 2)
6649 op[0] = xop[0];
6650 if (AVR_HAVE_MOVW)
6651 avr_asm_len ("movw %0,%1", op, plen, 1);
6652 else
6653 avr_asm_len ("mov %A0,%1" CR_TAB
6654 "mov %B0,%1", op, plen, 2);
6657 else if (n_bytes > 2)
6659 op[0] = xop[0];
6660 avr_asm_len ("mov %A0,%1" CR_TAB
6661 "mov %B0,%1", op, plen, 2);
6665 if (need_copy && n_bytes == 8)
6667 if (AVR_HAVE_MOVW)
6668 avr_asm_len ("movw %r0+2,%0" CR_TAB
6669 "movw %r0+4,%0", xop, plen, 2);
6670 else
6671 avr_asm_len ("mov %r0+2,%0" CR_TAB
6672 "mov %r0+3,%0" CR_TAB
6673 "mov %r0+4,%0" CR_TAB
6674 "mov %r0+5,%0", xop, plen, 4);
6677 if (out_label)
6678 avr_asm_len ("0:", op, plen, 0);
6682 /* Output addition/subtraction of register XOP[0] and a constant XOP[2] that
6683 is ont a compile-time constant:
6685 XOP[0] = XOP[0] +/- XOP[2]
6687 This is a helper for the function below. The only insns that need this
6688 are additions/subtraction for pointer modes, i.e. HImode and PSImode. */
6690 static const char*
6691 avr_out_plus_symbol (rtx *xop, enum rtx_code code, int *plen, int *pcc)
6693 enum machine_mode mode = GET_MODE (xop[0]);
6695 /* Only pointer modes want to add symbols. */
6697 gcc_assert (mode == HImode || mode == PSImode);
6699 *pcc = MINUS == code ? (int) CC_SET_CZN : (int) CC_SET_N;
6701 avr_asm_len (PLUS == code
6702 ? "subi %A0,lo8(-(%2))" CR_TAB "sbci %B0,hi8(-(%2))"
6703 : "subi %A0,lo8(%2)" CR_TAB "sbci %B0,hi8(%2)",
6704 xop, plen, -2);
6706 if (PSImode == mode)
6707 avr_asm_len (PLUS == code
6708 ? "sbci %C0,hlo8(-(%2))"
6709 : "sbci %C0,hlo8(%2)", xop, plen, 1);
6710 return "";
6714 /* Prepare operands of addition/subtraction to be used with avr_out_plus_1.
6716 INSN is a single_set insn or an insn pattern with a binary operation as
6717 SET_SRC that is one of: PLUS, SS_PLUS, US_PLUS, MINUS, SS_MINUS, US_MINUS.
6719 XOP are the operands of INSN. In the case of 64-bit operations with
6720 constant XOP[] has just one element: The summand/subtrahend in XOP[0].
6721 The non-saturating insns up to 32 bits may or may not supply a "d" class
6722 scratch as XOP[3].
6724 If PLEN == NULL output the instructions.
6725 If PLEN != NULL set *PLEN to the length of the sequence in words.
6727 PCC is a pointer to store the instructions' effect on cc0.
6728 PCC may be NULL.
6730 PLEN and PCC default to NULL.
6732 OUT_LABEL defaults to TRUE. For a description, see AVR_OUT_PLUS_1.
6734 Return "" */
6736 const char*
6737 avr_out_plus (rtx insn, rtx *xop, int *plen, int *pcc, bool out_label)
6739 int cc_plus, cc_minus, cc_dummy;
6740 int len_plus, len_minus;
6741 rtx op[4];
6742 rtx xpattern = INSN_P (insn) ? single_set (insn) : insn;
6743 rtx xdest = SET_DEST (xpattern);
6744 enum machine_mode mode = GET_MODE (xdest);
6745 enum machine_mode imode = int_mode_for_mode (mode);
6746 int n_bytes = GET_MODE_SIZE (mode);
6747 enum rtx_code code_sat = GET_CODE (SET_SRC (xpattern));
6748 enum rtx_code code
6749 = (PLUS == code_sat || SS_PLUS == code_sat || US_PLUS == code_sat
6750 ? PLUS : MINUS);
6752 if (!pcc)
6753 pcc = &cc_dummy;
6755 /* PLUS and MINUS don't saturate: Use modular wrap-around. */
6757 if (PLUS == code_sat || MINUS == code_sat)
6758 code_sat = UNKNOWN;
6760 if (n_bytes <= 4 && REG_P (xop[2]))
6762 avr_out_plus_1 (xop, plen, code, pcc, code_sat, 0, out_label);
6763 return "";
6766 if (8 == n_bytes)
6768 op[0] = gen_rtx_REG (DImode, ACC_A);
6769 op[1] = gen_rtx_REG (DImode, ACC_A);
6770 op[2] = avr_to_int_mode (xop[0]);
6772 else
6774 if (!REG_P (xop[2])
6775 && !CONST_INT_P (xop[2])
6776 && !CONST_FIXED_P (xop[2]))
6778 return avr_out_plus_symbol (xop, code, plen, pcc);
6781 op[0] = avr_to_int_mode (xop[0]);
6782 op[1] = avr_to_int_mode (xop[1]);
6783 op[2] = avr_to_int_mode (xop[2]);
6786 /* Saturations and 64-bit operations don't have a clobber operand.
6787 For the other cases, the caller will provide a proper XOP[3]. */
6789 xpattern = INSN_P (insn) ? PATTERN (insn) : insn;
6790 op[3] = PARALLEL == GET_CODE (xpattern) ? xop[3] : NULL_RTX;
6792 /* Saturation will need the sign of the original operand. */
6794 rtx xmsb = simplify_gen_subreg (QImode, op[2], imode, n_bytes-1);
6795 int sign = INTVAL (xmsb) < 0 ? -1 : 1;
6797 /* If we subtract and the subtrahend is a constant, then negate it
6798 so that avr_out_plus_1 can be used. */
6800 if (MINUS == code)
6801 op[2] = simplify_unary_operation (NEG, imode, op[2], imode);
6803 /* Work out the shortest sequence. */
6805 avr_out_plus_1 (op, &len_minus, MINUS, &cc_plus, code_sat, sign, out_label);
6806 avr_out_plus_1 (op, &len_plus, PLUS, &cc_minus, code_sat, sign, out_label);
6808 if (plen)
6810 *plen = (len_minus <= len_plus) ? len_minus : len_plus;
6811 *pcc = (len_minus <= len_plus) ? cc_minus : cc_plus;
6813 else if (len_minus <= len_plus)
6814 avr_out_plus_1 (op, NULL, MINUS, pcc, code_sat, sign, out_label);
6815 else
6816 avr_out_plus_1 (op, NULL, PLUS, pcc, code_sat, sign, out_label);
6818 return "";
6822 /* Output bit operation (IOR, AND, XOR) with register XOP[0] and compile
6823 time constant XOP[2]:
6825 XOP[0] = XOP[0] <op> XOP[2]
6827 and return "". If PLEN == NULL, print assembler instructions to perform the
6828 operation; otherwise, set *PLEN to the length of the instruction sequence
6829 (in words) printed with PLEN == NULL. XOP[3] is either an 8-bit clobber
6830 register or SCRATCH if no clobber register is needed for the operation.
6831 INSN is an INSN_P or a pattern of an insn. */
6833 const char*
6834 avr_out_bitop (rtx insn, rtx *xop, int *plen)
6836 /* CODE and MODE of the operation. */
6837 rtx xpattern = INSN_P (insn) ? single_set (insn) : insn;
6838 enum rtx_code code = GET_CODE (SET_SRC (xpattern));
6839 enum machine_mode mode = GET_MODE (xop[0]);
6841 /* Number of bytes to operate on. */
6842 int i, n_bytes = GET_MODE_SIZE (mode);
6844 /* Value of T-flag (0 or 1) or -1 if unknow. */
6845 int set_t = -1;
6847 /* Value (0..0xff) held in clobber register op[3] or -1 if unknown. */
6848 int clobber_val = -1;
6850 /* op[0]: 8-bit destination register
6851 op[1]: 8-bit const int
6852 op[2]: 8-bit clobber register or SCRATCH
6853 op[3]: 8-bit register containing 0xff or NULL_RTX */
6854 rtx op[4];
6856 op[2] = xop[3];
6857 op[3] = NULL_RTX;
6859 if (plen)
6860 *plen = 0;
6862 for (i = 0; i < n_bytes; i++)
6864 /* We operate byte-wise on the destination. */
6865 rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
6866 rtx xval8 = simplify_gen_subreg (QImode, xop[2], mode, i);
6868 /* 8-bit value to operate with this byte. */
6869 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
6871 /* Number of bits set in the current byte of the constant. */
6872 int pop8 = avr_popcount (val8);
6874 /* Registers R16..R31 can operate with immediate. */
6875 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
6877 op[0] = reg8;
6878 op[1] = GEN_INT (val8);
6880 switch (code)
6882 case IOR:
6884 if (0 == pop8)
6885 continue;
6886 else if (ld_reg_p)
6887 avr_asm_len ("ori %0,%1", op, plen, 1);
6888 else if (1 == pop8)
6890 if (set_t != 1)
6891 avr_asm_len ("set", op, plen, 1);
6892 set_t = 1;
6894 op[1] = GEN_INT (exact_log2 (val8));
6895 avr_asm_len ("bld %0,%1", op, plen, 1);
6897 else if (8 == pop8)
6899 if (op[3] != NULL_RTX)
6900 avr_asm_len ("mov %0,%3", op, plen, 1);
6901 else
6902 avr_asm_len ("clr %0" CR_TAB
6903 "dec %0", op, plen, 2);
6905 op[3] = op[0];
6907 else
6909 if (clobber_val != (int) val8)
6910 avr_asm_len ("ldi %2,%1", op, plen, 1);
6911 clobber_val = (int) val8;
6913 avr_asm_len ("or %0,%2", op, plen, 1);
6916 continue; /* IOR */
6918 case AND:
6920 if (8 == pop8)
6921 continue;
6922 else if (0 == pop8)
6923 avr_asm_len ("clr %0", op, plen, 1);
6924 else if (ld_reg_p)
6925 avr_asm_len ("andi %0,%1", op, plen, 1);
6926 else if (7 == pop8)
6928 if (set_t != 0)
6929 avr_asm_len ("clt", op, plen, 1);
6930 set_t = 0;
6932 op[1] = GEN_INT (exact_log2 (GET_MODE_MASK (QImode) & ~val8));
6933 avr_asm_len ("bld %0,%1", op, plen, 1);
6935 else
6937 if (clobber_val != (int) val8)
6938 avr_asm_len ("ldi %2,%1", op, plen, 1);
6939 clobber_val = (int) val8;
6941 avr_asm_len ("and %0,%2", op, plen, 1);
6944 continue; /* AND */
6946 case XOR:
6948 if (0 == pop8)
6949 continue;
6950 else if (8 == pop8)
6951 avr_asm_len ("com %0", op, plen, 1);
6952 else if (ld_reg_p && val8 == (1 << 7))
6953 avr_asm_len ("subi %0,%1", op, plen, 1);
6954 else
6956 if (clobber_val != (int) val8)
6957 avr_asm_len ("ldi %2,%1", op, plen, 1);
6958 clobber_val = (int) val8;
6960 avr_asm_len ("eor %0,%2", op, plen, 1);
6963 continue; /* XOR */
6965 default:
6966 /* Unknown rtx_code */
6967 gcc_unreachable();
6969 } /* for all sub-bytes */
6971 return "";
6975 /* PLEN == NULL: Output code to add CONST_INT OP[0] to SP.
6976 PLEN != NULL: Set *PLEN to the length of that sequence.
6977 Return "". */
6979 const char*
6980 avr_out_addto_sp (rtx *op, int *plen)
6982 int pc_len = AVR_2_BYTE_PC ? 2 : 3;
6983 int addend = INTVAL (op[0]);
6985 if (plen)
6986 *plen = 0;
6988 if (addend < 0)
6990 if (flag_verbose_asm || flag_print_asm_name)
6991 avr_asm_len (ASM_COMMENT_START "SP -= %n0", op, plen, 0);
6993 while (addend <= -pc_len)
6995 addend += pc_len;
6996 avr_asm_len ("rcall .", op, plen, 1);
6999 while (addend++ < 0)
7000 avr_asm_len ("push __zero_reg__", op, plen, 1);
7002 else if (addend > 0)
7004 if (flag_verbose_asm || flag_print_asm_name)
7005 avr_asm_len (ASM_COMMENT_START "SP += %0", op, plen, 0);
7007 while (addend-- > 0)
7008 avr_asm_len ("pop __tmp_reg__", op, plen, 1);
7011 return "";
7015 /* Outputs instructions needed for fixed point type conversion.
7016 This includes converting between any fixed point type, as well
7017 as converting to any integer type. Conversion between integer
7018 types is not supported.
7020 Converting signed fractional types requires a bit shift if converting
7021 to or from any unsigned fractional type because the decimal place is
7022 shifted by 1 bit. When the destination is a signed fractional, the sign
7023 is stored in either the carry or T bit. */
7025 const char*
7026 avr_out_fract (rtx insn, rtx operands[], bool intsigned, int *plen)
7028 size_t i;
7029 rtx xop[6];
7030 RTX_CODE shift = UNKNOWN;
7031 bool sign_in_carry = false;
7032 bool msb_in_carry = false;
7033 bool lsb_in_carry = false;
7034 const char *code_ashift = "lsl %0";
7037 #define MAY_CLOBBER(RR) \
7038 /* Shorthand used below. */ \
7039 ((sign_bytes \
7040 && IN_RANGE (RR, dest.regno_msb - sign_bytes + 1, dest.regno_msb)) \
7041 || (reg_unused_after (insn, all_regs_rtx[RR]) \
7042 && !IN_RANGE (RR, dest.regno, dest.regno_msb)))
7044 struct
7046 /* bytes : Length of operand in bytes.
7047 ibyte : Length of integral part in bytes.
7048 fbyte, fbit : Length of fractional part in bytes, bits. */
7050 bool sbit;
7051 unsigned fbit, bytes, ibyte, fbyte;
7052 unsigned regno, regno_msb;
7053 } dest, src, *val[2] = { &dest, &src };
7055 if (plen)
7056 *plen = 0;
7058 /* Step 0: Determine information on source and destination operand we
7059 ====== will need in the remainder. */
7061 for (i = 0; i < sizeof (val) / sizeof (*val); i++)
7063 enum machine_mode mode;
7065 xop[i] = operands[i];
7067 mode = GET_MODE (xop[i]);
7069 val[i]->bytes = GET_MODE_SIZE (mode);
7070 val[i]->regno = REGNO (xop[i]);
7071 val[i]->regno_msb = REGNO (xop[i]) + val[i]->bytes - 1;
7073 if (SCALAR_INT_MODE_P (mode))
7075 val[i]->sbit = intsigned;
7076 val[i]->fbit = 0;
7078 else if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
7080 val[i]->sbit = SIGNED_SCALAR_FIXED_POINT_MODE_P (mode);
7081 val[i]->fbit = GET_MODE_FBIT (mode);
7083 else
7084 fatal_insn ("unsupported fixed-point conversion", insn);
7086 val[i]->fbyte = (1 + val[i]->fbit) / BITS_PER_UNIT;
7087 val[i]->ibyte = val[i]->bytes - val[i]->fbyte;
7090 // Byte offset of the decimal point taking into account different place
7091 // of the decimal point in input and output and different register numbers
7092 // of input and output.
7093 int offset = dest.regno - src.regno + dest.fbyte - src.fbyte;
7095 // Number of destination bytes that will come from sign / zero extension.
7096 int sign_bytes = (dest.ibyte - src.ibyte) * (dest.ibyte > src.ibyte);
7098 // Number of bytes at the low end to be filled with zeros.
7099 int zero_bytes = (dest.fbyte - src.fbyte) * (dest.fbyte > src.fbyte);
7101 // Do we have a 16-Bit register that is cleared?
7102 rtx clrw = NULL_RTX;
7104 bool sign_extend = src.sbit && sign_bytes;
7106 if (0 == dest.fbit % 8 && 7 == src.fbit % 8)
7107 shift = ASHIFT;
7108 else if (7 == dest.fbit % 8 && 0 == src.fbit % 8)
7109 shift = ASHIFTRT;
7110 else if (dest.fbit % 8 == src.fbit % 8)
7111 shift = UNKNOWN;
7112 else
7113 gcc_unreachable();
7115 /* Step 1: Clear bytes at the low end and copy payload bits from source
7116 ====== to destination. */
7118 int step = offset < 0 ? 1 : -1;
7119 unsigned d0 = offset < 0 ? dest.regno : dest.regno_msb;
7121 // We leared at least that number of registers.
7122 int clr_n = 0;
7124 for (; d0 >= dest.regno && d0 <= dest.regno_msb; d0 += step)
7126 // Next regno of destination is needed for MOVW
7127 unsigned d1 = d0 + step;
7129 // Current and next regno of source
7130 signed s0 = d0 - offset;
7131 signed s1 = s0 + step;
7133 // Must current resp. next regno be CLRed? This applies to the low
7134 // bytes of the destination that have no associated source bytes.
7135 bool clr0 = s0 < (signed) src.regno;
7136 bool clr1 = s1 < (signed) src.regno && d1 >= dest.regno;
7138 // First gather what code to emit (if any) and additional step to
7139 // apply if a MOVW is in use. xop[2] is destination rtx and xop[3]
7140 // is the source rtx for the current loop iteration.
7141 const char *code = NULL;
7142 int stepw = 0;
7144 if (clr0)
7146 if (AVR_HAVE_MOVW && clr1 && clrw)
7148 xop[2] = all_regs_rtx[d0 & ~1];
7149 xop[3] = clrw;
7150 code = "movw %2,%3";
7151 stepw = step;
7153 else
7155 xop[2] = all_regs_rtx[d0];
7156 code = "clr %2";
7158 if (++clr_n >= 2
7159 && !clrw
7160 && d0 % 2 == (step > 0))
7162 clrw = all_regs_rtx[d0 & ~1];
7166 else if (offset && s0 <= (signed) src.regno_msb)
7168 int movw = AVR_HAVE_MOVW && offset % 2 == 0
7169 && d0 % 2 == (offset > 0)
7170 && d1 <= dest.regno_msb && d1 >= dest.regno
7171 && s1 <= (signed) src.regno_msb && s1 >= (signed) src.regno;
7173 xop[2] = all_regs_rtx[d0 & ~movw];
7174 xop[3] = all_regs_rtx[s0 & ~movw];
7175 code = movw ? "movw %2,%3" : "mov %2,%3";
7176 stepw = step * movw;
7179 if (code)
7181 if (sign_extend && shift != ASHIFT && !sign_in_carry
7182 && (d0 == src.regno_msb || d0 + stepw == src.regno_msb))
7184 /* We are going to override the sign bit. If we sign-extend,
7185 store the sign in the Carry flag. This is not needed if
7186 the destination will be ASHIFT is the remainder because
7187 the ASHIFT will set Carry without extra instruction. */
7189 avr_asm_len ("lsl %0", &all_regs_rtx[src.regno_msb], plen, 1);
7190 sign_in_carry = true;
7193 unsigned src_msb = dest.regno_msb - sign_bytes - offset + 1;
7195 if (!sign_extend && shift == ASHIFTRT && !msb_in_carry
7196 && src.ibyte > dest.ibyte
7197 && (d0 == src_msb || d0 + stepw == src_msb))
7199 /* We are going to override the MSB. If we shift right,
7200 store the MSB in the Carry flag. This is only needed if
7201 we don't sign-extend becaue with sign-extension the MSB
7202 (the sign) will be produced by the sign extension. */
7204 avr_asm_len ("lsr %0", &all_regs_rtx[src_msb], plen, 1);
7205 msb_in_carry = true;
7208 unsigned src_lsb = dest.regno - offset -1;
7210 if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry
7211 && (d0 == src_lsb || d0 + stepw == src_lsb))
7213 /* We are going to override the new LSB; store it into carry. */
7215 avr_asm_len ("lsl %0", &all_regs_rtx[src_lsb], plen, 1);
7216 code_ashift = "rol %0";
7217 lsb_in_carry = true;
7220 avr_asm_len (code, xop, plen, 1);
7221 d0 += stepw;
7225 /* Step 2: Shift destination left by 1 bit position. This might be needed
7226 ====== for signed input and unsigned output. */
7228 if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry)
7230 unsigned s0 = dest.regno - offset -1;
7232 if (MAY_CLOBBER (s0))
7233 avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1);
7234 else
7235 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
7236 "lsl __tmp_reg__", &all_regs_rtx[s0], plen, 2);
7238 code_ashift = "rol %0";
7239 lsb_in_carry = true;
7242 if (shift == ASHIFT)
7244 for (d0 = dest.regno + zero_bytes;
7245 d0 <= dest.regno_msb - sign_bytes; d0++)
7247 avr_asm_len (code_ashift, &all_regs_rtx[d0], plen, 1);
7248 code_ashift = "rol %0";
7251 lsb_in_carry = false;
7252 sign_in_carry = true;
7255 /* Step 4a: Store MSB in carry if we don't already have it or will produce
7256 ======= it in sign-extension below. */
7258 if (!sign_extend && shift == ASHIFTRT && !msb_in_carry
7259 && src.ibyte > dest.ibyte)
7261 unsigned s0 = dest.regno_msb - sign_bytes - offset + 1;
7263 if (MAY_CLOBBER (s0))
7264 avr_asm_len ("lsr %0", &all_regs_rtx[s0], plen, 1);
7265 else
7266 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
7267 "lsr __tmp_reg__", &all_regs_rtx[s0], plen, 2);
7269 msb_in_carry = true;
7272 /* Step 3: Sign-extend or zero-extend the destination as needed.
7273 ====== */
7275 if (sign_extend && !sign_in_carry)
7277 unsigned s0 = src.regno_msb;
7279 if (MAY_CLOBBER (s0))
7280 avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1);
7281 else
7282 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
7283 "lsl __tmp_reg__", &all_regs_rtx[s0], plen, 2);
7285 sign_in_carry = true;
7288 gcc_assert (sign_in_carry + msb_in_carry + lsb_in_carry <= 1);
7290 unsigned copies = 0;
7291 rtx movw = sign_extend ? NULL_RTX : clrw;
7293 for (d0 = dest.regno_msb - sign_bytes + 1; d0 <= dest.regno_msb; d0++)
7295 if (AVR_HAVE_MOVW && movw
7296 && d0 % 2 == 0 && d0 + 1 <= dest.regno_msb)
7298 xop[2] = all_regs_rtx[d0];
7299 xop[3] = movw;
7300 avr_asm_len ("movw %2,%3", xop, plen, 1);
7301 d0++;
7303 else
7305 avr_asm_len (sign_extend ? "sbc %0,%0" : "clr %0",
7306 &all_regs_rtx[d0], plen, 1);
7308 if (++copies >= 2 && !movw && d0 % 2 == 1)
7309 movw = all_regs_rtx[d0-1];
7311 } /* for */
7314 /* Step 4: Right shift the destination. This might be needed for
7315 ====== conversions from unsigned to signed. */
7317 if (shift == ASHIFTRT)
7319 const char *code_ashiftrt = "lsr %0";
7321 if (sign_extend || msb_in_carry)
7322 code_ashiftrt = "ror %0";
7324 if (src.sbit && src.ibyte == dest.ibyte)
7325 code_ashiftrt = "asr %0";
7327 for (d0 = dest.regno_msb - sign_bytes;
7328 d0 >= dest.regno + zero_bytes - 1 && d0 >= dest.regno; d0--)
7330 avr_asm_len (code_ashiftrt, &all_regs_rtx[d0], plen, 1);
7331 code_ashiftrt = "ror %0";
7335 #undef MAY_CLOBBER
7337 return "";
7341 /* Output fixed-point rounding. XOP[0] = XOP[1] is the operand to round.
7342 XOP[2] is the rounding point, a CONST_INT. The function prints the
7343 instruction sequence if PLEN = NULL and computes the length in words
7344 of the sequence if PLEN != NULL. Most of this function deals with
7345 preparing operands for calls to `avr_out_plus' and `avr_out_bitop'. */
7347 const char*
7348 avr_out_round (rtx insn ATTRIBUTE_UNUSED, rtx *xop, int *plen)
7350 enum machine_mode mode = GET_MODE (xop[0]);
7351 enum machine_mode imode = int_mode_for_mode (mode);
7352 // The smallest fractional bit not cleared by the rounding is 2^(-RP).
7353 int fbit = (int) GET_MODE_FBIT (mode);
7354 double_int i_add = double_int_zero.set_bit (fbit-1 - INTVAL (xop[2]));
7355 // Lengths of PLUS and AND parts.
7356 int len_add = 0, *plen_add = plen ? &len_add : NULL;
7357 int len_and = 0, *plen_and = plen ? &len_and : NULL;
7359 // Add-Saturate 1/2 * 2^(-RP). Don't print the label "0:" when printing
7360 // the saturated addition so that we can emit the "rjmp 1f" before the
7361 // "0:" below.
7363 rtx xadd = const_fixed_from_double_int (i_add, mode);
7364 rtx xpattern, xsrc, op[4];
7366 xsrc = SIGNED_FIXED_POINT_MODE_P (mode)
7367 ? gen_rtx_SS_PLUS (mode, xop[1], xadd)
7368 : gen_rtx_US_PLUS (mode, xop[1], xadd);
7369 xpattern = gen_rtx_SET (VOIDmode, xop[0], xsrc);
7371 op[0] = xop[0];
7372 op[1] = xop[1];
7373 op[2] = xadd;
7374 avr_out_plus (xpattern, op, plen_add, NULL, false /* Don't print "0:" */);
7376 avr_asm_len ("rjmp 1f" CR_TAB
7377 "0:", NULL, plen_add, 1);
7379 // Keep all bits from RP and higher: ... 2^(-RP)
7380 // Clear all bits from RP+1 and lower: 2^(-RP-1) ...
7381 // Rounding point ^^^^^^^
7382 // Added above ^^^^^^^^^
7383 rtx xreg = simplify_gen_subreg (imode, xop[0], mode, 0);
7384 rtx xmask = immed_double_int_const (-i_add - i_add, imode);
7386 xpattern = gen_rtx_SET (VOIDmode, xreg, gen_rtx_AND (imode, xreg, xmask));
7388 op[0] = xreg;
7389 op[1] = xreg;
7390 op[2] = xmask;
7391 op[3] = gen_rtx_SCRATCH (QImode);
7392 avr_out_bitop (xpattern, op, plen_and);
7393 avr_asm_len ("1:", NULL, plen, 0);
7395 if (plen)
7396 *plen = len_add + len_and;
7398 return "";
7402 /* Create RTL split patterns for byte sized rotate expressions. This
7403 produces a series of move instructions and considers overlap situations.
7404 Overlapping non-HImode operands need a scratch register. */
7406 bool
7407 avr_rotate_bytes (rtx operands[])
7409 int i, j;
7410 enum machine_mode mode = GET_MODE (operands[0]);
7411 bool overlapped = reg_overlap_mentioned_p (operands[0], operands[1]);
7412 bool same_reg = rtx_equal_p (operands[0], operands[1]);
7413 int num = INTVAL (operands[2]);
7414 rtx scratch = operands[3];
7415 /* Work out if byte or word move is needed. Odd byte rotates need QImode.
7416 Word move if no scratch is needed, otherwise use size of scratch. */
7417 enum machine_mode move_mode = QImode;
7418 int move_size, offset, size;
7420 if (num & 0xf)
7421 move_mode = QImode;
7422 else if ((mode == SImode && !same_reg) || !overlapped)
7423 move_mode = HImode;
7424 else
7425 move_mode = GET_MODE (scratch);
7427 /* Force DI rotate to use QI moves since other DI moves are currently split
7428 into QI moves so forward propagation works better. */
7429 if (mode == DImode)
7430 move_mode = QImode;
7431 /* Make scratch smaller if needed. */
7432 if (SCRATCH != GET_CODE (scratch)
7433 && HImode == GET_MODE (scratch)
7434 && QImode == move_mode)
7435 scratch = simplify_gen_subreg (move_mode, scratch, HImode, 0);
7437 move_size = GET_MODE_SIZE (move_mode);
7438 /* Number of bytes/words to rotate. */
7439 offset = (num >> 3) / move_size;
7440 /* Number of moves needed. */
7441 size = GET_MODE_SIZE (mode) / move_size;
7442 /* Himode byte swap is special case to avoid a scratch register. */
7443 if (mode == HImode && same_reg)
7445 /* HImode byte swap, using xor. This is as quick as using scratch. */
7446 rtx src, dst;
7447 src = simplify_gen_subreg (move_mode, operands[1], mode, 0);
7448 dst = simplify_gen_subreg (move_mode, operands[0], mode, 1);
7449 if (!rtx_equal_p (dst, src))
7451 emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
7452 emit_move_insn (src, gen_rtx_XOR (QImode, src, dst));
7453 emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
7456 else
7458 #define MAX_SIZE 8 /* GET_MODE_SIZE (DImode) / GET_MODE_SIZE (QImode) */
7459 /* Create linked list of moves to determine move order. */
7460 struct {
7461 rtx src, dst;
7462 int links;
7463 } move[MAX_SIZE + 8];
7464 int blocked, moves;
7466 gcc_assert (size <= MAX_SIZE);
7467 /* Generate list of subreg moves. */
7468 for (i = 0; i < size; i++)
7470 int from = i;
7471 int to = (from + offset) % size;
7472 move[i].src = simplify_gen_subreg (move_mode, operands[1],
7473 mode, from * move_size);
7474 move[i].dst = simplify_gen_subreg (move_mode, operands[0],
7475 mode, to * move_size);
7476 move[i].links = -1;
7478 /* Mark dependence where a dst of one move is the src of another move.
7479 The first move is a conflict as it must wait until second is
7480 performed. We ignore moves to self - we catch this later. */
7481 if (overlapped)
7482 for (i = 0; i < size; i++)
7483 if (reg_overlap_mentioned_p (move[i].dst, operands[1]))
7484 for (j = 0; j < size; j++)
7485 if (j != i && rtx_equal_p (move[j].src, move[i].dst))
7487 /* The dst of move i is the src of move j. */
7488 move[i].links = j;
7489 break;
7492 blocked = -1;
7493 moves = 0;
7494 /* Go through move list and perform non-conflicting moves. As each
7495 non-overlapping move is made, it may remove other conflicts
7496 so the process is repeated until no conflicts remain. */
7499 blocked = -1;
7500 moves = 0;
7501 /* Emit move where dst is not also a src or we have used that
7502 src already. */
7503 for (i = 0; i < size; i++)
7504 if (move[i].src != NULL_RTX)
7506 if (move[i].links == -1
7507 || move[move[i].links].src == NULL_RTX)
7509 moves++;
7510 /* Ignore NOP moves to self. */
7511 if (!rtx_equal_p (move[i].dst, move[i].src))
7512 emit_move_insn (move[i].dst, move[i].src);
7514 /* Remove conflict from list. */
7515 move[i].src = NULL_RTX;
7517 else
7518 blocked = i;
7521 /* Check for deadlock. This is when no moves occurred and we have
7522 at least one blocked move. */
7523 if (moves == 0 && blocked != -1)
7525 /* Need to use scratch register to break deadlock.
7526 Add move to put dst of blocked move into scratch.
7527 When this move occurs, it will break chain deadlock.
7528 The scratch register is substituted for real move. */
7530 gcc_assert (SCRATCH != GET_CODE (scratch));
7532 move[size].src = move[blocked].dst;
7533 move[size].dst = scratch;
7534 /* Scratch move is never blocked. */
7535 move[size].links = -1;
7536 /* Make sure we have valid link. */
7537 gcc_assert (move[blocked].links != -1);
7538 /* Replace src of blocking move with scratch reg. */
7539 move[move[blocked].links].src = scratch;
7540 /* Make dependent on scratch move occurring. */
7541 move[blocked].links = size;
7542 size=size+1;
7545 while (blocked != -1);
7547 return true;
7551 /* Worker function for `ADJUST_INSN_LENGTH'. */
7552 /* Modifies the length assigned to instruction INSN
7553 LEN is the initially computed length of the insn. */
7556 avr_adjust_insn_length (rtx insn, int len)
7558 rtx *op = recog_data.operand;
7559 enum attr_adjust_len adjust_len;
7561 /* Some complex insns don't need length adjustment and therefore
7562 the length need not/must not be adjusted for these insns.
7563 It is easier to state this in an insn attribute "adjust_len" than
7564 to clutter up code here... */
7566 if (-1 == recog_memoized (insn))
7568 return len;
7571 /* Read from insn attribute "adjust_len" if/how length is to be adjusted. */
7573 adjust_len = get_attr_adjust_len (insn);
7575 if (adjust_len == ADJUST_LEN_NO)
7577 /* Nothing to adjust: The length from attribute "length" is fine.
7578 This is the default. */
7580 return len;
7583 /* Extract insn's operands. */
7585 extract_constrain_insn_cached (insn);
7587 /* Dispatch to right function. */
7589 switch (adjust_len)
7591 case ADJUST_LEN_RELOAD_IN16: output_reload_inhi (op, op[2], &len); break;
7592 case ADJUST_LEN_RELOAD_IN24: avr_out_reload_inpsi (op, op[2], &len); break;
7593 case ADJUST_LEN_RELOAD_IN32: output_reload_insisf (op, op[2], &len); break;
7595 case ADJUST_LEN_OUT_BITOP: avr_out_bitop (insn, op, &len); break;
7597 case ADJUST_LEN_PLUS: avr_out_plus (insn, op, &len); break;
7598 case ADJUST_LEN_ADDTO_SP: avr_out_addto_sp (op, &len); break;
7600 case ADJUST_LEN_MOV8: output_movqi (insn, op, &len); break;
7601 case ADJUST_LEN_MOV16: output_movhi (insn, op, &len); break;
7602 case ADJUST_LEN_MOV24: avr_out_movpsi (insn, op, &len); break;
7603 case ADJUST_LEN_MOV32: output_movsisf (insn, op, &len); break;
7604 case ADJUST_LEN_MOVMEM: avr_out_movmem (insn, op, &len); break;
7605 case ADJUST_LEN_XLOAD: avr_out_xload (insn, op, &len); break;
7606 case ADJUST_LEN_LPM: avr_out_lpm (insn, op, &len); break;
7608 case ADJUST_LEN_SFRACT: avr_out_fract (insn, op, true, &len); break;
7609 case ADJUST_LEN_UFRACT: avr_out_fract (insn, op, false, &len); break;
7610 case ADJUST_LEN_ROUND: avr_out_round (insn, op, &len); break;
7612 case ADJUST_LEN_TSTHI: avr_out_tsthi (insn, op, &len); break;
7613 case ADJUST_LEN_TSTPSI: avr_out_tstpsi (insn, op, &len); break;
7614 case ADJUST_LEN_TSTSI: avr_out_tstsi (insn, op, &len); break;
7615 case ADJUST_LEN_COMPARE: avr_out_compare (insn, op, &len); break;
7616 case ADJUST_LEN_COMPARE64: avr_out_compare64 (insn, op, &len); break;
7618 case ADJUST_LEN_LSHRQI: lshrqi3_out (insn, op, &len); break;
7619 case ADJUST_LEN_LSHRHI: lshrhi3_out (insn, op, &len); break;
7620 case ADJUST_LEN_LSHRSI: lshrsi3_out (insn, op, &len); break;
7622 case ADJUST_LEN_ASHRQI: ashrqi3_out (insn, op, &len); break;
7623 case ADJUST_LEN_ASHRHI: ashrhi3_out (insn, op, &len); break;
7624 case ADJUST_LEN_ASHRSI: ashrsi3_out (insn, op, &len); break;
7626 case ADJUST_LEN_ASHLQI: ashlqi3_out (insn, op, &len); break;
7627 case ADJUST_LEN_ASHLHI: ashlhi3_out (insn, op, &len); break;
7628 case ADJUST_LEN_ASHLSI: ashlsi3_out (insn, op, &len); break;
7630 case ADJUST_LEN_ASHLPSI: avr_out_ashlpsi3 (insn, op, &len); break;
7631 case ADJUST_LEN_ASHRPSI: avr_out_ashrpsi3 (insn, op, &len); break;
7632 case ADJUST_LEN_LSHRPSI: avr_out_lshrpsi3 (insn, op, &len); break;
7634 case ADJUST_LEN_CALL: len = AVR_HAVE_JMP_CALL ? 2 : 1; break;
7636 case ADJUST_LEN_INSERT_BITS: avr_out_insert_bits (op, &len); break;
7638 default:
7639 gcc_unreachable();
7642 return len;
7645 /* Return nonzero if register REG dead after INSN. */
7648 reg_unused_after (rtx insn, rtx reg)
7650 return (dead_or_set_p (insn, reg)
7651 || (REG_P(reg) && _reg_unused_after (insn, reg)));
7654 /* Return nonzero if REG is not used after INSN.
7655 We assume REG is a reload reg, and therefore does
7656 not live past labels. It may live past calls or jumps though. */
7659 _reg_unused_after (rtx insn, rtx reg)
7661 enum rtx_code code;
7662 rtx set;
7664 /* If the reg is set by this instruction, then it is safe for our
7665 case. Disregard the case where this is a store to memory, since
7666 we are checking a register used in the store address. */
7667 set = single_set (insn);
7668 if (set && GET_CODE (SET_DEST (set)) != MEM
7669 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
7670 return 1;
7672 while ((insn = NEXT_INSN (insn)))
7674 rtx set;
7675 code = GET_CODE (insn);
7677 #if 0
7678 /* If this is a label that existed before reload, then the register
7679 if dead here. However, if this is a label added by reorg, then
7680 the register may still be live here. We can't tell the difference,
7681 so we just ignore labels completely. */
7682 if (code == CODE_LABEL)
7683 return 1;
7684 /* else */
7685 #endif
7687 if (!INSN_P (insn))
7688 continue;
7690 if (code == JUMP_INSN)
7691 return 0;
7693 /* If this is a sequence, we must handle them all at once.
7694 We could have for instance a call that sets the target register,
7695 and an insn in a delay slot that uses the register. In this case,
7696 we must return 0. */
7697 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
7699 int i;
7700 int retval = 0;
7702 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
7704 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
7705 rtx set = single_set (this_insn);
7707 if (CALL_P (this_insn))
7708 code = CALL_INSN;
7709 else if (JUMP_P (this_insn))
7711 if (INSN_ANNULLED_BRANCH_P (this_insn))
7712 return 0;
7713 code = JUMP_INSN;
7716 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
7717 return 0;
7718 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
7720 if (GET_CODE (SET_DEST (set)) != MEM)
7721 retval = 1;
7722 else
7723 return 0;
7725 if (set == 0
7726 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
7727 return 0;
7729 if (retval == 1)
7730 return 1;
7731 else if (code == JUMP_INSN)
7732 return 0;
7735 if (code == CALL_INSN)
7737 rtx tem;
7738 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
7739 if (GET_CODE (XEXP (tem, 0)) == USE
7740 && REG_P (XEXP (XEXP (tem, 0), 0))
7741 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
7742 return 0;
7743 if (call_used_regs[REGNO (reg)])
7744 return 1;
7747 set = single_set (insn);
7749 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
7750 return 0;
7751 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
7752 return GET_CODE (SET_DEST (set)) != MEM;
7753 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
7754 return 0;
7756 return 1;
7760 /* Implement `TARGET_ASM_INTEGER'. */
7761 /* Target hook for assembling integer objects. The AVR version needs
7762 special handling for references to certain labels. */
7764 static bool
7765 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
7767 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
7768 && text_segment_operand (x, VOIDmode))
7770 fputs ("\t.word\tgs(", asm_out_file);
7771 output_addr_const (asm_out_file, x);
7772 fputs (")\n", asm_out_file);
7774 return true;
7776 else if (GET_MODE (x) == PSImode)
7778 /* This needs binutils 2.23+, see PR binutils/13503 */
7780 fputs ("\t.byte\tlo8(", asm_out_file);
7781 output_addr_const (asm_out_file, x);
7782 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
7784 fputs ("\t.byte\thi8(", asm_out_file);
7785 output_addr_const (asm_out_file, x);
7786 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
7788 fputs ("\t.byte\thh8(", asm_out_file);
7789 output_addr_const (asm_out_file, x);
7790 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
7792 return true;
7794 else if (CONST_FIXED_P (x))
7796 unsigned n;
7798 /* varasm fails to handle big fixed modes that don't fit in hwi. */
7800 for (n = 0; n < size; n++)
7802 rtx xn = simplify_gen_subreg (QImode, x, GET_MODE (x), n);
7803 default_assemble_integer (xn, 1, aligned_p);
7806 return true;
7809 return default_assemble_integer (x, size, aligned_p);
7813 /* Implement `TARGET_CLASS_LIKELY_SPILLED_P'. */
7814 /* Return value is nonzero if pseudos that have been
7815 assigned to registers of class CLASS would likely be spilled
7816 because registers of CLASS are needed for spill registers. */
7818 static bool
7819 avr_class_likely_spilled_p (reg_class_t c)
7821 return (c != ALL_REGS && c != ADDW_REGS);
7825 /* Valid attributes:
7826 progmem - Put data to program memory.
7827 signal - Make a function to be hardware interrupt.
7828 After function prologue interrupts remain disabled.
7829 interrupt - Make a function to be hardware interrupt. Before function
7830 prologue interrupts are enabled by means of SEI.
7831 naked - Don't generate function prologue/epilogue and RET
7832 instruction. */
7834 /* Handle a "progmem" attribute; arguments as in
7835 struct attribute_spec.handler. */
7837 static tree
7838 avr_handle_progmem_attribute (tree *node, tree name,
7839 tree args ATTRIBUTE_UNUSED,
7840 int flags ATTRIBUTE_UNUSED,
7841 bool *no_add_attrs)
7843 if (DECL_P (*node))
7845 if (TREE_CODE (*node) == TYPE_DECL)
7847 /* This is really a decl attribute, not a type attribute,
7848 but try to handle it for GCC 3.0 backwards compatibility. */
7850 tree type = TREE_TYPE (*node);
7851 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
7852 tree newtype = build_type_attribute_variant (type, attr);
7854 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
7855 TREE_TYPE (*node) = newtype;
7856 *no_add_attrs = true;
7858 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
7860 *no_add_attrs = false;
7862 else
7864 warning (OPT_Wattributes, "%qE attribute ignored",
7865 name);
7866 *no_add_attrs = true;
7870 return NULL_TREE;
7873 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
7874 struct attribute_spec.handler. */
7876 static tree
7877 avr_handle_fndecl_attribute (tree *node, tree name,
7878 tree args ATTRIBUTE_UNUSED,
7879 int flags ATTRIBUTE_UNUSED,
7880 bool *no_add_attrs)
7882 if (TREE_CODE (*node) != FUNCTION_DECL)
7884 warning (OPT_Wattributes, "%qE attribute only applies to functions",
7885 name);
7886 *no_add_attrs = true;
7889 return NULL_TREE;
7892 static tree
7893 avr_handle_fntype_attribute (tree *node, tree name,
7894 tree args ATTRIBUTE_UNUSED,
7895 int flags ATTRIBUTE_UNUSED,
7896 bool *no_add_attrs)
7898 if (TREE_CODE (*node) != FUNCTION_TYPE)
7900 warning (OPT_Wattributes, "%qE attribute only applies to functions",
7901 name);
7902 *no_add_attrs = true;
7905 return NULL_TREE;
7909 /* AVR attributes. */
7910 static const struct attribute_spec
7911 avr_attribute_table[] =
7913 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
7914 affects_type_identity } */
7915 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute,
7916 false },
7917 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute,
7918 false },
7919 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute,
7920 false },
7921 { "naked", 0, 0, false, true, true, avr_handle_fntype_attribute,
7922 false },
7923 { "OS_task", 0, 0, false, true, true, avr_handle_fntype_attribute,
7924 false },
7925 { "OS_main", 0, 0, false, true, true, avr_handle_fntype_attribute,
7926 false },
7927 { NULL, 0, 0, false, false, false, NULL, false }
7931 /* Look if DECL shall be placed in program memory space by
7932 means of attribute `progmem' or some address-space qualifier.
7933 Return non-zero if DECL is data that must end up in Flash and
7934 zero if the data lives in RAM (.bss, .data, .rodata, ...).
7936 Return 2 if DECL is located in 24-bit flash address-space
7937 Return 1 if DECL is located in 16-bit flash address-space
7938 Return -1 if attribute `progmem' occurs in DECL or ATTRIBUTES
7939 Return 0 otherwise */
7942 avr_progmem_p (tree decl, tree attributes)
7944 tree a;
7946 if (TREE_CODE (decl) != VAR_DECL)
7947 return 0;
7949 if (avr_decl_memx_p (decl))
7950 return 2;
7952 if (avr_decl_flash_p (decl))
7953 return 1;
7955 if (NULL_TREE
7956 != lookup_attribute ("progmem", attributes))
7957 return -1;
7959 a = decl;
7962 a = TREE_TYPE(a);
7963 while (TREE_CODE (a) == ARRAY_TYPE);
7965 if (a == error_mark_node)
7966 return 0;
7968 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
7969 return -1;
7971 return 0;
7975 /* Scan type TYP for pointer references to address space ASn.
7976 Return ADDR_SPACE_GENERIC (i.e. 0) if all pointers targeting
7977 the AS are also declared to be CONST.
7978 Otherwise, return the respective address space, i.e. a value != 0. */
7980 static addr_space_t
7981 avr_nonconst_pointer_addrspace (tree typ)
7983 while (ARRAY_TYPE == TREE_CODE (typ))
7984 typ = TREE_TYPE (typ);
7986 if (POINTER_TYPE_P (typ))
7988 addr_space_t as;
7989 tree target = TREE_TYPE (typ);
7991 /* Pointer to function: Test the function's return type. */
7993 if (FUNCTION_TYPE == TREE_CODE (target))
7994 return avr_nonconst_pointer_addrspace (TREE_TYPE (target));
7996 /* "Ordinary" pointers... */
7998 while (TREE_CODE (target) == ARRAY_TYPE)
7999 target = TREE_TYPE (target);
8001 /* Pointers to non-generic address space must be const.
8002 Refuse address spaces outside the device's flash. */
8004 as = TYPE_ADDR_SPACE (target);
8006 if (!ADDR_SPACE_GENERIC_P (as)
8007 && (!TYPE_READONLY (target)
8008 || avr_addrspace[as].segment >= avr_current_device->n_flash))
8010 return as;
8013 /* Scan pointer's target type. */
8015 return avr_nonconst_pointer_addrspace (target);
8018 return ADDR_SPACE_GENERIC;
8022 /* Sanity check NODE so that all pointers targeting non-generic address spaces
8023 go along with CONST qualifier. Writing to these address spaces should
8024 be detected and complained about as early as possible. */
8026 static bool
8027 avr_pgm_check_var_decl (tree node)
8029 const char *reason = NULL;
8031 addr_space_t as = ADDR_SPACE_GENERIC;
8033 gcc_assert (as == 0);
8035 if (avr_log.progmem)
8036 avr_edump ("%?: %t\n", node);
8038 switch (TREE_CODE (node))
8040 default:
8041 break;
8043 case VAR_DECL:
8044 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
8045 reason = "variable";
8046 break;
8048 case PARM_DECL:
8049 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
8050 reason = "function parameter";
8051 break;
8053 case FIELD_DECL:
8054 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
8055 reason = "structure field";
8056 break;
8058 case FUNCTION_DECL:
8059 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (TREE_TYPE (node))),
8061 reason = "return type of function";
8062 break;
8064 case POINTER_TYPE:
8065 if (as = avr_nonconst_pointer_addrspace (node), as)
8066 reason = "pointer";
8067 break;
8070 if (reason)
8072 if (avr_addrspace[as].segment >= avr_current_device->n_flash)
8074 if (TYPE_P (node))
8075 error ("%qT uses address space %qs beyond flash of %qs",
8076 node, avr_addrspace[as].name, avr_current_device->name);
8077 else
8078 error ("%s %q+D uses address space %qs beyond flash of %qs",
8079 reason, node, avr_addrspace[as].name,
8080 avr_current_device->name);
8082 else
8084 if (TYPE_P (node))
8085 error ("pointer targeting address space %qs must be const in %qT",
8086 avr_addrspace[as].name, node);
8087 else
8088 error ("pointer targeting address space %qs must be const"
8089 " in %s %q+D",
8090 avr_addrspace[as].name, reason, node);
8094 return reason == NULL;
8098 /* Add the section attribute if the variable is in progmem. */
8100 static void
8101 avr_insert_attributes (tree node, tree *attributes)
8103 avr_pgm_check_var_decl (node);
8105 if (TREE_CODE (node) == VAR_DECL
8106 && (TREE_STATIC (node) || DECL_EXTERNAL (node))
8107 && avr_progmem_p (node, *attributes))
8109 addr_space_t as;
8110 tree node0 = node;
8112 /* For C++, we have to peel arrays in order to get correct
8113 determination of readonlyness. */
8116 node0 = TREE_TYPE (node0);
8117 while (TREE_CODE (node0) == ARRAY_TYPE);
8119 if (error_mark_node == node0)
8120 return;
8122 as = TYPE_ADDR_SPACE (TREE_TYPE (node));
8124 if (avr_addrspace[as].segment >= avr_current_device->n_flash)
8126 error ("variable %q+D located in address space %qs"
8127 " beyond flash of %qs",
8128 node, avr_addrspace[as].name, avr_current_device->name);
8131 if (!TYPE_READONLY (node0)
8132 && !TREE_READONLY (node))
8134 const char *reason = "__attribute__((progmem))";
8136 if (!ADDR_SPACE_GENERIC_P (as))
8137 reason = avr_addrspace[as].name;
8139 if (avr_log.progmem)
8140 avr_edump ("\n%?: %t\n%t\n", node, node0);
8142 error ("variable %q+D must be const in order to be put into"
8143 " read-only section by means of %qs", node, reason);
8149 /* Implement `ASM_OUTPUT_ALIGNED_DECL_LOCAL'. */
8150 /* Implement `ASM_OUTPUT_ALIGNED_DECL_COMMON'. */
8151 /* Track need of __do_clear_bss. */
8153 void
8154 avr_asm_output_aligned_decl_common (FILE * stream,
8155 const_tree decl ATTRIBUTE_UNUSED,
8156 const char *name,
8157 unsigned HOST_WIDE_INT size,
8158 unsigned int align, bool local_p)
8160 /* __gnu_lto_v1 etc. are just markers for the linker injected by toplev.c.
8161 There is no need to trigger __do_clear_bss code for them. */
8163 if (!STR_PREFIX_P (name, "__gnu_lto"))
8164 avr_need_clear_bss_p = true;
8166 if (local_p)
8167 ASM_OUTPUT_ALIGNED_LOCAL (stream, name, size, align);
8168 else
8169 ASM_OUTPUT_ALIGNED_COMMON (stream, name, size, align);
8173 /* Unnamed section callback for data_section
8174 to track need of __do_copy_data. */
8176 static void
8177 avr_output_data_section_asm_op (const void *data)
8179 avr_need_copy_data_p = true;
8181 /* Dispatch to default. */
8182 output_section_asm_op (data);
8186 /* Unnamed section callback for bss_section
8187 to track need of __do_clear_bss. */
8189 static void
8190 avr_output_bss_section_asm_op (const void *data)
8192 avr_need_clear_bss_p = true;
8194 /* Dispatch to default. */
8195 output_section_asm_op (data);
8199 /* Unnamed section callback for progmem*.data sections. */
8201 static void
8202 avr_output_progmem_section_asm_op (const void *data)
8204 fprintf (asm_out_file, "\t.section\t%s,\"a\",@progbits\n",
8205 (const char*) data);
8209 /* Implement `TARGET_ASM_INIT_SECTIONS'. */
8211 static void
8212 avr_asm_init_sections (void)
8214 /* Set up a section for jump tables. Alignment is handled by
8215 ASM_OUTPUT_BEFORE_CASE_LABEL. */
8217 if (AVR_HAVE_JMP_CALL)
8219 progmem_swtable_section
8220 = get_unnamed_section (0, output_section_asm_op,
8221 "\t.section\t.progmem.gcc_sw_table"
8222 ",\"a\",@progbits");
8224 else
8226 progmem_swtable_section
8227 = get_unnamed_section (SECTION_CODE, output_section_asm_op,
8228 "\t.section\t.progmem.gcc_sw_table"
8229 ",\"ax\",@progbits");
8232 /* Override section callbacks to keep track of `avr_need_clear_bss_p'
8233 resp. `avr_need_copy_data_p'. */
8235 readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
8236 data_section->unnamed.callback = avr_output_data_section_asm_op;
8237 bss_section->unnamed.callback = avr_output_bss_section_asm_op;
8241 /* Implement `TARGET_ASM_FUNCTION_RODATA_SECTION'. */
8243 static section*
8244 avr_asm_function_rodata_section (tree decl)
8246 /* If a function is unused and optimized out by -ffunction-sections
8247 and --gc-sections, ensure that the same will happen for its jump
8248 tables by putting them into individual sections. */
8250 unsigned int flags;
8251 section * frodata;
8253 /* Get the frodata section from the default function in varasm.c
8254 but treat function-associated data-like jump tables as code
8255 rather than as user defined data. AVR has no constant pools. */
8257 int fdata = flag_data_sections;
8259 flag_data_sections = flag_function_sections;
8260 frodata = default_function_rodata_section (decl);
8261 flag_data_sections = fdata;
8262 flags = frodata->common.flags;
8265 if (frodata != readonly_data_section
8266 && flags & SECTION_NAMED)
8268 /* Adjust section flags and replace section name prefix. */
8270 unsigned int i;
8272 static const char* const prefix[] =
8274 ".rodata", ".progmem.gcc_sw_table",
8275 ".gnu.linkonce.r.", ".gnu.linkonce.t."
8278 for (i = 0; i < sizeof (prefix) / sizeof (*prefix); i += 2)
8280 const char * old_prefix = prefix[i];
8281 const char * new_prefix = prefix[i+1];
8282 const char * name = frodata->named.name;
8284 if (STR_PREFIX_P (name, old_prefix))
8286 const char *rname = ACONCAT ((new_prefix,
8287 name + strlen (old_prefix), NULL));
8288 flags &= ~SECTION_CODE;
8289 flags |= AVR_HAVE_JMP_CALL ? 0 : SECTION_CODE;
8291 return get_section (rname, flags, frodata->named.decl);
8296 return progmem_swtable_section;
8300 /* Implement `TARGET_ASM_NAMED_SECTION'. */
8301 /* Track need of __do_clear_bss, __do_copy_data for named sections. */
8303 static void
8304 avr_asm_named_section (const char *name, unsigned int flags, tree decl)
8306 if (flags & AVR_SECTION_PROGMEM)
8308 addr_space_t as = (flags & AVR_SECTION_PROGMEM) / SECTION_MACH_DEP;
8309 const char *old_prefix = ".rodata";
8310 const char *new_prefix = avr_addrspace[as].section_name;
8312 if (STR_PREFIX_P (name, old_prefix))
8314 const char *sname = ACONCAT ((new_prefix,
8315 name + strlen (old_prefix), NULL));
8316 default_elf_asm_named_section (sname, flags, decl);
8317 return;
8320 default_elf_asm_named_section (new_prefix, flags, decl);
8321 return;
8324 if (!avr_need_copy_data_p)
8325 avr_need_copy_data_p = (STR_PREFIX_P (name, ".data")
8326 || STR_PREFIX_P (name, ".rodata")
8327 || STR_PREFIX_P (name, ".gnu.linkonce.d"));
8329 if (!avr_need_clear_bss_p)
8330 avr_need_clear_bss_p = STR_PREFIX_P (name, ".bss");
8332 default_elf_asm_named_section (name, flags, decl);
8336 /* Implement `TARGET_SECTION_TYPE_FLAGS'. */
8338 static unsigned int
8339 avr_section_type_flags (tree decl, const char *name, int reloc)
8341 unsigned int flags = default_section_type_flags (decl, name, reloc);
8343 if (STR_PREFIX_P (name, ".noinit"))
8345 if (decl && TREE_CODE (decl) == VAR_DECL
8346 && DECL_INITIAL (decl) == NULL_TREE)
8347 flags |= SECTION_BSS; /* @nobits */
8348 else
8349 warning (0, "only uninitialized variables can be placed in the "
8350 ".noinit section");
8353 if (decl && DECL_P (decl)
8354 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
8356 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
8358 /* Attribute progmem puts data in generic address space.
8359 Set section flags as if it was in __flash to get the right
8360 section prefix in the remainder. */
8362 if (ADDR_SPACE_GENERIC_P (as))
8363 as = ADDR_SPACE_FLASH;
8365 flags |= as * SECTION_MACH_DEP;
8366 flags &= ~SECTION_WRITE;
8367 flags &= ~SECTION_BSS;
8370 return flags;
8374 /* Implement `TARGET_ENCODE_SECTION_INFO'. */
8376 static void
8377 avr_encode_section_info (tree decl, rtx rtl, int new_decl_p)
8379 /* In avr_handle_progmem_attribute, DECL_INITIAL is not yet
8380 readily available, see PR34734. So we postpone the warning
8381 about uninitialized data in program memory section until here. */
8383 if (new_decl_p
8384 && decl && DECL_P (decl)
8385 && NULL_TREE == DECL_INITIAL (decl)
8386 && !DECL_EXTERNAL (decl)
8387 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
8389 warning (OPT_Wuninitialized,
8390 "uninitialized variable %q+D put into "
8391 "program memory area", decl);
8394 default_encode_section_info (decl, rtl, new_decl_p);
8396 if (decl && DECL_P (decl)
8397 && TREE_CODE (decl) != FUNCTION_DECL
8398 && MEM_P (rtl)
8399 && SYMBOL_REF == GET_CODE (XEXP (rtl, 0)))
8401 rtx sym = XEXP (rtl, 0);
8402 tree type = TREE_TYPE (decl);
8403 if (type == error_mark_node)
8404 return;
8405 addr_space_t as = TYPE_ADDR_SPACE (type);
8407 /* PSTR strings are in generic space but located in flash:
8408 patch address space. */
8410 if (-1 == avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
8411 as = ADDR_SPACE_FLASH;
8413 AVR_SYMBOL_SET_ADDR_SPACE (sym, as);
8418 /* Implement `TARGET_ASM_SELECT_SECTION' */
8420 static section *
8421 avr_asm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
8423 section * sect = default_elf_select_section (decl, reloc, align);
8425 if (decl && DECL_P (decl)
8426 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
8428 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
8430 /* __progmem__ goes in generic space but shall be allocated to
8431 .progmem.data */
8433 if (ADDR_SPACE_GENERIC_P (as))
8434 as = ADDR_SPACE_FLASH;
8436 if (sect->common.flags & SECTION_NAMED)
8438 const char * name = sect->named.name;
8439 const char * old_prefix = ".rodata";
8440 const char * new_prefix = avr_addrspace[as].section_name;
8442 if (STR_PREFIX_P (name, old_prefix))
8444 const char *sname = ACONCAT ((new_prefix,
8445 name + strlen (old_prefix), NULL));
8446 return get_section (sname, sect->common.flags, sect->named.decl);
8450 if (!progmem_section[as])
8452 progmem_section[as]
8453 = get_unnamed_section (0, avr_output_progmem_section_asm_op,
8454 avr_addrspace[as].section_name);
8457 return progmem_section[as];
8460 return sect;
8463 /* Implement `TARGET_ASM_FILE_START'. */
8464 /* Outputs some text at the start of each assembler file. */
8466 static void
8467 avr_file_start (void)
8469 int sfr_offset = avr_current_arch->sfr_offset;
8471 if (avr_current_arch->asm_only)
8472 error ("MCU %qs supported for assembler only", avr_current_device->name);
8474 default_file_start ();
8476 /* Print I/O addresses of some SFRs used with IN and OUT. */
8478 if (AVR_HAVE_SPH)
8479 fprintf (asm_out_file, "__SP_H__ = 0x%02x\n", avr_addr.sp_h - sfr_offset);
8481 fprintf (asm_out_file, "__SP_L__ = 0x%02x\n", avr_addr.sp_l - sfr_offset);
8482 fprintf (asm_out_file, "__SREG__ = 0x%02x\n", avr_addr.sreg - sfr_offset);
8483 if (AVR_HAVE_RAMPZ)
8484 fprintf (asm_out_file, "__RAMPZ__ = 0x%02x\n", avr_addr.rampz - sfr_offset);
8485 if (AVR_HAVE_RAMPY)
8486 fprintf (asm_out_file, "__RAMPY__ = 0x%02x\n", avr_addr.rampy - sfr_offset);
8487 if (AVR_HAVE_RAMPX)
8488 fprintf (asm_out_file, "__RAMPX__ = 0x%02x\n", avr_addr.rampx - sfr_offset);
8489 if (AVR_HAVE_RAMPD)
8490 fprintf (asm_out_file, "__RAMPD__ = 0x%02x\n", avr_addr.rampd - sfr_offset);
8491 if (AVR_XMEGA)
8492 fprintf (asm_out_file, "__CCP__ = 0x%02x\n", avr_addr.ccp - sfr_offset);
8493 fprintf (asm_out_file, "__tmp_reg__ = %d\n", TMP_REGNO);
8494 fprintf (asm_out_file, "__zero_reg__ = %d\n", ZERO_REGNO);
8498 /* Implement `TARGET_ASM_FILE_END'. */
8499 /* Outputs to the stdio stream FILE some
8500 appropriate text to go at the end of an assembler file. */
8502 static void
8503 avr_file_end (void)
8505 /* Output these only if there is anything in the
8506 .data* / .rodata* / .gnu.linkonce.* resp. .bss* or COMMON
8507 input section(s) - some code size can be saved by not
8508 linking in the initialization code from libgcc if resp.
8509 sections are empty, see PR18145. */
8511 if (avr_need_copy_data_p)
8512 fputs (".global __do_copy_data\n", asm_out_file);
8514 if (avr_need_clear_bss_p)
8515 fputs (".global __do_clear_bss\n", asm_out_file);
8519 /* Worker function for `ADJUST_REG_ALLOC_ORDER'. */
8520 /* Choose the order in which to allocate hard registers for
8521 pseudo-registers local to a basic block.
8523 Store the desired register order in the array `reg_alloc_order'.
8524 Element 0 should be the register to allocate first; element 1, the
8525 next register; and so on. */
8527 void
8528 avr_adjust_reg_alloc_order (void)
8530 unsigned int i;
8531 static const int order_0[] =
8533 24, 25,
8534 18, 19, 20, 21, 22, 23,
8535 30, 31,
8536 26, 27, 28, 29,
8537 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
8538 0, 1,
8539 32, 33, 34, 35
8541 static const int order_1[] =
8543 18, 19, 20, 21, 22, 23, 24, 25,
8544 30, 31,
8545 26, 27, 28, 29,
8546 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
8547 0, 1,
8548 32, 33, 34, 35
8550 static const int order_2[] =
8552 25, 24, 23, 22, 21, 20, 19, 18,
8553 30, 31,
8554 26, 27, 28, 29,
8555 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
8556 1, 0,
8557 32, 33, 34, 35
8560 const int *order = (TARGET_ORDER_1 ? order_1 :
8561 TARGET_ORDER_2 ? order_2 :
8562 order_0);
8563 for (i = 0; i < ARRAY_SIZE (order_0); ++i)
8564 reg_alloc_order[i] = order[i];
8568 /* Implement `TARGET_REGISTER_MOVE_COST' */
8570 static int
8571 avr_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
8572 reg_class_t from, reg_class_t to)
8574 return (from == STACK_REG ? 6
8575 : to == STACK_REG ? 12
8576 : 2);
8580 /* Implement `TARGET_MEMORY_MOVE_COST' */
8582 static int
8583 avr_memory_move_cost (enum machine_mode mode,
8584 reg_class_t rclass ATTRIBUTE_UNUSED,
8585 bool in ATTRIBUTE_UNUSED)
8587 return (mode == QImode ? 2
8588 : mode == HImode ? 4
8589 : mode == SImode ? 8
8590 : mode == SFmode ? 8
8591 : 16);
8595 /* Mutually recursive subroutine of avr_rtx_cost for calculating the
8596 cost of an RTX operand given its context. X is the rtx of the
8597 operand, MODE is its mode, and OUTER is the rtx_code of this
8598 operand's parent operator. */
8600 static int
8601 avr_operand_rtx_cost (rtx x, enum machine_mode mode, enum rtx_code outer,
8602 int opno, bool speed)
8604 enum rtx_code code = GET_CODE (x);
8605 int total;
8607 switch (code)
8609 case REG:
8610 case SUBREG:
8611 return 0;
8613 case CONST_INT:
8614 case CONST_FIXED:
8615 case CONST_DOUBLE:
8616 return COSTS_N_INSNS (GET_MODE_SIZE (mode));
8618 default:
8619 break;
8622 total = 0;
8623 avr_rtx_costs (x, code, outer, opno, &total, speed);
8624 return total;
8627 /* Worker function for AVR backend's rtx_cost function.
8628 X is rtx expression whose cost is to be calculated.
8629 Return true if the complete cost has been computed.
8630 Return false if subexpressions should be scanned.
8631 In either case, *TOTAL contains the cost result. */
8633 static bool
8634 avr_rtx_costs_1 (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED,
8635 int opno ATTRIBUTE_UNUSED, int *total, bool speed)
8637 enum rtx_code code = (enum rtx_code) codearg;
8638 enum machine_mode mode = GET_MODE (x);
8639 HOST_WIDE_INT val;
8641 switch (code)
8643 case CONST_INT:
8644 case CONST_FIXED:
8645 case CONST_DOUBLE:
8646 case SYMBOL_REF:
8647 case CONST:
8648 case LABEL_REF:
8649 /* Immediate constants are as cheap as registers. */
8650 *total = 0;
8651 return true;
8653 case MEM:
8654 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
8655 return true;
8657 case NEG:
8658 switch (mode)
8660 case QImode:
8661 case SFmode:
8662 *total = COSTS_N_INSNS (1);
8663 break;
8665 case HImode:
8666 case PSImode:
8667 case SImode:
8668 *total = COSTS_N_INSNS (2 * GET_MODE_SIZE (mode) - 1);
8669 break;
8671 default:
8672 return false;
8674 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8675 return true;
8677 case ABS:
8678 switch (mode)
8680 case QImode:
8681 case SFmode:
8682 *total = COSTS_N_INSNS (1);
8683 break;
8685 default:
8686 return false;
8688 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8689 return true;
8691 case NOT:
8692 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
8693 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8694 return true;
8696 case ZERO_EXTEND:
8697 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
8698 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
8699 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8700 return true;
8702 case SIGN_EXTEND:
8703 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
8704 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
8705 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8706 return true;
8708 case PLUS:
8709 switch (mode)
8711 case QImode:
8712 if (AVR_HAVE_MUL
8713 && MULT == GET_CODE (XEXP (x, 0))
8714 && register_operand (XEXP (x, 1), QImode))
8716 /* multiply-add */
8717 *total = COSTS_N_INSNS (speed ? 4 : 3);
8718 /* multiply-add with constant: will be split and load constant. */
8719 if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
8720 *total = COSTS_N_INSNS (1) + *total;
8721 return true;
8723 *total = COSTS_N_INSNS (1);
8724 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
8725 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
8726 break;
8728 case HImode:
8729 if (AVR_HAVE_MUL
8730 && (MULT == GET_CODE (XEXP (x, 0))
8731 || ASHIFT == GET_CODE (XEXP (x, 0)))
8732 && register_operand (XEXP (x, 1), HImode)
8733 && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))
8734 || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))))
8736 /* multiply-add */
8737 *total = COSTS_N_INSNS (speed ? 5 : 4);
8738 /* multiply-add with constant: will be split and load constant. */
8739 if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
8740 *total = COSTS_N_INSNS (1) + *total;
8741 return true;
8743 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
8745 *total = COSTS_N_INSNS (2);
8746 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
8747 speed);
8749 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
8750 *total = COSTS_N_INSNS (1);
8751 else
8752 *total = COSTS_N_INSNS (2);
8753 break;
8755 case PSImode:
8756 if (!CONST_INT_P (XEXP (x, 1)))
8758 *total = COSTS_N_INSNS (3);
8759 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
8760 speed);
8762 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
8763 *total = COSTS_N_INSNS (2);
8764 else
8765 *total = COSTS_N_INSNS (3);
8766 break;
8768 case SImode:
8769 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
8771 *total = COSTS_N_INSNS (4);
8772 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
8773 speed);
8775 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
8776 *total = COSTS_N_INSNS (1);
8777 else
8778 *total = COSTS_N_INSNS (4);
8779 break;
8781 default:
8782 return false;
8784 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8785 return true;
8787 case MINUS:
8788 if (AVR_HAVE_MUL
8789 && QImode == mode
8790 && register_operand (XEXP (x, 0), QImode)
8791 && MULT == GET_CODE (XEXP (x, 1)))
8793 /* multiply-sub */
8794 *total = COSTS_N_INSNS (speed ? 4 : 3);
8795 /* multiply-sub with constant: will be split and load constant. */
8796 if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
8797 *total = COSTS_N_INSNS (1) + *total;
8798 return true;
8800 if (AVR_HAVE_MUL
8801 && HImode == mode
8802 && register_operand (XEXP (x, 0), HImode)
8803 && (MULT == GET_CODE (XEXP (x, 1))
8804 || ASHIFT == GET_CODE (XEXP (x, 1)))
8805 && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))
8806 || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))))
8808 /* multiply-sub */
8809 *total = COSTS_N_INSNS (speed ? 5 : 4);
8810 /* multiply-sub with constant: will be split and load constant. */
8811 if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
8812 *total = COSTS_N_INSNS (1) + *total;
8813 return true;
8815 /* FALLTHRU */
8816 case AND:
8817 case IOR:
8818 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
8819 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8820 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
8821 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
8822 return true;
8824 case XOR:
8825 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
8826 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8827 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
8828 return true;
8830 case MULT:
8831 switch (mode)
8833 case QImode:
8834 if (AVR_HAVE_MUL)
8835 *total = COSTS_N_INSNS (!speed ? 3 : 4);
8836 else if (!speed)
8837 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
8838 else
8839 return false;
8840 break;
8842 case HImode:
8843 if (AVR_HAVE_MUL)
8845 rtx op0 = XEXP (x, 0);
8846 rtx op1 = XEXP (x, 1);
8847 enum rtx_code code0 = GET_CODE (op0);
8848 enum rtx_code code1 = GET_CODE (op1);
8849 bool ex0 = SIGN_EXTEND == code0 || ZERO_EXTEND == code0;
8850 bool ex1 = SIGN_EXTEND == code1 || ZERO_EXTEND == code1;
8852 if (ex0
8853 && (u8_operand (op1, HImode)
8854 || s8_operand (op1, HImode)))
8856 *total = COSTS_N_INSNS (!speed ? 4 : 6);
8857 return true;
8859 if (ex0
8860 && register_operand (op1, HImode))
8862 *total = COSTS_N_INSNS (!speed ? 5 : 8);
8863 return true;
8865 else if (ex0 || ex1)
8867 *total = COSTS_N_INSNS (!speed ? 3 : 5);
8868 return true;
8870 else if (register_operand (op0, HImode)
8871 && (u8_operand (op1, HImode)
8872 || s8_operand (op1, HImode)))
8874 *total = COSTS_N_INSNS (!speed ? 6 : 9);
8875 return true;
8877 else
8878 *total = COSTS_N_INSNS (!speed ? 7 : 10);
8880 else if (!speed)
8881 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
8882 else
8883 return false;
8884 break;
8886 case PSImode:
8887 if (!speed)
8888 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
8889 else
8890 *total = 10;
8891 break;
8893 case SImode:
8894 if (AVR_HAVE_MUL)
8896 if (!speed)
8898 /* Add some additional costs besides CALL like moves etc. */
8900 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
8902 else
8904 /* Just a rough estimate. Even with -O2 we don't want bulky
8905 code expanded inline. */
8907 *total = COSTS_N_INSNS (25);
8910 else
8912 if (speed)
8913 *total = COSTS_N_INSNS (300);
8914 else
8915 /* Add some additional costs besides CALL like moves etc. */
8916 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
8919 return true;
8921 default:
8922 return false;
8924 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8925 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
8926 return true;
8928 case DIV:
8929 case MOD:
8930 case UDIV:
8931 case UMOD:
8932 if (!speed)
8933 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
8934 else
8935 *total = COSTS_N_INSNS (15 * GET_MODE_SIZE (mode));
8936 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8937 /* For div/mod with const-int divisor we have at least the cost of
8938 loading the divisor. */
8939 if (CONST_INT_P (XEXP (x, 1)))
8940 *total += COSTS_N_INSNS (GET_MODE_SIZE (mode));
8941 /* Add some overall penaly for clobbering and moving around registers */
8942 *total += COSTS_N_INSNS (2);
8943 return true;
8945 case ROTATE:
8946 switch (mode)
8948 case QImode:
8949 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 4)
8950 *total = COSTS_N_INSNS (1);
8952 break;
8954 case HImode:
8955 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 8)
8956 *total = COSTS_N_INSNS (3);
8958 break;
8960 case SImode:
8961 if (CONST_INT_P (XEXP (x, 1)))
8962 switch (INTVAL (XEXP (x, 1)))
8964 case 8:
8965 case 24:
8966 *total = COSTS_N_INSNS (5);
8967 break;
8968 case 16:
8969 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 6);
8970 break;
8972 break;
8974 default:
8975 return false;
8977 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8978 return true;
8980 case ASHIFT:
8981 switch (mode)
8983 case QImode:
8984 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
8986 *total = COSTS_N_INSNS (!speed ? 4 : 17);
8987 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
8988 speed);
8990 else
8992 val = INTVAL (XEXP (x, 1));
8993 if (val == 7)
8994 *total = COSTS_N_INSNS (3);
8995 else if (val >= 0 && val <= 7)
8996 *total = COSTS_N_INSNS (val);
8997 else
8998 *total = COSTS_N_INSNS (1);
9000 break;
9002 case HImode:
9003 if (AVR_HAVE_MUL)
9005 if (const_2_to_7_operand (XEXP (x, 1), HImode)
9006 && (SIGN_EXTEND == GET_CODE (XEXP (x, 0))
9007 || ZERO_EXTEND == GET_CODE (XEXP (x, 0))))
9009 *total = COSTS_N_INSNS (!speed ? 4 : 6);
9010 return true;
9014 if (const1_rtx == (XEXP (x, 1))
9015 && SIGN_EXTEND == GET_CODE (XEXP (x, 0)))
9017 *total = COSTS_N_INSNS (2);
9018 return true;
9021 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9023 *total = COSTS_N_INSNS (!speed ? 5 : 41);
9024 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9025 speed);
9027 else
9028 switch (INTVAL (XEXP (x, 1)))
9030 case 0:
9031 *total = 0;
9032 break;
9033 case 1:
9034 case 8:
9035 *total = COSTS_N_INSNS (2);
9036 break;
9037 case 9:
9038 *total = COSTS_N_INSNS (3);
9039 break;
9040 case 2:
9041 case 3:
9042 case 10:
9043 case 15:
9044 *total = COSTS_N_INSNS (4);
9045 break;
9046 case 7:
9047 case 11:
9048 case 12:
9049 *total = COSTS_N_INSNS (5);
9050 break;
9051 case 4:
9052 *total = COSTS_N_INSNS (!speed ? 5 : 8);
9053 break;
9054 case 6:
9055 *total = COSTS_N_INSNS (!speed ? 5 : 9);
9056 break;
9057 case 5:
9058 *total = COSTS_N_INSNS (!speed ? 5 : 10);
9059 break;
9060 default:
9061 *total = COSTS_N_INSNS (!speed ? 5 : 41);
9062 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9063 speed);
9065 break;
9067 case PSImode:
9068 if (!CONST_INT_P (XEXP (x, 1)))
9070 *total = COSTS_N_INSNS (!speed ? 6 : 73);
9072 else
9073 switch (INTVAL (XEXP (x, 1)))
9075 case 0:
9076 *total = 0;
9077 break;
9078 case 1:
9079 case 8:
9080 case 16:
9081 *total = COSTS_N_INSNS (3);
9082 break;
9083 case 23:
9084 *total = COSTS_N_INSNS (5);
9085 break;
9086 default:
9087 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
9088 break;
9090 break;
9092 case SImode:
9093 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9095 *total = COSTS_N_INSNS (!speed ? 7 : 113);
9096 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9097 speed);
9099 else
9100 switch (INTVAL (XEXP (x, 1)))
9102 case 0:
9103 *total = 0;
9104 break;
9105 case 24:
9106 *total = COSTS_N_INSNS (3);
9107 break;
9108 case 1:
9109 case 8:
9110 case 16:
9111 *total = COSTS_N_INSNS (4);
9112 break;
9113 case 31:
9114 *total = COSTS_N_INSNS (6);
9115 break;
9116 case 2:
9117 *total = COSTS_N_INSNS (!speed ? 7 : 8);
9118 break;
9119 default:
9120 *total = COSTS_N_INSNS (!speed ? 7 : 113);
9121 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9122 speed);
9124 break;
9126 default:
9127 return false;
9129 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9130 return true;
9132 case ASHIFTRT:
9133 switch (mode)
9135 case QImode:
9136 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9138 *total = COSTS_N_INSNS (!speed ? 4 : 17);
9139 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9140 speed);
9142 else
9144 val = INTVAL (XEXP (x, 1));
9145 if (val == 6)
9146 *total = COSTS_N_INSNS (4);
9147 else if (val == 7)
9148 *total = COSTS_N_INSNS (2);
9149 else if (val >= 0 && val <= 7)
9150 *total = COSTS_N_INSNS (val);
9151 else
9152 *total = COSTS_N_INSNS (1);
9154 break;
9156 case HImode:
9157 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9159 *total = COSTS_N_INSNS (!speed ? 5 : 41);
9160 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9161 speed);
9163 else
9164 switch (INTVAL (XEXP (x, 1)))
9166 case 0:
9167 *total = 0;
9168 break;
9169 case 1:
9170 *total = COSTS_N_INSNS (2);
9171 break;
9172 case 15:
9173 *total = COSTS_N_INSNS (3);
9174 break;
9175 case 2:
9176 case 7:
9177 case 8:
9178 case 9:
9179 *total = COSTS_N_INSNS (4);
9180 break;
9181 case 10:
9182 case 14:
9183 *total = COSTS_N_INSNS (5);
9184 break;
9185 case 11:
9186 *total = COSTS_N_INSNS (!speed ? 5 : 6);
9187 break;
9188 case 12:
9189 *total = COSTS_N_INSNS (!speed ? 5 : 7);
9190 break;
9191 case 6:
9192 case 13:
9193 *total = COSTS_N_INSNS (!speed ? 5 : 8);
9194 break;
9195 default:
9196 *total = COSTS_N_INSNS (!speed ? 5 : 41);
9197 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9198 speed);
9200 break;
9202 case PSImode:
9203 if (!CONST_INT_P (XEXP (x, 1)))
9205 *total = COSTS_N_INSNS (!speed ? 6 : 73);
9207 else
9208 switch (INTVAL (XEXP (x, 1)))
9210 case 0:
9211 *total = 0;
9212 break;
9213 case 1:
9214 *total = COSTS_N_INSNS (3);
9215 break;
9216 case 16:
9217 case 8:
9218 *total = COSTS_N_INSNS (5);
9219 break;
9220 case 23:
9221 *total = COSTS_N_INSNS (4);
9222 break;
9223 default:
9224 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
9225 break;
9227 break;
9229 case SImode:
9230 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9232 *total = COSTS_N_INSNS (!speed ? 7 : 113);
9233 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9234 speed);
9236 else
9237 switch (INTVAL (XEXP (x, 1)))
9239 case 0:
9240 *total = 0;
9241 break;
9242 case 1:
9243 *total = COSTS_N_INSNS (4);
9244 break;
9245 case 8:
9246 case 16:
9247 case 24:
9248 *total = COSTS_N_INSNS (6);
9249 break;
9250 case 2:
9251 *total = COSTS_N_INSNS (!speed ? 7 : 8);
9252 break;
9253 case 31:
9254 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 5);
9255 break;
9256 default:
9257 *total = COSTS_N_INSNS (!speed ? 7 : 113);
9258 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9259 speed);
9261 break;
9263 default:
9264 return false;
9266 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9267 return true;
9269 case LSHIFTRT:
9270 switch (mode)
9272 case QImode:
9273 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9275 *total = COSTS_N_INSNS (!speed ? 4 : 17);
9276 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9277 speed);
9279 else
9281 val = INTVAL (XEXP (x, 1));
9282 if (val == 7)
9283 *total = COSTS_N_INSNS (3);
9284 else if (val >= 0 && val <= 7)
9285 *total = COSTS_N_INSNS (val);
9286 else
9287 *total = COSTS_N_INSNS (1);
9289 break;
9291 case HImode:
9292 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9294 *total = COSTS_N_INSNS (!speed ? 5 : 41);
9295 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9296 speed);
9298 else
9299 switch (INTVAL (XEXP (x, 1)))
9301 case 0:
9302 *total = 0;
9303 break;
9304 case 1:
9305 case 8:
9306 *total = COSTS_N_INSNS (2);
9307 break;
9308 case 9:
9309 *total = COSTS_N_INSNS (3);
9310 break;
9311 case 2:
9312 case 10:
9313 case 15:
9314 *total = COSTS_N_INSNS (4);
9315 break;
9316 case 7:
9317 case 11:
9318 *total = COSTS_N_INSNS (5);
9319 break;
9320 case 3:
9321 case 12:
9322 case 13:
9323 case 14:
9324 *total = COSTS_N_INSNS (!speed ? 5 : 6);
9325 break;
9326 case 4:
9327 *total = COSTS_N_INSNS (!speed ? 5 : 7);
9328 break;
9329 case 5:
9330 case 6:
9331 *total = COSTS_N_INSNS (!speed ? 5 : 9);
9332 break;
9333 default:
9334 *total = COSTS_N_INSNS (!speed ? 5 : 41);
9335 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9336 speed);
9338 break;
9340 case PSImode:
9341 if (!CONST_INT_P (XEXP (x, 1)))
9343 *total = COSTS_N_INSNS (!speed ? 6 : 73);
9345 else
9346 switch (INTVAL (XEXP (x, 1)))
9348 case 0:
9349 *total = 0;
9350 break;
9351 case 1:
9352 case 8:
9353 case 16:
9354 *total = COSTS_N_INSNS (3);
9355 break;
9356 case 23:
9357 *total = COSTS_N_INSNS (5);
9358 break;
9359 default:
9360 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
9361 break;
9363 break;
9365 case SImode:
9366 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9368 *total = COSTS_N_INSNS (!speed ? 7 : 113);
9369 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9370 speed);
9372 else
9373 switch (INTVAL (XEXP (x, 1)))
9375 case 0:
9376 *total = 0;
9377 break;
9378 case 1:
9379 *total = COSTS_N_INSNS (4);
9380 break;
9381 case 2:
9382 *total = COSTS_N_INSNS (!speed ? 7 : 8);
9383 break;
9384 case 8:
9385 case 16:
9386 case 24:
9387 *total = COSTS_N_INSNS (4);
9388 break;
9389 case 31:
9390 *total = COSTS_N_INSNS (6);
9391 break;
9392 default:
9393 *total = COSTS_N_INSNS (!speed ? 7 : 113);
9394 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9395 speed);
9397 break;
9399 default:
9400 return false;
9402 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9403 return true;
9405 case COMPARE:
9406 switch (GET_MODE (XEXP (x, 0)))
9408 case QImode:
9409 *total = COSTS_N_INSNS (1);
9410 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9411 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
9412 break;
9414 case HImode:
9415 *total = COSTS_N_INSNS (2);
9416 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9417 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
9418 else if (INTVAL (XEXP (x, 1)) != 0)
9419 *total += COSTS_N_INSNS (1);
9420 break;
9422 case PSImode:
9423 *total = COSTS_N_INSNS (3);
9424 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) != 0)
9425 *total += COSTS_N_INSNS (2);
9426 break;
9428 case SImode:
9429 *total = COSTS_N_INSNS (4);
9430 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9431 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
9432 else if (INTVAL (XEXP (x, 1)) != 0)
9433 *total += COSTS_N_INSNS (3);
9434 break;
9436 default:
9437 return false;
9439 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9440 return true;
9442 case TRUNCATE:
9443 if (AVR_HAVE_MUL
9444 && LSHIFTRT == GET_CODE (XEXP (x, 0))
9445 && MULT == GET_CODE (XEXP (XEXP (x, 0), 0))
9446 && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
9448 if (QImode == mode || HImode == mode)
9450 *total = COSTS_N_INSNS (2);
9451 return true;
9454 break;
9456 default:
9457 break;
9459 return false;
9463 /* Implement `TARGET_RTX_COSTS'. */
9465 static bool
9466 avr_rtx_costs (rtx x, int codearg, int outer_code,
9467 int opno, int *total, bool speed)
9469 bool done = avr_rtx_costs_1 (x, codearg, outer_code,
9470 opno, total, speed);
9472 if (avr_log.rtx_costs)
9474 avr_edump ("\n%?=%b (%s) total=%d, outer=%C:\n%r\n",
9475 done, speed ? "speed" : "size", *total, outer_code, x);
9478 return done;
9482 /* Implement `TARGET_ADDRESS_COST'. */
9484 static int
9485 avr_address_cost (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED,
9486 addr_space_t as ATTRIBUTE_UNUSED,
9487 bool speed ATTRIBUTE_UNUSED)
9489 int cost = 4;
9491 if (GET_CODE (x) == PLUS
9492 && CONST_INT_P (XEXP (x, 1))
9493 && (REG_P (XEXP (x, 0))
9494 || GET_CODE (XEXP (x, 0)) == SUBREG))
9496 if (INTVAL (XEXP (x, 1)) >= 61)
9497 cost = 18;
9499 else if (CONSTANT_ADDRESS_P (x))
9501 if (optimize > 0
9502 && io_address_operand (x, QImode))
9503 cost = 2;
9506 if (avr_log.address_cost)
9507 avr_edump ("\n%?: %d = %r\n", cost, x);
9509 return cost;
9512 /* Test for extra memory constraint 'Q'.
9513 It's a memory address based on Y or Z pointer with valid displacement. */
9516 extra_constraint_Q (rtx x)
9518 int ok = 0;
9520 if (GET_CODE (XEXP (x,0)) == PLUS
9521 && REG_P (XEXP (XEXP (x,0), 0))
9522 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
9523 && (INTVAL (XEXP (XEXP (x,0), 1))
9524 <= MAX_LD_OFFSET (GET_MODE (x))))
9526 rtx xx = XEXP (XEXP (x,0), 0);
9527 int regno = REGNO (xx);
9529 ok = (/* allocate pseudos */
9530 regno >= FIRST_PSEUDO_REGISTER
9531 /* strictly check */
9532 || regno == REG_Z || regno == REG_Y
9533 /* XXX frame & arg pointer checks */
9534 || xx == frame_pointer_rtx
9535 || xx == arg_pointer_rtx);
9537 if (avr_log.constraints)
9538 avr_edump ("\n%?=%d reload_completed=%d reload_in_progress=%d\n %r\n",
9539 ok, reload_completed, reload_in_progress, x);
9542 return ok;
9545 /* Convert condition code CONDITION to the valid AVR condition code. */
9547 RTX_CODE
9548 avr_normalize_condition (RTX_CODE condition)
9550 switch (condition)
9552 case GT:
9553 return GE;
9554 case GTU:
9555 return GEU;
9556 case LE:
9557 return LT;
9558 case LEU:
9559 return LTU;
9560 default:
9561 gcc_unreachable ();
9565 /* Helper function for `avr_reorg'. */
9567 static rtx
9568 avr_compare_pattern (rtx insn)
9570 rtx pattern = single_set (insn);
9572 if (pattern
9573 && NONJUMP_INSN_P (insn)
9574 && SET_DEST (pattern) == cc0_rtx
9575 && GET_CODE (SET_SRC (pattern)) == COMPARE)
9577 enum machine_mode mode0 = GET_MODE (XEXP (SET_SRC (pattern), 0));
9578 enum machine_mode mode1 = GET_MODE (XEXP (SET_SRC (pattern), 1));
9580 /* The 64-bit comparisons have fixed operands ACC_A and ACC_B.
9581 They must not be swapped, thus skip them. */
9583 if ((mode0 == VOIDmode || GET_MODE_SIZE (mode0) <= 4)
9584 && (mode1 == VOIDmode || GET_MODE_SIZE (mode1) <= 4))
9585 return pattern;
9588 return NULL_RTX;
9591 /* Helper function for `avr_reorg'. */
9593 /* Expansion of switch/case decision trees leads to code like
9595 cc0 = compare (Reg, Num)
9596 if (cc0 == 0)
9597 goto L1
9599 cc0 = compare (Reg, Num)
9600 if (cc0 > 0)
9601 goto L2
9603 The second comparison is superfluous and can be deleted.
9604 The second jump condition can be transformed from a
9605 "difficult" one to a "simple" one because "cc0 > 0" and
9606 "cc0 >= 0" will have the same effect here.
9608 This function relies on the way switch/case is being expaned
9609 as binary decision tree. For example code see PR 49903.
9611 Return TRUE if optimization performed.
9612 Return FALSE if nothing changed.
9614 INSN1 is a comparison, i.e. avr_compare_pattern != 0.
9616 We don't want to do this in text peephole because it is
9617 tedious to work out jump offsets there and the second comparison
9618 might have been transormed by `avr_reorg'.
9620 RTL peephole won't do because peephole2 does not scan across
9621 basic blocks. */
9623 static bool
9624 avr_reorg_remove_redundant_compare (rtx insn1)
9626 rtx comp1, ifelse1, xcond1, branch1;
9627 rtx comp2, ifelse2, xcond2, branch2, insn2;
9628 enum rtx_code code;
9629 rtx jump, target, cond;
9631 /* Look out for: compare1 - branch1 - compare2 - branch2 */
9633 branch1 = next_nonnote_nondebug_insn (insn1);
9634 if (!branch1 || !JUMP_P (branch1))
9635 return false;
9637 insn2 = next_nonnote_nondebug_insn (branch1);
9638 if (!insn2 || !avr_compare_pattern (insn2))
9639 return false;
9641 branch2 = next_nonnote_nondebug_insn (insn2);
9642 if (!branch2 || !JUMP_P (branch2))
9643 return false;
9645 comp1 = avr_compare_pattern (insn1);
9646 comp2 = avr_compare_pattern (insn2);
9647 xcond1 = single_set (branch1);
9648 xcond2 = single_set (branch2);
9650 if (!comp1 || !comp2
9651 || !rtx_equal_p (comp1, comp2)
9652 || !xcond1 || SET_DEST (xcond1) != pc_rtx
9653 || !xcond2 || SET_DEST (xcond2) != pc_rtx
9654 || IF_THEN_ELSE != GET_CODE (SET_SRC (xcond1))
9655 || IF_THEN_ELSE != GET_CODE (SET_SRC (xcond2)))
9657 return false;
9660 comp1 = SET_SRC (comp1);
9661 ifelse1 = SET_SRC (xcond1);
9662 ifelse2 = SET_SRC (xcond2);
9664 /* comp<n> is COMPARE now and ifelse<n> is IF_THEN_ELSE. */
9666 if (EQ != GET_CODE (XEXP (ifelse1, 0))
9667 || !REG_P (XEXP (comp1, 0))
9668 || !CONST_INT_P (XEXP (comp1, 1))
9669 || XEXP (ifelse1, 2) != pc_rtx
9670 || XEXP (ifelse2, 2) != pc_rtx
9671 || LABEL_REF != GET_CODE (XEXP (ifelse1, 1))
9672 || LABEL_REF != GET_CODE (XEXP (ifelse2, 1))
9673 || !COMPARISON_P (XEXP (ifelse2, 0))
9674 || cc0_rtx != XEXP (XEXP (ifelse1, 0), 0)
9675 || cc0_rtx != XEXP (XEXP (ifelse2, 0), 0)
9676 || const0_rtx != XEXP (XEXP (ifelse1, 0), 1)
9677 || const0_rtx != XEXP (XEXP (ifelse2, 0), 1))
9679 return false;
9682 /* We filtered the insn sequence to look like
9684 (set (cc0)
9685 (compare (reg:M N)
9686 (const_int VAL)))
9687 (set (pc)
9688 (if_then_else (eq (cc0)
9689 (const_int 0))
9690 (label_ref L1)
9691 (pc)))
9693 (set (cc0)
9694 (compare (reg:M N)
9695 (const_int VAL)))
9696 (set (pc)
9697 (if_then_else (CODE (cc0)
9698 (const_int 0))
9699 (label_ref L2)
9700 (pc)))
9703 code = GET_CODE (XEXP (ifelse2, 0));
9705 /* Map GT/GTU to GE/GEU which is easier for AVR.
9706 The first two instructions compare/branch on EQ
9707 so we may replace the difficult
9709 if (x == VAL) goto L1;
9710 if (x > VAL) goto L2;
9712 with easy
9714 if (x == VAL) goto L1;
9715 if (x >= VAL) goto L2;
9717 Similarly, replace LE/LEU by LT/LTU. */
9719 switch (code)
9721 case EQ:
9722 case LT: case LTU:
9723 case GE: case GEU:
9724 break;
9726 case LE: case LEU:
9727 case GT: case GTU:
9728 code = avr_normalize_condition (code);
9729 break;
9731 default:
9732 return false;
9735 /* Wrap the branches into UNSPECs so they won't be changed or
9736 optimized in the remainder. */
9738 target = XEXP (XEXP (ifelse1, 1), 0);
9739 cond = XEXP (ifelse1, 0);
9740 jump = emit_jump_insn_after (gen_branch_unspec (target, cond), insn1);
9742 JUMP_LABEL (jump) = JUMP_LABEL (branch1);
9744 target = XEXP (XEXP (ifelse2, 1), 0);
9745 cond = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
9746 jump = emit_jump_insn_after (gen_branch_unspec (target, cond), insn2);
9748 JUMP_LABEL (jump) = JUMP_LABEL (branch2);
9750 /* The comparisons in insn1 and insn2 are exactly the same;
9751 insn2 is superfluous so delete it. */
9753 delete_insn (insn2);
9754 delete_insn (branch1);
9755 delete_insn (branch2);
9757 return true;
9761 /* Implement `TARGET_MACHINE_DEPENDENT_REORG'. */
9762 /* Optimize conditional jumps. */
9764 static void
9765 avr_reorg (void)
9767 rtx insn = get_insns();
9769 for (insn = next_real_insn (insn); insn; insn = next_real_insn (insn))
9771 rtx pattern = avr_compare_pattern (insn);
9773 if (!pattern)
9774 continue;
9776 if (optimize
9777 && avr_reorg_remove_redundant_compare (insn))
9779 continue;
9782 if (compare_diff_p (insn))
9784 /* Now we work under compare insn with difficult branch. */
9786 rtx next = next_real_insn (insn);
9787 rtx pat = PATTERN (next);
9789 pattern = SET_SRC (pattern);
9791 if (true_regnum (XEXP (pattern, 0)) >= 0
9792 && true_regnum (XEXP (pattern, 1)) >= 0)
9794 rtx x = XEXP (pattern, 0);
9795 rtx src = SET_SRC (pat);
9796 rtx t = XEXP (src,0);
9797 PUT_CODE (t, swap_condition (GET_CODE (t)));
9798 XEXP (pattern, 0) = XEXP (pattern, 1);
9799 XEXP (pattern, 1) = x;
9800 INSN_CODE (next) = -1;
9802 else if (true_regnum (XEXP (pattern, 0)) >= 0
9803 && XEXP (pattern, 1) == const0_rtx)
9805 /* This is a tst insn, we can reverse it. */
9806 rtx src = SET_SRC (pat);
9807 rtx t = XEXP (src,0);
9809 PUT_CODE (t, swap_condition (GET_CODE (t)));
9810 XEXP (pattern, 1) = XEXP (pattern, 0);
9811 XEXP (pattern, 0) = const0_rtx;
9812 INSN_CODE (next) = -1;
9813 INSN_CODE (insn) = -1;
9815 else if (true_regnum (XEXP (pattern, 0)) >= 0
9816 && CONST_INT_P (XEXP (pattern, 1)))
9818 rtx x = XEXP (pattern, 1);
9819 rtx src = SET_SRC (pat);
9820 rtx t = XEXP (src,0);
9821 enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
9823 if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
9825 XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
9826 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
9827 INSN_CODE (next) = -1;
9828 INSN_CODE (insn) = -1;
9835 /* Returns register number for function return value.*/
9837 static inline unsigned int
9838 avr_ret_register (void)
9840 return 24;
9844 /* Implement `TARGET_FUNCTION_VALUE_REGNO_P'. */
9846 static bool
9847 avr_function_value_regno_p (const unsigned int regno)
9849 return (regno == avr_ret_register ());
9853 /* Implement `TARGET_LIBCALL_VALUE'. */
9854 /* Create an RTX representing the place where a
9855 library function returns a value of mode MODE. */
9857 static rtx
9858 avr_libcall_value (enum machine_mode mode,
9859 const_rtx func ATTRIBUTE_UNUSED)
9861 int offs = GET_MODE_SIZE (mode);
9863 if (offs <= 4)
9864 offs = (offs + 1) & ~1;
9866 return gen_rtx_REG (mode, avr_ret_register () + 2 - offs);
9870 /* Implement `TARGET_FUNCTION_VALUE'. */
9871 /* Create an RTX representing the place where a
9872 function returns a value of data type VALTYPE. */
9874 static rtx
9875 avr_function_value (const_tree type,
9876 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
9877 bool outgoing ATTRIBUTE_UNUSED)
9879 unsigned int offs;
9881 if (TYPE_MODE (type) != BLKmode)
9882 return avr_libcall_value (TYPE_MODE (type), NULL_RTX);
9884 offs = int_size_in_bytes (type);
9885 if (offs < 2)
9886 offs = 2;
9887 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
9888 offs = GET_MODE_SIZE (SImode);
9889 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
9890 offs = GET_MODE_SIZE (DImode);
9892 return gen_rtx_REG (BLKmode, avr_ret_register () + 2 - offs);
9896 test_hard_reg_class (enum reg_class rclass, rtx x)
9898 int regno = true_regnum (x);
9899 if (regno < 0)
9900 return 0;
9902 if (TEST_HARD_REG_CLASS (rclass, regno))
9903 return 1;
9905 return 0;
9909 /* Helper for jump_over_one_insn_p: Test if INSN is a 2-word instruction
9910 and thus is suitable to be skipped by CPSE, SBRC, etc. */
9912 static bool
9913 avr_2word_insn_p (rtx insn)
9915 if (avr_current_device->errata_skip
9916 || !insn
9917 || 2 != get_attr_length (insn))
9919 return false;
9922 switch (INSN_CODE (insn))
9924 default:
9925 return false;
9927 case CODE_FOR_movqi_insn:
9928 case CODE_FOR_movuqq_insn:
9929 case CODE_FOR_movqq_insn:
9931 rtx set = single_set (insn);
9932 rtx src = SET_SRC (set);
9933 rtx dest = SET_DEST (set);
9935 /* Factor out LDS and STS from movqi_insn. */
9937 if (MEM_P (dest)
9938 && (REG_P (src) || src == CONST0_RTX (GET_MODE (dest))))
9940 return CONSTANT_ADDRESS_P (XEXP (dest, 0));
9942 else if (REG_P (dest)
9943 && MEM_P (src))
9945 return CONSTANT_ADDRESS_P (XEXP (src, 0));
9948 return false;
9951 case CODE_FOR_call_insn:
9952 case CODE_FOR_call_value_insn:
9953 return true;
9959 jump_over_one_insn_p (rtx insn, rtx dest)
9961 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
9962 ? XEXP (dest, 0)
9963 : dest);
9964 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
9965 int dest_addr = INSN_ADDRESSES (uid);
9966 int jump_offset = dest_addr - jump_addr - get_attr_length (insn);
9968 return (jump_offset == 1
9969 || (jump_offset == 2
9970 && avr_2word_insn_p (next_active_insn (insn))));
9974 /* Worker function for `HARD_REGNO_MODE_OK'. */
9975 /* Returns 1 if a value of mode MODE can be stored starting with hard
9976 register number REGNO. On the enhanced core, anything larger than
9977 1 byte must start in even numbered register for "movw" to work
9978 (this way we don't have to check for odd registers everywhere). */
9981 avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
9983 /* NOTE: 8-bit values must not be disallowed for R28 or R29.
9984 Disallowing QI et al. in these regs might lead to code like
9985 (set (subreg:QI (reg:HI 28) n) ...)
9986 which will result in wrong code because reload does not
9987 handle SUBREGs of hard regsisters like this.
9988 This could be fixed in reload. However, it appears
9989 that fixing reload is not wanted by reload people. */
9991 /* Any GENERAL_REGS register can hold 8-bit values. */
9993 if (GET_MODE_SIZE (mode) == 1)
9994 return 1;
9996 /* FIXME: Ideally, the following test is not needed.
9997 However, it turned out that it can reduce the number
9998 of spill fails. AVR and it's poor endowment with
9999 address registers is extreme stress test for reload. */
10001 if (GET_MODE_SIZE (mode) >= 4
10002 && regno >= REG_X)
10003 return 0;
10005 /* All modes larger than 8 bits should start in an even register. */
10007 return !(regno & 1);
10011 /* Implement `HARD_REGNO_CALL_PART_CLOBBERED'. */
10014 avr_hard_regno_call_part_clobbered (unsigned regno, enum machine_mode mode)
10016 /* FIXME: This hook gets called with MODE:REGNO combinations that don't
10017 represent valid hard registers like, e.g. HI:29. Returning TRUE
10018 for such registers can lead to performance degradation as mentioned
10019 in PR53595. Thus, report invalid hard registers as FALSE. */
10021 if (!avr_hard_regno_mode_ok (regno, mode))
10022 return 0;
10024 /* Return true if any of the following boundaries is crossed:
10025 17/18, 27/28 and 29/30. */
10027 return ((regno < 18 && regno + GET_MODE_SIZE (mode) > 18)
10028 || (regno < REG_Y && regno + GET_MODE_SIZE (mode) > REG_Y)
10029 || (regno < REG_Z && regno + GET_MODE_SIZE (mode) > REG_Z));
10033 /* Implement `MODE_CODE_BASE_REG_CLASS'. */
10035 enum reg_class
10036 avr_mode_code_base_reg_class (enum machine_mode mode ATTRIBUTE_UNUSED,
10037 addr_space_t as, RTX_CODE outer_code,
10038 RTX_CODE index_code ATTRIBUTE_UNUSED)
10040 if (!ADDR_SPACE_GENERIC_P (as))
10042 return POINTER_Z_REGS;
10045 if (!avr_strict_X)
10046 return reload_completed ? BASE_POINTER_REGS : POINTER_REGS;
10048 return PLUS == outer_code ? BASE_POINTER_REGS : POINTER_REGS;
10052 /* Implement `REGNO_MODE_CODE_OK_FOR_BASE_P'. */
10054 bool
10055 avr_regno_mode_code_ok_for_base_p (int regno,
10056 enum machine_mode mode ATTRIBUTE_UNUSED,
10057 addr_space_t as ATTRIBUTE_UNUSED,
10058 RTX_CODE outer_code,
10059 RTX_CODE index_code ATTRIBUTE_UNUSED)
10061 bool ok = false;
10063 if (!ADDR_SPACE_GENERIC_P (as))
10065 if (regno < FIRST_PSEUDO_REGISTER
10066 && regno == REG_Z)
10068 return true;
10071 if (reg_renumber)
10073 regno = reg_renumber[regno];
10075 if (regno == REG_Z)
10077 return true;
10081 return false;
10084 if (regno < FIRST_PSEUDO_REGISTER
10085 && (regno == REG_X
10086 || regno == REG_Y
10087 || regno == REG_Z
10088 || regno == ARG_POINTER_REGNUM))
10090 ok = true;
10092 else if (reg_renumber)
10094 regno = reg_renumber[regno];
10096 if (regno == REG_X
10097 || regno == REG_Y
10098 || regno == REG_Z
10099 || regno == ARG_POINTER_REGNUM)
10101 ok = true;
10105 if (avr_strict_X
10106 && PLUS == outer_code
10107 && regno == REG_X)
10109 ok = false;
10112 return ok;
10116 /* A helper for `output_reload_insisf' and `output_reload_inhi'. */
10117 /* Set 32-bit register OP[0] to compile-time constant OP[1].
10118 CLOBBER_REG is a QI clobber register or NULL_RTX.
10119 LEN == NULL: output instructions.
10120 LEN != NULL: set *LEN to the length of the instruction sequence
10121 (in words) printed with LEN = NULL.
10122 If CLEAR_P is true, OP[0] had been cleard to Zero already.
10123 If CLEAR_P is false, nothing is known about OP[0].
10125 The effect on cc0 is as follows:
10127 Load 0 to any register except ZERO_REG : NONE
10128 Load ld register with any value : NONE
10129 Anything else: : CLOBBER */
10131 static void
10132 output_reload_in_const (rtx *op, rtx clobber_reg, int *len, bool clear_p)
10134 rtx src = op[1];
10135 rtx dest = op[0];
10136 rtx xval, xdest[4];
10137 int ival[4];
10138 int clobber_val = 1234;
10139 bool cooked_clobber_p = false;
10140 bool set_p = false;
10141 enum machine_mode mode = GET_MODE (dest);
10142 int n, n_bytes = GET_MODE_SIZE (mode);
10144 gcc_assert (REG_P (dest)
10145 && CONSTANT_P (src));
10147 if (len)
10148 *len = 0;
10150 /* (REG:SI 14) is special: It's neither in LD_REGS nor in NO_LD_REGS
10151 but has some subregs that are in LD_REGS. Use the MSB (REG:QI 17). */
10153 if (REGNO (dest) < 16
10154 && REGNO (dest) + GET_MODE_SIZE (mode) > 16)
10156 clobber_reg = all_regs_rtx[REGNO (dest) + n_bytes - 1];
10159 /* We might need a clobber reg but don't have one. Look at the value to
10160 be loaded more closely. A clobber is only needed if it is a symbol
10161 or contains a byte that is neither 0, -1 or a power of 2. */
10163 if (NULL_RTX == clobber_reg
10164 && !test_hard_reg_class (LD_REGS, dest)
10165 && (! (CONST_INT_P (src) || CONST_FIXED_P (src) || CONST_DOUBLE_P (src))
10166 || !avr_popcount_each_byte (src, n_bytes,
10167 (1 << 0) | (1 << 1) | (1 << 8))))
10169 /* We have no clobber register but need one. Cook one up.
10170 That's cheaper than loading from constant pool. */
10172 cooked_clobber_p = true;
10173 clobber_reg = all_regs_rtx[REG_Z + 1];
10174 avr_asm_len ("mov __tmp_reg__,%0", &clobber_reg, len, 1);
10177 /* Now start filling DEST from LSB to MSB. */
10179 for (n = 0; n < n_bytes; n++)
10181 int ldreg_p;
10182 bool done_byte = false;
10183 int j;
10184 rtx xop[3];
10186 /* Crop the n-th destination byte. */
10188 xdest[n] = simplify_gen_subreg (QImode, dest, mode, n);
10189 ldreg_p = test_hard_reg_class (LD_REGS, xdest[n]);
10191 if (!CONST_INT_P (src)
10192 && !CONST_FIXED_P (src)
10193 && !CONST_DOUBLE_P (src))
10195 static const char* const asm_code[][2] =
10197 { "ldi %2,lo8(%1)" CR_TAB "mov %0,%2", "ldi %0,lo8(%1)" },
10198 { "ldi %2,hi8(%1)" CR_TAB "mov %0,%2", "ldi %0,hi8(%1)" },
10199 { "ldi %2,hlo8(%1)" CR_TAB "mov %0,%2", "ldi %0,hlo8(%1)" },
10200 { "ldi %2,hhi8(%1)" CR_TAB "mov %0,%2", "ldi %0,hhi8(%1)" }
10203 xop[0] = xdest[n];
10204 xop[1] = src;
10205 xop[2] = clobber_reg;
10207 avr_asm_len (asm_code[n][ldreg_p], xop, len, ldreg_p ? 1 : 2);
10209 continue;
10212 /* Crop the n-th source byte. */
10214 xval = simplify_gen_subreg (QImode, src, mode, n);
10215 ival[n] = INTVAL (xval);
10217 /* Look if we can reuse the low word by means of MOVW. */
10219 if (n == 2
10220 && n_bytes >= 4
10221 && AVR_HAVE_MOVW)
10223 rtx lo16 = simplify_gen_subreg (HImode, src, mode, 0);
10224 rtx hi16 = simplify_gen_subreg (HImode, src, mode, 2);
10226 if (INTVAL (lo16) == INTVAL (hi16))
10228 if (0 != INTVAL (lo16)
10229 || !clear_p)
10231 avr_asm_len ("movw %C0,%A0", &op[0], len, 1);
10234 break;
10238 /* Don't use CLR so that cc0 is set as expected. */
10240 if (ival[n] == 0)
10242 if (!clear_p)
10243 avr_asm_len (ldreg_p ? "ldi %0,0"
10244 : ZERO_REGNO == REGNO (xdest[n]) ? "clr %0"
10245 : "mov %0,__zero_reg__",
10246 &xdest[n], len, 1);
10247 continue;
10250 if (clobber_val == ival[n]
10251 && REGNO (clobber_reg) == REGNO (xdest[n]))
10253 continue;
10256 /* LD_REGS can use LDI to move a constant value */
10258 if (ldreg_p)
10260 xop[0] = xdest[n];
10261 xop[1] = xval;
10262 avr_asm_len ("ldi %0,lo8(%1)", xop, len, 1);
10263 continue;
10266 /* Try to reuse value already loaded in some lower byte. */
10268 for (j = 0; j < n; j++)
10269 if (ival[j] == ival[n])
10271 xop[0] = xdest[n];
10272 xop[1] = xdest[j];
10274 avr_asm_len ("mov %0,%1", xop, len, 1);
10275 done_byte = true;
10276 break;
10279 if (done_byte)
10280 continue;
10282 /* Need no clobber reg for -1: Use CLR/DEC */
10284 if (-1 == ival[n])
10286 if (!clear_p)
10287 avr_asm_len ("clr %0", &xdest[n], len, 1);
10289 avr_asm_len ("dec %0", &xdest[n], len, 1);
10290 continue;
10292 else if (1 == ival[n])
10294 if (!clear_p)
10295 avr_asm_len ("clr %0", &xdest[n], len, 1);
10297 avr_asm_len ("inc %0", &xdest[n], len, 1);
10298 continue;
10301 /* Use T flag or INC to manage powers of 2 if we have
10302 no clobber reg. */
10304 if (NULL_RTX == clobber_reg
10305 && single_one_operand (xval, QImode))
10307 xop[0] = xdest[n];
10308 xop[1] = GEN_INT (exact_log2 (ival[n] & GET_MODE_MASK (QImode)));
10310 gcc_assert (constm1_rtx != xop[1]);
10312 if (!set_p)
10314 set_p = true;
10315 avr_asm_len ("set", xop, len, 1);
10318 if (!clear_p)
10319 avr_asm_len ("clr %0", xop, len, 1);
10321 avr_asm_len ("bld %0,%1", xop, len, 1);
10322 continue;
10325 /* We actually need the LD_REGS clobber reg. */
10327 gcc_assert (NULL_RTX != clobber_reg);
10329 xop[0] = xdest[n];
10330 xop[1] = xval;
10331 xop[2] = clobber_reg;
10332 clobber_val = ival[n];
10334 avr_asm_len ("ldi %2,lo8(%1)" CR_TAB
10335 "mov %0,%2", xop, len, 2);
10338 /* If we cooked up a clobber reg above, restore it. */
10340 if (cooked_clobber_p)
10342 avr_asm_len ("mov %0,__tmp_reg__", &clobber_reg, len, 1);
10347 /* Reload the constant OP[1] into the HI register OP[0].
10348 CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
10349 into a NO_LD_REGS register. If CLOBBER_REG is NULL_RTX we either don't
10350 need a clobber reg or have to cook one up.
10352 PLEN == NULL: Output instructions.
10353 PLEN != NULL: Output nothing. Set *PLEN to number of words occupied
10354 by the insns printed.
10356 Return "". */
10358 const char*
10359 output_reload_inhi (rtx *op, rtx clobber_reg, int *plen)
10361 output_reload_in_const (op, clobber_reg, plen, false);
10362 return "";
10366 /* Reload a SI or SF compile time constant OP[1] into the register OP[0].
10367 CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
10368 into a NO_LD_REGS register. If CLOBBER_REG is NULL_RTX we either don't
10369 need a clobber reg or have to cook one up.
10371 LEN == NULL: Output instructions.
10373 LEN != NULL: Output nothing. Set *LEN to number of words occupied
10374 by the insns printed.
10376 Return "". */
10378 const char *
10379 output_reload_insisf (rtx *op, rtx clobber_reg, int *len)
10381 if (AVR_HAVE_MOVW
10382 && !test_hard_reg_class (LD_REGS, op[0])
10383 && (CONST_INT_P (op[1])
10384 || CONST_FIXED_P (op[1])
10385 || CONST_DOUBLE_P (op[1])))
10387 int len_clr, len_noclr;
10389 /* In some cases it is better to clear the destination beforehand, e.g.
10391 CLR R2 CLR R3 MOVW R4,R2 INC R2
10393 is shorther than
10395 CLR R2 INC R2 CLR R3 CLR R4 CLR R5
10397 We find it too tedious to work that out in the print function.
10398 Instead, we call the print function twice to get the lengths of
10399 both methods and use the shortest one. */
10401 output_reload_in_const (op, clobber_reg, &len_clr, true);
10402 output_reload_in_const (op, clobber_reg, &len_noclr, false);
10404 if (len_noclr - len_clr == 4)
10406 /* Default needs 4 CLR instructions: clear register beforehand. */
10408 avr_asm_len ("mov %A0,__zero_reg__" CR_TAB
10409 "mov %B0,__zero_reg__" CR_TAB
10410 "movw %C0,%A0", &op[0], len, 3);
10412 output_reload_in_const (op, clobber_reg, len, true);
10414 if (len)
10415 *len += 3;
10417 return "";
10421 /* Default: destination not pre-cleared. */
10423 output_reload_in_const (op, clobber_reg, len, false);
10424 return "";
10427 const char*
10428 avr_out_reload_inpsi (rtx *op, rtx clobber_reg, int *len)
10430 output_reload_in_const (op, clobber_reg, len, false);
10431 return "";
10435 /* Worker function for `ASM_OUTPUT_ADDR_VEC_ELT'. */
10437 void
10438 avr_output_addr_vec_elt (FILE *stream, int value)
10440 if (AVR_HAVE_JMP_CALL)
10441 fprintf (stream, "\t.word gs(.L%d)\n", value);
10442 else
10443 fprintf (stream, "\trjmp .L%d\n", value);
10447 /* Implement `TARGET_HARD_REGNO_SCRATCH_OK'. */
10448 /* Returns true if SCRATCH are safe to be allocated as a scratch
10449 registers (for a define_peephole2) in the current function. */
10451 static bool
10452 avr_hard_regno_scratch_ok (unsigned int regno)
10454 /* Interrupt functions can only use registers that have already been saved
10455 by the prologue, even if they would normally be call-clobbered. */
10457 if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
10458 && !df_regs_ever_live_p (regno))
10459 return false;
10461 /* Don't allow hard registers that might be part of the frame pointer.
10462 Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
10463 and don't care for a frame pointer that spans more than one register. */
10465 if ((!reload_completed || frame_pointer_needed)
10466 && (regno == REG_Y || regno == REG_Y + 1))
10468 return false;
10471 return true;
10475 /* Worker function for `HARD_REGNO_RENAME_OK'. */
10476 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
10479 avr_hard_regno_rename_ok (unsigned int old_reg,
10480 unsigned int new_reg)
10482 /* Interrupt functions can only use registers that have already been
10483 saved by the prologue, even if they would normally be
10484 call-clobbered. */
10486 if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
10487 && !df_regs_ever_live_p (new_reg))
10488 return 0;
10490 /* Don't allow hard registers that might be part of the frame pointer.
10491 Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
10492 and don't care for a frame pointer that spans more than one register. */
10494 if ((!reload_completed || frame_pointer_needed)
10495 && (old_reg == REG_Y || old_reg == REG_Y + 1
10496 || new_reg == REG_Y || new_reg == REG_Y + 1))
10498 return 0;
10501 return 1;
10504 /* Output a branch that tests a single bit of a register (QI, HI, SI or DImode)
10505 or memory location in the I/O space (QImode only).
10507 Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
10508 Operand 1: register operand to test, or CONST_INT memory address.
10509 Operand 2: bit number.
10510 Operand 3: label to jump to if the test is true. */
10512 const char*
10513 avr_out_sbxx_branch (rtx insn, rtx operands[])
10515 enum rtx_code comp = GET_CODE (operands[0]);
10516 bool long_jump = get_attr_length (insn) >= 4;
10517 bool reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
10519 if (comp == GE)
10520 comp = EQ;
10521 else if (comp == LT)
10522 comp = NE;
10524 if (reverse)
10525 comp = reverse_condition (comp);
10527 switch (GET_CODE (operands[1]))
10529 default:
10530 gcc_unreachable();
10532 case CONST_INT:
10534 if (low_io_address_operand (operands[1], QImode))
10536 if (comp == EQ)
10537 output_asm_insn ("sbis %i1,%2", operands);
10538 else
10539 output_asm_insn ("sbic %i1,%2", operands);
10541 else
10543 output_asm_insn ("in __tmp_reg__,%i1", operands);
10544 if (comp == EQ)
10545 output_asm_insn ("sbrs __tmp_reg__,%2", operands);
10546 else
10547 output_asm_insn ("sbrc __tmp_reg__,%2", operands);
10550 break; /* CONST_INT */
10552 case REG:
10554 if (comp == EQ)
10555 output_asm_insn ("sbrs %T1%T2", operands);
10556 else
10557 output_asm_insn ("sbrc %T1%T2", operands);
10559 break; /* REG */
10560 } /* switch */
10562 if (long_jump)
10563 return ("rjmp .+4" CR_TAB
10564 "jmp %x3");
10566 if (!reverse)
10567 return "rjmp %x3";
10569 return "";
10572 /* Worker function for `TARGET_ASM_CONSTRUCTOR'. */
10574 static void
10575 avr_asm_out_ctor (rtx symbol, int priority)
10577 fputs ("\t.global __do_global_ctors\n", asm_out_file);
10578 default_ctor_section_asm_out_constructor (symbol, priority);
10582 /* Worker function for `TARGET_ASM_DESTRUCTOR'. */
10584 static void
10585 avr_asm_out_dtor (rtx symbol, int priority)
10587 fputs ("\t.global __do_global_dtors\n", asm_out_file);
10588 default_dtor_section_asm_out_destructor (symbol, priority);
10592 /* Worker function for `TARGET_RETURN_IN_MEMORY'. */
10594 static bool
10595 avr_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
10597 if (TYPE_MODE (type) == BLKmode)
10599 HOST_WIDE_INT size = int_size_in_bytes (type);
10600 return (size == -1 || size > 8);
10602 else
10603 return false;
10607 /* Implement `CASE_VALUES_THRESHOLD'. */
10608 /* Supply the default for --param case-values-threshold=0 */
10610 static unsigned int
10611 avr_case_values_threshold (void)
10613 /* The exact break-even point between a jump table and an if-else tree
10614 depends on several factors not available here like, e.g. if 8-bit
10615 comparisons can be used in the if-else tree or not, on the
10616 range of the case values, if the case value can be reused, on the
10617 register allocation, etc. '7' appears to be a good choice. */
10619 return 7;
10623 /* Implement `TARGET_ADDR_SPACE_ADDRESS_MODE'. */
10625 static enum machine_mode
10626 avr_addr_space_address_mode (addr_space_t as)
10628 return avr_addrspace[as].pointer_size == 3 ? PSImode : HImode;
10632 /* Implement `TARGET_ADDR_SPACE_POINTER_MODE'. */
10634 static enum machine_mode
10635 avr_addr_space_pointer_mode (addr_space_t as)
10637 return avr_addr_space_address_mode (as);
10641 /* Helper for following function. */
10643 static bool
10644 avr_reg_ok_for_pgm_addr (rtx reg, bool strict)
10646 gcc_assert (REG_P (reg));
10648 if (strict)
10650 return REGNO (reg) == REG_Z;
10653 /* Avoid combine to propagate hard regs. */
10655 if (can_create_pseudo_p()
10656 && REGNO (reg) < REG_Z)
10658 return false;
10661 return true;
10665 /* Implement `TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P'. */
10667 static bool
10668 avr_addr_space_legitimate_address_p (enum machine_mode mode, rtx x,
10669 bool strict, addr_space_t as)
10671 bool ok = false;
10673 switch (as)
10675 default:
10676 gcc_unreachable();
10678 case ADDR_SPACE_GENERIC:
10679 return avr_legitimate_address_p (mode, x, strict);
10681 case ADDR_SPACE_FLASH:
10682 case ADDR_SPACE_FLASH1:
10683 case ADDR_SPACE_FLASH2:
10684 case ADDR_SPACE_FLASH3:
10685 case ADDR_SPACE_FLASH4:
10686 case ADDR_SPACE_FLASH5:
10688 switch (GET_CODE (x))
10690 case REG:
10691 ok = avr_reg_ok_for_pgm_addr (x, strict);
10692 break;
10694 case POST_INC:
10695 ok = avr_reg_ok_for_pgm_addr (XEXP (x, 0), strict);
10696 break;
10698 default:
10699 break;
10702 break; /* FLASH */
10704 case ADDR_SPACE_MEMX:
10705 if (REG_P (x))
10706 ok = (!strict
10707 && can_create_pseudo_p());
10709 if (LO_SUM == GET_CODE (x))
10711 rtx hi = XEXP (x, 0);
10712 rtx lo = XEXP (x, 1);
10714 ok = (REG_P (hi)
10715 && (!strict || REGNO (hi) < FIRST_PSEUDO_REGISTER)
10716 && REG_P (lo)
10717 && REGNO (lo) == REG_Z);
10720 break; /* MEMX */
10723 if (avr_log.legitimate_address_p)
10725 avr_edump ("\n%?: ret=%b, mode=%m strict=%d "
10726 "reload_completed=%d reload_in_progress=%d %s:",
10727 ok, mode, strict, reload_completed, reload_in_progress,
10728 reg_renumber ? "(reg_renumber)" : "");
10730 if (GET_CODE (x) == PLUS
10731 && REG_P (XEXP (x, 0))
10732 && CONST_INT_P (XEXP (x, 1))
10733 && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
10734 && reg_renumber)
10736 avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
10737 true_regnum (XEXP (x, 0)));
10740 avr_edump ("\n%r\n", x);
10743 return ok;
10747 /* Implement `TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS'. */
10749 static rtx
10750 avr_addr_space_legitimize_address (rtx x, rtx old_x,
10751 enum machine_mode mode, addr_space_t as)
10753 if (ADDR_SPACE_GENERIC_P (as))
10754 return avr_legitimize_address (x, old_x, mode);
10756 if (avr_log.legitimize_address)
10758 avr_edump ("\n%?: mode=%m\n %r\n", mode, old_x);
10761 return old_x;
10765 /* Implement `TARGET_ADDR_SPACE_CONVERT'. */
10767 static rtx
10768 avr_addr_space_convert (rtx src, tree type_from, tree type_to)
10770 addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (type_from));
10771 addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type_to));
10773 if (avr_log.progmem)
10774 avr_edump ("\n%!: op = %r\nfrom = %t\nto = %t\n",
10775 src, type_from, type_to);
10777 /* Up-casting from 16-bit to 24-bit pointer. */
10779 if (as_from != ADDR_SPACE_MEMX
10780 && as_to == ADDR_SPACE_MEMX)
10782 int msb;
10783 rtx sym = src;
10784 rtx reg = gen_reg_rtx (PSImode);
10786 while (CONST == GET_CODE (sym) || PLUS == GET_CODE (sym))
10787 sym = XEXP (sym, 0);
10789 /* Look at symbol flags: avr_encode_section_info set the flags
10790 also if attribute progmem was seen so that we get the right
10791 promotion for, e.g. PSTR-like strings that reside in generic space
10792 but are located in flash. In that case we patch the incoming
10793 address space. */
10795 if (SYMBOL_REF == GET_CODE (sym)
10796 && ADDR_SPACE_FLASH == AVR_SYMBOL_GET_ADDR_SPACE (sym))
10798 as_from = ADDR_SPACE_FLASH;
10801 /* Linearize memory: RAM has bit 23 set. */
10803 msb = ADDR_SPACE_GENERIC_P (as_from)
10804 ? 0x80
10805 : avr_addrspace[as_from].segment;
10807 src = force_reg (Pmode, src);
10809 emit_insn (msb == 0
10810 ? gen_zero_extendhipsi2 (reg, src)
10811 : gen_n_extendhipsi2 (reg, gen_int_mode (msb, QImode), src));
10813 return reg;
10816 /* Down-casting from 24-bit to 16-bit throws away the high byte. */
10818 if (as_from == ADDR_SPACE_MEMX
10819 && as_to != ADDR_SPACE_MEMX)
10821 rtx new_src = gen_reg_rtx (Pmode);
10823 src = force_reg (PSImode, src);
10825 emit_move_insn (new_src,
10826 simplify_gen_subreg (Pmode, src, PSImode, 0));
10827 return new_src;
10830 return src;
10834 /* Implement `TARGET_ADDR_SPACE_SUBSET_P'. */
10836 static bool
10837 avr_addr_space_subset_p (addr_space_t subset ATTRIBUTE_UNUSED,
10838 addr_space_t superset ATTRIBUTE_UNUSED)
10840 /* Allow any kind of pointer mess. */
10842 return true;
10846 /* Implement `TARGET_CONVERT_TO_TYPE'. */
10848 static tree
10849 avr_convert_to_type (tree type, tree expr)
10851 /* Print a diagnose for pointer conversion that changes the address
10852 space of the pointer target to a non-enclosing address space,
10853 provided -Waddr-space-convert is on.
10855 FIXME: Filter out cases where the target object is known to
10856 be located in the right memory, like in
10858 (const __flash*) PSTR ("text")
10860 Also try to distinguish between explicit casts requested by
10861 the user and implicit casts like
10863 void f (const __flash char*);
10865 void g (const char *p)
10867 f ((const __flash*) p);
10870 under the assumption that an explicit casts means that the user
10871 knows what he is doing, e.g. interface with PSTR or old style
10872 code with progmem and pgm_read_xxx.
10875 if (avr_warn_addr_space_convert
10876 && expr != error_mark_node
10877 && POINTER_TYPE_P (type)
10878 && POINTER_TYPE_P (TREE_TYPE (expr)))
10880 addr_space_t as_old = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
10881 addr_space_t as_new = TYPE_ADDR_SPACE (TREE_TYPE (type));
10883 if (avr_log.progmem)
10884 avr_edump ("%?: type = %t\nexpr = %t\n\n", type, expr);
10886 if (as_new != ADDR_SPACE_MEMX
10887 && as_new != as_old)
10889 location_t loc = EXPR_LOCATION (expr);
10890 const char *name_old = avr_addrspace[as_old].name;
10891 const char *name_new = avr_addrspace[as_new].name;
10893 warning (OPT_Waddr_space_convert,
10894 "conversion from address space %qs to address space %qs",
10895 ADDR_SPACE_GENERIC_P (as_old) ? "generic" : name_old,
10896 ADDR_SPACE_GENERIC_P (as_new) ? "generic" : name_new);
10898 return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, expr);
10902 return NULL_TREE;
10906 /* Worker function for movmemhi expander.
10907 XOP[0] Destination as MEM:BLK
10908 XOP[1] Source " "
10909 XOP[2] # Bytes to copy
10911 Return TRUE if the expansion is accomplished.
10912 Return FALSE if the operand compination is not supported. */
10914 bool
10915 avr_emit_movmemhi (rtx *xop)
10917 HOST_WIDE_INT count;
10918 enum machine_mode loop_mode;
10919 addr_space_t as = MEM_ADDR_SPACE (xop[1]);
10920 rtx loop_reg, addr1, a_src, a_dest, insn, xas;
10921 rtx a_hi8 = NULL_RTX;
10923 if (avr_mem_flash_p (xop[0]))
10924 return false;
10926 if (!CONST_INT_P (xop[2]))
10927 return false;
10929 count = INTVAL (xop[2]);
10930 if (count <= 0)
10931 return false;
10933 a_src = XEXP (xop[1], 0);
10934 a_dest = XEXP (xop[0], 0);
10936 if (PSImode == GET_MODE (a_src))
10938 gcc_assert (as == ADDR_SPACE_MEMX);
10940 loop_mode = (count < 0x100) ? QImode : HImode;
10941 loop_reg = gen_rtx_REG (loop_mode, 24);
10942 emit_move_insn (loop_reg, gen_int_mode (count, loop_mode));
10944 addr1 = simplify_gen_subreg (HImode, a_src, PSImode, 0);
10945 a_hi8 = simplify_gen_subreg (QImode, a_src, PSImode, 2);
10947 else
10949 int segment = avr_addrspace[as].segment;
10951 if (segment
10952 && avr_current_device->n_flash > 1)
10954 a_hi8 = GEN_INT (segment);
10955 emit_move_insn (rampz_rtx, a_hi8 = copy_to_mode_reg (QImode, a_hi8));
10957 else if (!ADDR_SPACE_GENERIC_P (as))
10959 as = ADDR_SPACE_FLASH;
10962 addr1 = a_src;
10964 loop_mode = (count <= 0x100) ? QImode : HImode;
10965 loop_reg = copy_to_mode_reg (loop_mode, gen_int_mode (count, loop_mode));
10968 xas = GEN_INT (as);
10970 /* FIXME: Register allocator might come up with spill fails if it is left
10971 on its own. Thus, we allocate the pointer registers by hand:
10972 Z = source address
10973 X = destination address */
10975 emit_move_insn (lpm_addr_reg_rtx, addr1);
10976 emit_move_insn (gen_rtx_REG (HImode, REG_X), a_dest);
10978 /* FIXME: Register allocator does a bad job and might spill address
10979 register(s) inside the loop leading to additional move instruction
10980 to/from stack which could clobber tmp_reg. Thus, do *not* emit
10981 load and store as separate insns. Instead, we perform the copy
10982 by means of one monolithic insn. */
10984 gcc_assert (TMP_REGNO == LPM_REGNO);
10986 if (as != ADDR_SPACE_MEMX)
10988 /* Load instruction ([E]LPM or LD) is known at compile time:
10989 Do the copy-loop inline. */
10991 rtx (*fun) (rtx, rtx, rtx)
10992 = QImode == loop_mode ? gen_movmem_qi : gen_movmem_hi;
10994 insn = fun (xas, loop_reg, loop_reg);
10996 else
10998 rtx (*fun) (rtx, rtx)
10999 = QImode == loop_mode ? gen_movmemx_qi : gen_movmemx_hi;
11001 emit_move_insn (gen_rtx_REG (QImode, 23), a_hi8);
11003 insn = fun (xas, GEN_INT (avr_addr.rampz));
11006 set_mem_addr_space (SET_SRC (XVECEXP (insn, 0, 0)), as);
11007 emit_insn (insn);
11009 return true;
11013 /* Print assembler for movmem_qi, movmem_hi insns...
11014 $0 : Address Space
11015 $1, $2 : Loop register
11016 Z : Source address
11017 X : Destination address
11020 const char*
11021 avr_out_movmem (rtx insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
11023 addr_space_t as = (addr_space_t) INTVAL (op[0]);
11024 enum machine_mode loop_mode = GET_MODE (op[1]);
11025 bool sbiw_p = test_hard_reg_class (ADDW_REGS, op[1]);
11026 rtx xop[3];
11028 if (plen)
11029 *plen = 0;
11031 xop[0] = op[0];
11032 xop[1] = op[1];
11033 xop[2] = tmp_reg_rtx;
11035 /* Loop label */
11037 avr_asm_len ("0:", xop, plen, 0);
11039 /* Load with post-increment */
11041 switch (as)
11043 default:
11044 gcc_unreachable();
11046 case ADDR_SPACE_GENERIC:
11048 avr_asm_len ("ld %2,Z+", xop, plen, 1);
11049 break;
11051 case ADDR_SPACE_FLASH:
11053 if (AVR_HAVE_LPMX)
11054 avr_asm_len ("lpm %2,Z+", xop, plen, 1);
11055 else
11056 avr_asm_len ("lpm" CR_TAB
11057 "adiw r30,1", xop, plen, 2);
11058 break;
11060 case ADDR_SPACE_FLASH1:
11061 case ADDR_SPACE_FLASH2:
11062 case ADDR_SPACE_FLASH3:
11063 case ADDR_SPACE_FLASH4:
11064 case ADDR_SPACE_FLASH5:
11066 if (AVR_HAVE_ELPMX)
11067 avr_asm_len ("elpm %2,Z+", xop, plen, 1);
11068 else
11069 avr_asm_len ("elpm" CR_TAB
11070 "adiw r30,1", xop, plen, 2);
11071 break;
11074 /* Store with post-increment */
11076 avr_asm_len ("st X+,%2", xop, plen, 1);
11078 /* Decrement loop-counter and set Z-flag */
11080 if (QImode == loop_mode)
11082 avr_asm_len ("dec %1", xop, plen, 1);
11084 else if (sbiw_p)
11086 avr_asm_len ("sbiw %1,1", xop, plen, 1);
11088 else
11090 avr_asm_len ("subi %A1,1" CR_TAB
11091 "sbci %B1,0", xop, plen, 2);
11094 /* Loop until zero */
11096 return avr_asm_len ("brne 0b", xop, plen, 1);
11101 /* Helper for __builtin_avr_delay_cycles */
11103 static rtx
11104 avr_mem_clobber (void)
11106 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11107 MEM_VOLATILE_P (mem) = 1;
11108 return mem;
11111 static void
11112 avr_expand_delay_cycles (rtx operands0)
11114 unsigned HOST_WIDE_INT cycles = UINTVAL (operands0) & GET_MODE_MASK (SImode);
11115 unsigned HOST_WIDE_INT cycles_used;
11116 unsigned HOST_WIDE_INT loop_count;
11118 if (IN_RANGE (cycles, 83886082, 0xFFFFFFFF))
11120 loop_count = ((cycles - 9) / 6) + 1;
11121 cycles_used = ((loop_count - 1) * 6) + 9;
11122 emit_insn (gen_delay_cycles_4 (gen_int_mode (loop_count, SImode),
11123 avr_mem_clobber()));
11124 cycles -= cycles_used;
11127 if (IN_RANGE (cycles, 262145, 83886081))
11129 loop_count = ((cycles - 7) / 5) + 1;
11130 if (loop_count > 0xFFFFFF)
11131 loop_count = 0xFFFFFF;
11132 cycles_used = ((loop_count - 1) * 5) + 7;
11133 emit_insn (gen_delay_cycles_3 (gen_int_mode (loop_count, SImode),
11134 avr_mem_clobber()));
11135 cycles -= cycles_used;
11138 if (IN_RANGE (cycles, 768, 262144))
11140 loop_count = ((cycles - 5) / 4) + 1;
11141 if (loop_count > 0xFFFF)
11142 loop_count = 0xFFFF;
11143 cycles_used = ((loop_count - 1) * 4) + 5;
11144 emit_insn (gen_delay_cycles_2 (gen_int_mode (loop_count, HImode),
11145 avr_mem_clobber()));
11146 cycles -= cycles_used;
11149 if (IN_RANGE (cycles, 6, 767))
11151 loop_count = cycles / 3;
11152 if (loop_count > 255)
11153 loop_count = 255;
11154 cycles_used = loop_count * 3;
11155 emit_insn (gen_delay_cycles_1 (gen_int_mode (loop_count, QImode),
11156 avr_mem_clobber()));
11157 cycles -= cycles_used;
11160 while (cycles >= 2)
11162 emit_insn (gen_nopv (GEN_INT(2)));
11163 cycles -= 2;
11166 if (cycles == 1)
11168 emit_insn (gen_nopv (GEN_INT(1)));
11169 cycles--;
11174 /* Return VAL * BASE + DIGIT. BASE = 0 is shortcut for BASE = 2^{32} */
11176 static double_int
11177 avr_double_int_push_digit (double_int val, int base,
11178 unsigned HOST_WIDE_INT digit)
11180 val = 0 == base
11181 ? val.llshift (32, 64)
11182 : val * double_int::from_uhwi (base);
11184 return val + double_int::from_uhwi (digit);
11188 /* Compute the image of x under f, i.e. perform x --> f(x) */
11190 static int
11191 avr_map (double_int f, int x)
11193 return 0xf & f.lrshift (4*x, 64).to_uhwi ();
11197 /* Return some metrics of map A. */
11199 enum
11201 /* Number of fixed points in { 0 ... 7 } */
11202 MAP_FIXED_0_7,
11204 /* Size of preimage of non-fixed points in { 0 ... 7 } */
11205 MAP_NONFIXED_0_7,
11207 /* Mask representing the fixed points in { 0 ... 7 } */
11208 MAP_MASK_FIXED_0_7,
11210 /* Size of the preimage of { 0 ... 7 } */
11211 MAP_PREIMAGE_0_7,
11213 /* Mask that represents the preimage of { f } */
11214 MAP_MASK_PREIMAGE_F
11217 static unsigned
11218 avr_map_metric (double_int a, int mode)
11220 unsigned i, metric = 0;
11222 for (i = 0; i < 8; i++)
11224 unsigned ai = avr_map (a, i);
11226 if (mode == MAP_FIXED_0_7)
11227 metric += ai == i;
11228 else if (mode == MAP_NONFIXED_0_7)
11229 metric += ai < 8 && ai != i;
11230 else if (mode == MAP_MASK_FIXED_0_7)
11231 metric |= ((unsigned) (ai == i)) << i;
11232 else if (mode == MAP_PREIMAGE_0_7)
11233 metric += ai < 8;
11234 else if (mode == MAP_MASK_PREIMAGE_F)
11235 metric |= ((unsigned) (ai == 0xf)) << i;
11236 else
11237 gcc_unreachable();
11240 return metric;
11244 /* Return true if IVAL has a 0xf in its hexadecimal representation
11245 and false, otherwise. Only nibbles 0..7 are taken into account.
11246 Used as constraint helper for C0f and Cxf. */
11248 bool
11249 avr_has_nibble_0xf (rtx ival)
11251 return 0 != avr_map_metric (rtx_to_double_int (ival), MAP_MASK_PREIMAGE_F);
11255 /* We have a set of bits that are mapped by a function F.
11256 Try to decompose F by means of a second function G so that
11258 F = F o G^-1 o G
11262 cost (F o G^-1) + cost (G) < cost (F)
11264 Example: Suppose builtin insert_bits supplies us with the map
11265 F = 0x3210ffff. Instead of doing 4 bit insertions to get the high
11266 nibble of the result, we can just as well rotate the bits before inserting
11267 them and use the map 0x7654ffff which is cheaper than the original map.
11268 For this example G = G^-1 = 0x32107654 and F o G^-1 = 0x7654ffff. */
11270 typedef struct
11272 /* tree code of binary function G */
11273 enum tree_code code;
11275 /* The constant second argument of G */
11276 int arg;
11278 /* G^-1, the inverse of G (*, arg) */
11279 unsigned ginv;
11281 /* The cost of appplying G (*, arg) */
11282 int cost;
11284 /* The composition F o G^-1 (*, arg) for some function F */
11285 double_int map;
11287 /* For debug purpose only */
11288 const char *str;
11289 } avr_map_op_t;
11291 static const avr_map_op_t avr_map_op[] =
11293 { LROTATE_EXPR, 0, 0x76543210, 0, { 0, 0 }, "id" },
11294 { LROTATE_EXPR, 1, 0x07654321, 2, { 0, 0 }, "<<<" },
11295 { LROTATE_EXPR, 2, 0x10765432, 4, { 0, 0 }, "<<<" },
11296 { LROTATE_EXPR, 3, 0x21076543, 4, { 0, 0 }, "<<<" },
11297 { LROTATE_EXPR, 4, 0x32107654, 1, { 0, 0 }, "<<<" },
11298 { LROTATE_EXPR, 5, 0x43210765, 3, { 0, 0 }, "<<<" },
11299 { LROTATE_EXPR, 6, 0x54321076, 5, { 0, 0 }, "<<<" },
11300 { LROTATE_EXPR, 7, 0x65432107, 3, { 0, 0 }, "<<<" },
11301 { RSHIFT_EXPR, 1, 0x6543210c, 1, { 0, 0 }, ">>" },
11302 { RSHIFT_EXPR, 1, 0x7543210c, 1, { 0, 0 }, ">>" },
11303 { RSHIFT_EXPR, 2, 0x543210cc, 2, { 0, 0 }, ">>" },
11304 { RSHIFT_EXPR, 2, 0x643210cc, 2, { 0, 0 }, ">>" },
11305 { RSHIFT_EXPR, 2, 0x743210cc, 2, { 0, 0 }, ">>" },
11306 { LSHIFT_EXPR, 1, 0xc7654321, 1, { 0, 0 }, "<<" },
11307 { LSHIFT_EXPR, 2, 0xcc765432, 2, { 0, 0 }, "<<" }
11311 /* Try to decompose F as F = (F o G^-1) o G as described above.
11312 The result is a struct representing F o G^-1 and G.
11313 If result.cost < 0 then such a decomposition does not exist. */
11315 static avr_map_op_t
11316 avr_map_decompose (double_int f, const avr_map_op_t *g, bool val_const_p)
11318 int i;
11319 bool val_used_p = 0 != avr_map_metric (f, MAP_MASK_PREIMAGE_F);
11320 avr_map_op_t f_ginv = *g;
11321 double_int ginv = double_int::from_uhwi (g->ginv);
11323 f_ginv.cost = -1;
11325 /* Step 1: Computing F o G^-1 */
11327 for (i = 7; i >= 0; i--)
11329 int x = avr_map (f, i);
11331 if (x <= 7)
11333 x = avr_map (ginv, x);
11335 /* The bit is no element of the image of G: no avail (cost = -1) */
11337 if (x > 7)
11338 return f_ginv;
11341 f_ginv.map = avr_double_int_push_digit (f_ginv.map, 16, x);
11344 /* Step 2: Compute the cost of the operations.
11345 The overall cost of doing an operation prior to the insertion is
11346 the cost of the insertion plus the cost of the operation. */
11348 /* Step 2a: Compute cost of F o G^-1 */
11350 if (0 == avr_map_metric (f_ginv.map, MAP_NONFIXED_0_7))
11352 /* The mapping consists only of fixed points and can be folded
11353 to AND/OR logic in the remainder. Reasonable cost is 3. */
11355 f_ginv.cost = 2 + (val_used_p && !val_const_p);
11357 else
11359 rtx xop[4];
11361 /* Get the cost of the insn by calling the output worker with some
11362 fake values. Mimic effect of reloading xop[3]: Unused operands
11363 are mapped to 0 and used operands are reloaded to xop[0]. */
11365 xop[0] = all_regs_rtx[24];
11366 xop[1] = gen_int_mode (f_ginv.map.to_uhwi (), SImode);
11367 xop[2] = all_regs_rtx[25];
11368 xop[3] = val_used_p ? xop[0] : const0_rtx;
11370 avr_out_insert_bits (xop, &f_ginv.cost);
11372 f_ginv.cost += val_const_p && val_used_p ? 1 : 0;
11375 /* Step 2b: Add cost of G */
11377 f_ginv.cost += g->cost;
11379 if (avr_log.builtin)
11380 avr_edump (" %s%d=%d", g->str, g->arg, f_ginv.cost);
11382 return f_ginv;
11386 /* Insert bits from XOP[1] into XOP[0] according to MAP.
11387 XOP[0] and XOP[1] don't overlap.
11388 If FIXP_P = true: Move all bits according to MAP using BLD/BST sequences.
11389 If FIXP_P = false: Just move the bit if its position in the destination
11390 is different to its source position. */
11392 static void
11393 avr_move_bits (rtx *xop, double_int map, bool fixp_p, int *plen)
11395 int bit_dest, b;
11397 /* T-flag contains this bit of the source, i.e. of XOP[1] */
11398 int t_bit_src = -1;
11400 /* We order the operations according to the requested source bit b. */
11402 for (b = 0; b < 8; b++)
11403 for (bit_dest = 0; bit_dest < 8; bit_dest++)
11405 int bit_src = avr_map (map, bit_dest);
11407 if (b != bit_src
11408 || bit_src >= 8
11409 /* Same position: No need to copy as requested by FIXP_P. */
11410 || (bit_dest == bit_src && !fixp_p))
11411 continue;
11413 if (t_bit_src != bit_src)
11415 /* Source bit is not yet in T: Store it to T. */
11417 t_bit_src = bit_src;
11419 xop[3] = GEN_INT (bit_src);
11420 avr_asm_len ("bst %T1%T3", xop, plen, 1);
11423 /* Load destination bit with T. */
11425 xop[3] = GEN_INT (bit_dest);
11426 avr_asm_len ("bld %T0%T3", xop, plen, 1);
11431 /* PLEN == 0: Print assembler code for `insert_bits'.
11432 PLEN != 0: Compute code length in bytes.
11434 OP[0]: Result
11435 OP[1]: The mapping composed of nibbles. If nibble no. N is
11436 0: Bit N of result is copied from bit OP[2].0
11437 ... ...
11438 7: Bit N of result is copied from bit OP[2].7
11439 0xf: Bit N of result is copied from bit OP[3].N
11440 OP[2]: Bits to be inserted
11441 OP[3]: Target value */
11443 const char*
11444 avr_out_insert_bits (rtx *op, int *plen)
11446 double_int map = rtx_to_double_int (op[1]);
11447 unsigned mask_fixed;
11448 bool fixp_p = true;
11449 rtx xop[4];
11451 xop[0] = op[0];
11452 xop[1] = op[2];
11453 xop[2] = op[3];
11455 gcc_assert (REG_P (xop[2]) || CONST_INT_P (xop[2]));
11457 if (plen)
11458 *plen = 0;
11459 else if (flag_print_asm_name)
11460 fprintf (asm_out_file,
11461 ASM_COMMENT_START "map = 0x%08" HOST_LONG_FORMAT "x\n",
11462 map.to_uhwi () & GET_MODE_MASK (SImode));
11464 /* If MAP has fixed points it might be better to initialize the result
11465 with the bits to be inserted instead of moving all bits by hand. */
11467 mask_fixed = avr_map_metric (map, MAP_MASK_FIXED_0_7);
11469 if (REGNO (xop[0]) == REGNO (xop[1]))
11471 /* Avoid early-clobber conflicts */
11473 avr_asm_len ("mov __tmp_reg__,%1", xop, plen, 1);
11474 xop[1] = tmp_reg_rtx;
11475 fixp_p = false;
11478 if (avr_map_metric (map, MAP_MASK_PREIMAGE_F))
11480 /* XOP[2] is used and reloaded to XOP[0] already */
11482 int n_fix = 0, n_nofix = 0;
11484 gcc_assert (REG_P (xop[2]));
11486 /* Get the code size of the bit insertions; once with all bits
11487 moved and once with fixed points omitted. */
11489 avr_move_bits (xop, map, true, &n_fix);
11490 avr_move_bits (xop, map, false, &n_nofix);
11492 if (fixp_p && n_fix - n_nofix > 3)
11494 xop[3] = gen_int_mode (~mask_fixed, QImode);
11496 avr_asm_len ("eor %0,%1" CR_TAB
11497 "andi %0,%3" CR_TAB
11498 "eor %0,%1", xop, plen, 3);
11499 fixp_p = false;
11502 else
11504 /* XOP[2] is unused */
11506 if (fixp_p && mask_fixed)
11508 avr_asm_len ("mov %0,%1", xop, plen, 1);
11509 fixp_p = false;
11513 /* Move/insert remaining bits. */
11515 avr_move_bits (xop, map, fixp_p, plen);
11517 return "";
11521 /* IDs for all the AVR builtins. */
11523 enum avr_builtin_id
11525 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME) \
11526 AVR_BUILTIN_ ## NAME,
11527 #include "builtins.def"
11528 #undef DEF_BUILTIN
11530 AVR_BUILTIN_COUNT
11533 struct GTY(()) avr_builtin_description
11535 enum insn_code icode;
11536 int n_args;
11537 tree fndecl;
11541 /* Notice that avr_bdesc[] and avr_builtin_id are initialized in such a way
11542 that a built-in's ID can be used to access the built-in by means of
11543 avr_bdesc[ID] */
11545 static GTY(()) struct avr_builtin_description
11546 avr_bdesc[AVR_BUILTIN_COUNT] =
11548 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, LIBNAME) \
11549 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
11550 #include "builtins.def"
11551 #undef DEF_BUILTIN
11555 /* Implement `TARGET_BUILTIN_DECL'. */
11557 static tree
11558 avr_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED)
11560 if (id < AVR_BUILTIN_COUNT)
11561 return avr_bdesc[id].fndecl;
11563 return error_mark_node;
11567 static void
11568 avr_init_builtin_int24 (void)
11570 tree int24_type = make_signed_type (GET_MODE_BITSIZE (PSImode));
11571 tree uint24_type = make_unsigned_type (GET_MODE_BITSIZE (PSImode));
11573 lang_hooks.types.register_builtin_type (int24_type, "__int24");
11574 lang_hooks.types.register_builtin_type (uint24_type, "__uint24");
11578 /* Implement `TARGET_INIT_BUILTINS' */
11579 /* Set up all builtin functions for this target. */
11581 static void
11582 avr_init_builtins (void)
11584 tree void_ftype_void
11585 = build_function_type_list (void_type_node, NULL_TREE);
11586 tree uchar_ftype_uchar
11587 = build_function_type_list (unsigned_char_type_node,
11588 unsigned_char_type_node,
11589 NULL_TREE);
11590 tree uint_ftype_uchar_uchar
11591 = build_function_type_list (unsigned_type_node,
11592 unsigned_char_type_node,
11593 unsigned_char_type_node,
11594 NULL_TREE);
11595 tree int_ftype_char_char
11596 = build_function_type_list (integer_type_node,
11597 char_type_node,
11598 char_type_node,
11599 NULL_TREE);
11600 tree int_ftype_char_uchar
11601 = build_function_type_list (integer_type_node,
11602 char_type_node,
11603 unsigned_char_type_node,
11604 NULL_TREE);
11605 tree void_ftype_ulong
11606 = build_function_type_list (void_type_node,
11607 long_unsigned_type_node,
11608 NULL_TREE);
11610 tree uchar_ftype_ulong_uchar_uchar
11611 = build_function_type_list (unsigned_char_type_node,
11612 long_unsigned_type_node,
11613 unsigned_char_type_node,
11614 unsigned_char_type_node,
11615 NULL_TREE);
11617 tree const_memx_void_node
11618 = build_qualified_type (void_type_node,
11619 TYPE_QUAL_CONST
11620 | ENCODE_QUAL_ADDR_SPACE (ADDR_SPACE_MEMX));
11622 tree const_memx_ptr_type_node
11623 = build_pointer_type_for_mode (const_memx_void_node, PSImode, false);
11625 tree char_ftype_const_memx_ptr
11626 = build_function_type_list (char_type_node,
11627 const_memx_ptr_type_node,
11628 NULL);
11630 #define ITYP(T) \
11631 lang_hooks.types.type_for_size (TYPE_PRECISION (T), TYPE_UNSIGNED (T))
11633 #define FX_FTYPE_FX(fx) \
11634 tree fx##r_ftype_##fx##r \
11635 = build_function_type_list (node_##fx##r, node_##fx##r, NULL); \
11636 tree fx##k_ftype_##fx##k \
11637 = build_function_type_list (node_##fx##k, node_##fx##k, NULL)
11639 #define FX_FTYPE_FX_INT(fx) \
11640 tree fx##r_ftype_##fx##r_int \
11641 = build_function_type_list (node_##fx##r, node_##fx##r, \
11642 integer_type_node, NULL); \
11643 tree fx##k_ftype_##fx##k_int \
11644 = build_function_type_list (node_##fx##k, node_##fx##k, \
11645 integer_type_node, NULL)
11647 #define INT_FTYPE_FX(fx) \
11648 tree int_ftype_##fx##r \
11649 = build_function_type_list (integer_type_node, node_##fx##r, NULL); \
11650 tree int_ftype_##fx##k \
11651 = build_function_type_list (integer_type_node, node_##fx##k, NULL)
11653 #define INTX_FTYPE_FX(fx) \
11654 tree int##fx##r_ftype_##fx##r \
11655 = build_function_type_list (ITYP (node_##fx##r), node_##fx##r, NULL); \
11656 tree int##fx##k_ftype_##fx##k \
11657 = build_function_type_list (ITYP (node_##fx##k), node_##fx##k, NULL)
11659 #define FX_FTYPE_INTX(fx) \
11660 tree fx##r_ftype_int##fx##r \
11661 = build_function_type_list (node_##fx##r, ITYP (node_##fx##r), NULL); \
11662 tree fx##k_ftype_int##fx##k \
11663 = build_function_type_list (node_##fx##k, ITYP (node_##fx##k), NULL)
11665 tree node_hr = short_fract_type_node;
11666 tree node_nr = fract_type_node;
11667 tree node_lr = long_fract_type_node;
11668 tree node_llr = long_long_fract_type_node;
11670 tree node_uhr = unsigned_short_fract_type_node;
11671 tree node_unr = unsigned_fract_type_node;
11672 tree node_ulr = unsigned_long_fract_type_node;
11673 tree node_ullr = unsigned_long_long_fract_type_node;
11675 tree node_hk = short_accum_type_node;
11676 tree node_nk = accum_type_node;
11677 tree node_lk = long_accum_type_node;
11678 tree node_llk = long_long_accum_type_node;
11680 tree node_uhk = unsigned_short_accum_type_node;
11681 tree node_unk = unsigned_accum_type_node;
11682 tree node_ulk = unsigned_long_accum_type_node;
11683 tree node_ullk = unsigned_long_long_accum_type_node;
11686 /* For absfx builtins. */
11688 FX_FTYPE_FX (h);
11689 FX_FTYPE_FX (n);
11690 FX_FTYPE_FX (l);
11691 FX_FTYPE_FX (ll);
11693 /* For roundfx builtins. */
11695 FX_FTYPE_FX_INT (h);
11696 FX_FTYPE_FX_INT (n);
11697 FX_FTYPE_FX_INT (l);
11698 FX_FTYPE_FX_INT (ll);
11700 FX_FTYPE_FX_INT (uh);
11701 FX_FTYPE_FX_INT (un);
11702 FX_FTYPE_FX_INT (ul);
11703 FX_FTYPE_FX_INT (ull);
11705 /* For countlsfx builtins. */
11707 INT_FTYPE_FX (h);
11708 INT_FTYPE_FX (n);
11709 INT_FTYPE_FX (l);
11710 INT_FTYPE_FX (ll);
11712 INT_FTYPE_FX (uh);
11713 INT_FTYPE_FX (un);
11714 INT_FTYPE_FX (ul);
11715 INT_FTYPE_FX (ull);
11717 /* For bitsfx builtins. */
11719 INTX_FTYPE_FX (h);
11720 INTX_FTYPE_FX (n);
11721 INTX_FTYPE_FX (l);
11722 INTX_FTYPE_FX (ll);
11724 INTX_FTYPE_FX (uh);
11725 INTX_FTYPE_FX (un);
11726 INTX_FTYPE_FX (ul);
11727 INTX_FTYPE_FX (ull);
11729 /* For fxbits builtins. */
11731 FX_FTYPE_INTX (h);
11732 FX_FTYPE_INTX (n);
11733 FX_FTYPE_INTX (l);
11734 FX_FTYPE_INTX (ll);
11736 FX_FTYPE_INTX (uh);
11737 FX_FTYPE_INTX (un);
11738 FX_FTYPE_INTX (ul);
11739 FX_FTYPE_INTX (ull);
11742 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME) \
11744 int id = AVR_BUILTIN_ ## NAME; \
11745 const char *Name = "__builtin_avr_" #NAME; \
11746 char *name = (char*) alloca (1 + strlen (Name)); \
11748 gcc_assert (id < AVR_BUILTIN_COUNT); \
11749 avr_bdesc[id].fndecl \
11750 = add_builtin_function (avr_tolower (name, Name), TYPE, id, \
11751 BUILT_IN_MD, LIBNAME, NULL_TREE); \
11753 #include "builtins.def"
11754 #undef DEF_BUILTIN
11756 avr_init_builtin_int24 ();
11760 /* Subroutine of avr_expand_builtin to expand vanilla builtins
11761 with non-void result and 1 ... 3 arguments. */
11763 static rtx
11764 avr_default_expand_builtin (enum insn_code icode, tree exp, rtx target)
11766 rtx pat, xop[3];
11767 int n, n_args = call_expr_nargs (exp);
11768 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11770 gcc_assert (n_args >= 1 && n_args <= 3);
11772 if (target == NULL_RTX
11773 || GET_MODE (target) != tmode
11774 || !insn_data[icode].operand[0].predicate (target, tmode))
11776 target = gen_reg_rtx (tmode);
11779 for (n = 0; n < n_args; n++)
11781 tree arg = CALL_EXPR_ARG (exp, n);
11782 rtx op = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
11783 enum machine_mode opmode = GET_MODE (op);
11784 enum machine_mode mode = insn_data[icode].operand[n+1].mode;
11786 if ((opmode == SImode || opmode == VOIDmode) && mode == HImode)
11788 opmode = HImode;
11789 op = gen_lowpart (HImode, op);
11792 /* In case the insn wants input operands in modes different from
11793 the result, abort. */
11795 gcc_assert (opmode == mode || opmode == VOIDmode);
11797 if (!insn_data[icode].operand[n+1].predicate (op, mode))
11798 op = copy_to_mode_reg (mode, op);
11800 xop[n] = op;
11803 switch (n_args)
11805 case 1: pat = GEN_FCN (icode) (target, xop[0]); break;
11806 case 2: pat = GEN_FCN (icode) (target, xop[0], xop[1]); break;
11807 case 3: pat = GEN_FCN (icode) (target, xop[0], xop[1], xop[2]); break;
11809 default:
11810 gcc_unreachable();
11813 if (pat == NULL_RTX)
11814 return NULL_RTX;
11816 emit_insn (pat);
11818 return target;
11822 /* Implement `TARGET_EXPAND_BUILTIN'. */
11823 /* Expand an expression EXP that calls a built-in function,
11824 with result going to TARGET if that's convenient
11825 (and in mode MODE if that's convenient).
11826 SUBTARGET may be used as the target for computing one of EXP's operands.
11827 IGNORE is nonzero if the value is to be ignored. */
11829 static rtx
11830 avr_expand_builtin (tree exp, rtx target,
11831 rtx subtarget ATTRIBUTE_UNUSED,
11832 enum machine_mode mode ATTRIBUTE_UNUSED,
11833 int ignore)
11835 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11836 const char *bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
11837 unsigned int id = DECL_FUNCTION_CODE (fndecl);
11838 const struct avr_builtin_description *d = &avr_bdesc[id];
11839 tree arg0;
11840 rtx op0;
11842 gcc_assert (id < AVR_BUILTIN_COUNT);
11844 switch (id)
11846 case AVR_BUILTIN_NOP:
11847 emit_insn (gen_nopv (GEN_INT(1)));
11848 return 0;
11850 case AVR_BUILTIN_DELAY_CYCLES:
11852 arg0 = CALL_EXPR_ARG (exp, 0);
11853 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
11855 if (!CONST_INT_P (op0))
11856 error ("%s expects a compile time integer constant", bname);
11857 else
11858 avr_expand_delay_cycles (op0);
11860 return NULL_RTX;
11863 case AVR_BUILTIN_INSERT_BITS:
11865 arg0 = CALL_EXPR_ARG (exp, 0);
11866 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
11868 if (!CONST_INT_P (op0))
11870 error ("%s expects a compile time long integer constant"
11871 " as first argument", bname);
11872 return target;
11875 break;
11878 case AVR_BUILTIN_ROUNDHR: case AVR_BUILTIN_ROUNDUHR:
11879 case AVR_BUILTIN_ROUNDR: case AVR_BUILTIN_ROUNDUR:
11880 case AVR_BUILTIN_ROUNDLR: case AVR_BUILTIN_ROUNDULR:
11881 case AVR_BUILTIN_ROUNDLLR: case AVR_BUILTIN_ROUNDULLR:
11883 case AVR_BUILTIN_ROUNDHK: case AVR_BUILTIN_ROUNDUHK:
11884 case AVR_BUILTIN_ROUNDK: case AVR_BUILTIN_ROUNDUK:
11885 case AVR_BUILTIN_ROUNDLK: case AVR_BUILTIN_ROUNDULK:
11886 case AVR_BUILTIN_ROUNDLLK: case AVR_BUILTIN_ROUNDULLK:
11888 /* Warn about odd rounding. Rounding points >= FBIT will have
11889 no effect. */
11891 if (TREE_CODE (CALL_EXPR_ARG (exp, 1)) != INTEGER_CST)
11892 break;
11894 int rbit = (int) TREE_INT_CST_LOW (CALL_EXPR_ARG (exp, 1));
11896 if (rbit >= (int) GET_MODE_FBIT (mode))
11898 warning (OPT_Wextra, "rounding to %d bits has no effect for "
11899 "fixed-point value with %d fractional bits",
11900 rbit, GET_MODE_FBIT (mode));
11902 return expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX, mode,
11903 EXPAND_NORMAL);
11905 else if (rbit <= - (int) GET_MODE_IBIT (mode))
11907 warning (0, "rounding result will always be 0");
11908 return CONST0_RTX (mode);
11911 /* The rounding points RP satisfies now: -IBIT < RP < FBIT.
11913 TR 18037 only specifies results for RP > 0. However, the
11914 remaining cases of -IBIT < RP <= 0 can easily be supported
11915 without any additional overhead. */
11917 break; /* round */
11920 /* No fold found and no insn: Call support function from libgcc. */
11922 if (d->icode == CODE_FOR_nothing
11923 && DECL_ASSEMBLER_NAME (get_callee_fndecl (exp)) != NULL_TREE)
11925 return expand_call (exp, target, ignore);
11928 /* No special treatment needed: vanilla expand. */
11930 gcc_assert (d->icode != CODE_FOR_nothing);
11931 gcc_assert (d->n_args == call_expr_nargs (exp));
11933 if (d->n_args == 0)
11935 emit_insn ((GEN_FCN (d->icode)) (target));
11936 return NULL_RTX;
11939 return avr_default_expand_builtin (d->icode, exp, target);
11943 /* Helper for `avr_fold_builtin' that folds absfx (FIXED_CST). */
11945 static tree
11946 avr_fold_absfx (tree tval)
11948 if (FIXED_CST != TREE_CODE (tval))
11949 return NULL_TREE;
11951 /* Our fixed-points have no padding: Use double_int payload directly. */
11953 FIXED_VALUE_TYPE fval = TREE_FIXED_CST (tval);
11954 unsigned int bits = GET_MODE_BITSIZE (fval.mode);
11955 double_int ival = fval.data.sext (bits);
11957 if (!ival.is_negative())
11958 return tval;
11960 /* ISO/IEC TR 18037, 7.18a.6.2: The absfx functions are saturating. */
11962 fval.data = (ival == double_int::min_value (bits, false).sext (bits))
11963 ? double_int::max_value (bits, false)
11964 : -ival;
11966 return build_fixed (TREE_TYPE (tval), fval);
11970 /* Implement `TARGET_FOLD_BUILTIN'. */
11972 static tree
11973 avr_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg,
11974 bool ignore ATTRIBUTE_UNUSED)
11976 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11977 tree val_type = TREE_TYPE (TREE_TYPE (fndecl));
11979 if (!optimize)
11980 return NULL_TREE;
11982 switch (fcode)
11984 default:
11985 break;
11987 case AVR_BUILTIN_SWAP:
11989 return fold_build2 (LROTATE_EXPR, val_type, arg[0],
11990 build_int_cst (val_type, 4));
11993 case AVR_BUILTIN_ABSHR:
11994 case AVR_BUILTIN_ABSR:
11995 case AVR_BUILTIN_ABSLR:
11996 case AVR_BUILTIN_ABSLLR:
11998 case AVR_BUILTIN_ABSHK:
11999 case AVR_BUILTIN_ABSK:
12000 case AVR_BUILTIN_ABSLK:
12001 case AVR_BUILTIN_ABSLLK:
12002 /* GCC is not good with folding ABS for fixed-point. Do it by hand. */
12004 return avr_fold_absfx (arg[0]);
12006 case AVR_BUILTIN_BITSHR: case AVR_BUILTIN_HRBITS:
12007 case AVR_BUILTIN_BITSHK: case AVR_BUILTIN_HKBITS:
12008 case AVR_BUILTIN_BITSUHR: case AVR_BUILTIN_UHRBITS:
12009 case AVR_BUILTIN_BITSUHK: case AVR_BUILTIN_UHKBITS:
12011 case AVR_BUILTIN_BITSR: case AVR_BUILTIN_RBITS:
12012 case AVR_BUILTIN_BITSK: case AVR_BUILTIN_KBITS:
12013 case AVR_BUILTIN_BITSUR: case AVR_BUILTIN_URBITS:
12014 case AVR_BUILTIN_BITSUK: case AVR_BUILTIN_UKBITS:
12016 case AVR_BUILTIN_BITSLR: case AVR_BUILTIN_LRBITS:
12017 case AVR_BUILTIN_BITSLK: case AVR_BUILTIN_LKBITS:
12018 case AVR_BUILTIN_BITSULR: case AVR_BUILTIN_ULRBITS:
12019 case AVR_BUILTIN_BITSULK: case AVR_BUILTIN_ULKBITS:
12021 case AVR_BUILTIN_BITSLLR: case AVR_BUILTIN_LLRBITS:
12022 case AVR_BUILTIN_BITSLLK: case AVR_BUILTIN_LLKBITS:
12023 case AVR_BUILTIN_BITSULLR: case AVR_BUILTIN_ULLRBITS:
12024 case AVR_BUILTIN_BITSULLK: case AVR_BUILTIN_ULLKBITS:
12026 gcc_assert (TYPE_PRECISION (val_type)
12027 == TYPE_PRECISION (TREE_TYPE (arg[0])));
12029 return build1 (VIEW_CONVERT_EXPR, val_type, arg[0]);
12031 case AVR_BUILTIN_INSERT_BITS:
12033 tree tbits = arg[1];
12034 tree tval = arg[2];
12035 tree tmap;
12036 tree map_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
12037 double_int map;
12038 bool changed = false;
12039 unsigned i;
12040 avr_map_op_t best_g;
12042 if (TREE_CODE (arg[0]) != INTEGER_CST)
12044 /* No constant as first argument: Don't fold this and run into
12045 error in avr_expand_builtin. */
12047 break;
12050 map = tree_to_double_int (arg[0]);
12051 tmap = double_int_to_tree (map_type, map);
12053 if (TREE_CODE (tval) != INTEGER_CST
12054 && 0 == avr_map_metric (map, MAP_MASK_PREIMAGE_F))
12056 /* There are no F in the map, i.e. 3rd operand is unused.
12057 Replace that argument with some constant to render
12058 respective input unused. */
12060 tval = build_int_cst (val_type, 0);
12061 changed = true;
12064 if (TREE_CODE (tbits) != INTEGER_CST
12065 && 0 == avr_map_metric (map, MAP_PREIMAGE_0_7))
12067 /* Similar for the bits to be inserted. If they are unused,
12068 we can just as well pass 0. */
12070 tbits = build_int_cst (val_type, 0);
12073 if (TREE_CODE (tbits) == INTEGER_CST)
12075 /* Inserting bits known at compile time is easy and can be
12076 performed by AND and OR with appropriate masks. */
12078 int bits = TREE_INT_CST_LOW (tbits);
12079 int mask_ior = 0, mask_and = 0xff;
12081 for (i = 0; i < 8; i++)
12083 int mi = avr_map (map, i);
12085 if (mi < 8)
12087 if (bits & (1 << mi)) mask_ior |= (1 << i);
12088 else mask_and &= ~(1 << i);
12092 tval = fold_build2 (BIT_IOR_EXPR, val_type, tval,
12093 build_int_cst (val_type, mask_ior));
12094 return fold_build2 (BIT_AND_EXPR, val_type, tval,
12095 build_int_cst (val_type, mask_and));
12098 if (changed)
12099 return build_call_expr (fndecl, 3, tmap, tbits, tval);
12101 /* If bits don't change their position we can use vanilla logic
12102 to merge the two arguments. */
12104 if (0 == avr_map_metric (map, MAP_NONFIXED_0_7))
12106 int mask_f = avr_map_metric (map, MAP_MASK_PREIMAGE_F);
12107 tree tres, tmask = build_int_cst (val_type, mask_f ^ 0xff);
12109 tres = fold_build2 (BIT_XOR_EXPR, val_type, tbits, tval);
12110 tres = fold_build2 (BIT_AND_EXPR, val_type, tres, tmask);
12111 return fold_build2 (BIT_XOR_EXPR, val_type, tres, tval);
12114 /* Try to decomposing map to reduce overall cost. */
12116 if (avr_log.builtin)
12117 avr_edump ("\n%?: %X\n%?: ROL cost: ", map);
12119 best_g = avr_map_op[0];
12120 best_g.cost = 1000;
12122 for (i = 0; i < sizeof (avr_map_op) / sizeof (*avr_map_op); i++)
12124 avr_map_op_t g
12125 = avr_map_decompose (map, avr_map_op + i,
12126 TREE_CODE (tval) == INTEGER_CST);
12128 if (g.cost >= 0 && g.cost < best_g.cost)
12129 best_g = g;
12132 if (avr_log.builtin)
12133 avr_edump ("\n");
12135 if (best_g.arg == 0)
12136 /* No optimization found */
12137 break;
12139 /* Apply operation G to the 2nd argument. */
12141 if (avr_log.builtin)
12142 avr_edump ("%?: using OP(%s%d, %X) cost %d\n",
12143 best_g.str, best_g.arg, best_g.map, best_g.cost);
12145 /* Do right-shifts arithmetically: They copy the MSB instead of
12146 shifting in a non-usable value (0) as with logic right-shift. */
12148 tbits = fold_convert (signed_char_type_node, tbits);
12149 tbits = fold_build2 (best_g.code, signed_char_type_node, tbits,
12150 build_int_cst (val_type, best_g.arg));
12151 tbits = fold_convert (val_type, tbits);
12153 /* Use map o G^-1 instead of original map to undo the effect of G. */
12155 tmap = double_int_to_tree (map_type, best_g.map);
12157 return build_call_expr (fndecl, 3, tmap, tbits, tval);
12158 } /* AVR_BUILTIN_INSERT_BITS */
12161 return NULL_TREE;
12166 /* Initialize the GCC target structure. */
12168 #undef TARGET_ASM_ALIGNED_HI_OP
12169 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
12170 #undef TARGET_ASM_ALIGNED_SI_OP
12171 #define TARGET_ASM_ALIGNED_SI_OP "\t.long\t"
12172 #undef TARGET_ASM_UNALIGNED_HI_OP
12173 #define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
12174 #undef TARGET_ASM_UNALIGNED_SI_OP
12175 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
12176 #undef TARGET_ASM_INTEGER
12177 #define TARGET_ASM_INTEGER avr_assemble_integer
12178 #undef TARGET_ASM_FILE_START
12179 #define TARGET_ASM_FILE_START avr_file_start
12180 #undef TARGET_ASM_FILE_END
12181 #define TARGET_ASM_FILE_END avr_file_end
12183 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
12184 #define TARGET_ASM_FUNCTION_END_PROLOGUE avr_asm_function_end_prologue
12185 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
12186 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE avr_asm_function_begin_epilogue
12188 #undef TARGET_FUNCTION_VALUE
12189 #define TARGET_FUNCTION_VALUE avr_function_value
12190 #undef TARGET_LIBCALL_VALUE
12191 #define TARGET_LIBCALL_VALUE avr_libcall_value
12192 #undef TARGET_FUNCTION_VALUE_REGNO_P
12193 #define TARGET_FUNCTION_VALUE_REGNO_P avr_function_value_regno_p
12195 #undef TARGET_ATTRIBUTE_TABLE
12196 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
12197 #undef TARGET_INSERT_ATTRIBUTES
12198 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
12199 #undef TARGET_SECTION_TYPE_FLAGS
12200 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
12202 #undef TARGET_ASM_NAMED_SECTION
12203 #define TARGET_ASM_NAMED_SECTION avr_asm_named_section
12204 #undef TARGET_ASM_INIT_SECTIONS
12205 #define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections
12206 #undef TARGET_ENCODE_SECTION_INFO
12207 #define TARGET_ENCODE_SECTION_INFO avr_encode_section_info
12208 #undef TARGET_ASM_SELECT_SECTION
12209 #define TARGET_ASM_SELECT_SECTION avr_asm_select_section
12211 #undef TARGET_REGISTER_MOVE_COST
12212 #define TARGET_REGISTER_MOVE_COST avr_register_move_cost
12213 #undef TARGET_MEMORY_MOVE_COST
12214 #define TARGET_MEMORY_MOVE_COST avr_memory_move_cost
12215 #undef TARGET_RTX_COSTS
12216 #define TARGET_RTX_COSTS avr_rtx_costs
12217 #undef TARGET_ADDRESS_COST
12218 #define TARGET_ADDRESS_COST avr_address_cost
12219 #undef TARGET_MACHINE_DEPENDENT_REORG
12220 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
12221 #undef TARGET_FUNCTION_ARG
12222 #define TARGET_FUNCTION_ARG avr_function_arg
12223 #undef TARGET_FUNCTION_ARG_ADVANCE
12224 #define TARGET_FUNCTION_ARG_ADVANCE avr_function_arg_advance
12226 #undef TARGET_SET_CURRENT_FUNCTION
12227 #define TARGET_SET_CURRENT_FUNCTION avr_set_current_function
12229 #undef TARGET_RETURN_IN_MEMORY
12230 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
12232 #undef TARGET_STRICT_ARGUMENT_NAMING
12233 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
12235 #undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
12236 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE avr_builtin_setjmp_frame_value
12238 #undef TARGET_HARD_REGNO_SCRATCH_OK
12239 #define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok
12240 #undef TARGET_CASE_VALUES_THRESHOLD
12241 #define TARGET_CASE_VALUES_THRESHOLD avr_case_values_threshold
12243 #undef TARGET_FRAME_POINTER_REQUIRED
12244 #define TARGET_FRAME_POINTER_REQUIRED avr_frame_pointer_required_p
12245 #undef TARGET_CAN_ELIMINATE
12246 #define TARGET_CAN_ELIMINATE avr_can_eliminate
12248 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
12249 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS avr_allocate_stack_slots_for_args
12251 #undef TARGET_WARN_FUNC_RETURN
12252 #define TARGET_WARN_FUNC_RETURN avr_warn_func_return
12254 #undef TARGET_CLASS_LIKELY_SPILLED_P
12255 #define TARGET_CLASS_LIKELY_SPILLED_P avr_class_likely_spilled_p
12257 #undef TARGET_OPTION_OVERRIDE
12258 #define TARGET_OPTION_OVERRIDE avr_option_override
12260 #undef TARGET_CANNOT_MODIFY_JUMPS_P
12261 #define TARGET_CANNOT_MODIFY_JUMPS_P avr_cannot_modify_jumps_p
12263 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
12264 #define TARGET_FUNCTION_OK_FOR_SIBCALL avr_function_ok_for_sibcall
12266 #undef TARGET_INIT_BUILTINS
12267 #define TARGET_INIT_BUILTINS avr_init_builtins
12269 #undef TARGET_BUILTIN_DECL
12270 #define TARGET_BUILTIN_DECL avr_builtin_decl
12272 #undef TARGET_EXPAND_BUILTIN
12273 #define TARGET_EXPAND_BUILTIN avr_expand_builtin
12275 #undef TARGET_FOLD_BUILTIN
12276 #define TARGET_FOLD_BUILTIN avr_fold_builtin
12278 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
12279 #define TARGET_ASM_FUNCTION_RODATA_SECTION avr_asm_function_rodata_section
12281 #undef TARGET_SCALAR_MODE_SUPPORTED_P
12282 #define TARGET_SCALAR_MODE_SUPPORTED_P avr_scalar_mode_supported_p
12284 #undef TARGET_BUILD_BUILTIN_VA_LIST
12285 #define TARGET_BUILD_BUILTIN_VA_LIST avr_build_builtin_va_list
12287 #undef TARGET_FIXED_POINT_SUPPORTED_P
12288 #define TARGET_FIXED_POINT_SUPPORTED_P hook_bool_void_true
12290 #undef TARGET_CONVERT_TO_TYPE
12291 #define TARGET_CONVERT_TO_TYPE avr_convert_to_type
12293 #undef TARGET_ADDR_SPACE_SUBSET_P
12294 #define TARGET_ADDR_SPACE_SUBSET_P avr_addr_space_subset_p
12296 #undef TARGET_ADDR_SPACE_CONVERT
12297 #define TARGET_ADDR_SPACE_CONVERT avr_addr_space_convert
12299 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
12300 #define TARGET_ADDR_SPACE_ADDRESS_MODE avr_addr_space_address_mode
12302 #undef TARGET_ADDR_SPACE_POINTER_MODE
12303 #define TARGET_ADDR_SPACE_POINTER_MODE avr_addr_space_pointer_mode
12305 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
12306 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
12307 avr_addr_space_legitimate_address_p
12309 #undef TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS
12310 #define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS avr_addr_space_legitimize_address
12312 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
12313 #define TARGET_MODE_DEPENDENT_ADDRESS_P avr_mode_dependent_address_p
12315 #undef TARGET_SECONDARY_RELOAD
12316 #define TARGET_SECONDARY_RELOAD avr_secondary_reload
12318 #undef TARGET_PRINT_OPERAND
12319 #define TARGET_PRINT_OPERAND avr_print_operand
12320 #undef TARGET_PRINT_OPERAND_ADDRESS
12321 #define TARGET_PRINT_OPERAND_ADDRESS avr_print_operand_address
12322 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
12323 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P avr_print_operand_punct_valid_p
12325 struct gcc_target targetm = TARGET_INITIALIZER;
12328 #include "gt-avr.h"