1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2 Copyright (C) 1998-2016 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)
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/>. */
23 #include "coretypes.h"
27 #include "c-family/c-common.h"
35 #include "conditions.h"
36 #include "insn-attr.h"
40 #include "stor-layout.h"
44 #include "langhooks.h"
49 #include "tree-pass.h"
51 /* This file should be included last. */
52 #include "target-def.h"
54 /* Maximal allowed offset for an address in the LD command */
55 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
57 /* Return true if STR starts with PREFIX and false, otherwise. */
58 #define STR_PREFIX_P(STR,PREFIX) (0 == strncmp (STR, PREFIX, strlen (PREFIX)))
60 /* The 4 bits starting at SECTION_MACH_DEP are reserved to store the
61 address space where data is to be located.
62 As the only non-generic address spaces are all located in flash,
63 this can be used to test if data shall go into some .progmem* section.
64 This must be the rightmost field of machine dependent section flags. */
65 #define AVR_SECTION_PROGMEM (0xf * SECTION_MACH_DEP)
67 /* Similar 4-bit region for SYMBOL_REF_FLAGS. */
68 #define AVR_SYMBOL_FLAG_PROGMEM (0xf * SYMBOL_FLAG_MACH_DEP)
70 /* Similar 4-bit region in SYMBOL_REF_FLAGS:
71 Set address-space AS in SYMBOL_REF_FLAGS of SYM */
72 #define AVR_SYMBOL_SET_ADDR_SPACE(SYM,AS) \
74 SYMBOL_REF_FLAGS (sym) &= ~AVR_SYMBOL_FLAG_PROGMEM; \
75 SYMBOL_REF_FLAGS (sym) |= (AS) * SYMBOL_FLAG_MACH_DEP; \
78 /* Read address-space from SYMBOL_REF_FLAGS of SYM */
79 #define AVR_SYMBOL_GET_ADDR_SPACE(SYM) \
80 ((SYMBOL_REF_FLAGS (sym) & AVR_SYMBOL_FLAG_PROGMEM) \
81 / SYMBOL_FLAG_MACH_DEP)
83 #define TINY_ADIW(REG1, REG2, I) \
84 "subi " #REG1 ",lo8(-(" #I "))" CR_TAB \
85 "sbci " #REG2 ",hi8(-(" #I "))"
87 #define TINY_SBIW(REG1, REG2, I) \
88 "subi " #REG1 ",lo8((" #I "))" CR_TAB \
89 "sbci " #REG2 ",hi8((" #I "))"
91 #define AVR_TMP_REGNO (AVR_TINY ? TMP_REGNO_TINY : TMP_REGNO)
92 #define AVR_ZERO_REGNO (AVR_TINY ? ZERO_REGNO_TINY : ZERO_REGNO)
94 /* Known address spaces. The order must be the same as in the respective
95 enum from avr.h (or designated initialized must be used). */
96 const avr_addrspace_t avr_addrspace[ADDR_SPACE_COUNT] =
98 { ADDR_SPACE_RAM, 0, 2, "", 0, NULL },
99 { ADDR_SPACE_FLASH, 1, 2, "__flash", 0, ".progmem.data" },
100 { ADDR_SPACE_FLASH1, 1, 2, "__flash1", 1, ".progmem1.data" },
101 { ADDR_SPACE_FLASH2, 1, 2, "__flash2", 2, ".progmem2.data" },
102 { ADDR_SPACE_FLASH3, 1, 2, "__flash3", 3, ".progmem3.data" },
103 { ADDR_SPACE_FLASH4, 1, 2, "__flash4", 4, ".progmem4.data" },
104 { ADDR_SPACE_FLASH5, 1, 2, "__flash5", 5, ".progmem5.data" },
105 { ADDR_SPACE_MEMX, 1, 3, "__memx", 0, ".progmemx.data" },
109 /* Holding RAM addresses of some SFRs used by the compiler and that
110 are unique over all devices in an architecture like 'avr4'. */
114 /* SREG: The processor status */
117 /* RAMPX, RAMPY, RAMPD and CCP of XMEGA */
123 /* RAMPZ: The high byte of 24-bit address used with ELPM */
126 /* SP: The stack pointer and its low and high byte */
131 static avr_addr_t avr_addr;
134 /* Prototypes for local helper functions. */
136 static const char* out_movqi_r_mr (rtx_insn *, rtx[], int*);
137 static const char* out_movhi_r_mr (rtx_insn *, rtx[], int*);
138 static const char* out_movsi_r_mr (rtx_insn *, rtx[], int*);
139 static const char* out_movqi_mr_r (rtx_insn *, rtx[], int*);
140 static const char* out_movhi_mr_r (rtx_insn *, rtx[], int*);
141 static const char* out_movsi_mr_r (rtx_insn *, rtx[], int*);
143 static int get_sequence_length (rtx_insn *insns);
144 static int sequent_regs_live (void);
145 static const char *ptrreg_to_str (int);
146 static const char *cond_string (enum rtx_code);
147 static int avr_num_arg_regs (machine_mode, const_tree);
148 static int avr_operand_rtx_cost (rtx, machine_mode, enum rtx_code,
150 static void output_reload_in_const (rtx*, rtx, int*, bool);
151 static struct machine_function * avr_init_machine_status (void);
154 /* Prototypes for hook implementors if needed before their implementation. */
156 static bool avr_rtx_costs (rtx, machine_mode, int, int, int*, bool);
159 /* Allocate registers from r25 to r8 for parameters for function calls. */
160 #define FIRST_CUM_REG 26
162 /* Last call saved register */
163 #define LAST_CALLEE_SAVED_REG (AVR_TINY ? 19 : 17)
165 /* Implicit target register of LPM instruction (R0) */
166 extern GTY(()) rtx lpm_reg_rtx;
169 /* (Implicit) address register of LPM instruction (R31:R30 = Z) */
170 extern GTY(()) rtx lpm_addr_reg_rtx;
171 rtx lpm_addr_reg_rtx;
173 /* Temporary register RTX (reg:QI TMP_REGNO) */
174 extern GTY(()) rtx tmp_reg_rtx;
177 /* Zeroed register RTX (reg:QI ZERO_REGNO) */
178 extern GTY(()) rtx zero_reg_rtx;
181 /* RTXs for all general purpose registers as QImode */
182 extern GTY(()) rtx all_regs_rtx[32];
183 rtx all_regs_rtx[32];
185 /* SREG, the processor status */
186 extern GTY(()) rtx sreg_rtx;
189 /* RAMP* special function registers */
190 extern GTY(()) rtx rampd_rtx;
191 extern GTY(()) rtx rampx_rtx;
192 extern GTY(()) rtx rampy_rtx;
193 extern GTY(()) rtx rampz_rtx;
199 /* RTX containing the strings "" and "e", respectively */
200 static GTY(()) rtx xstring_empty;
201 static GTY(()) rtx xstring_e;
203 /* Current architecture. */
204 const avr_arch_t *avr_arch;
206 /* Unnamed sections associated to __attribute__((progmem)) aka. PROGMEM
207 or to address space __flash* or __memx. Only used as singletons inside
208 avr_asm_select_section, but it must not be local there because of GTY. */
209 static GTY(()) section *progmem_section[ADDR_SPACE_COUNT];
211 /* Condition for insns/expanders from avr-dimode.md. */
212 bool avr_have_dimode = true;
214 /* To track if code will use .bss and/or .data. */
215 bool avr_need_clear_bss_p = false;
216 bool avr_need_copy_data_p = false;
219 /* Transform UP into lowercase and write the result to LO.
220 You must provide enough space for LO. Return LO. */
223 avr_tolower (char *lo, const char *up)
227 for (; *up; up++, lo++)
236 /* Custom function to count number of set bits. */
239 avr_popcount (unsigned int val)
253 /* Constraint helper function. XVAL is a CONST_INT or a CONST_DOUBLE.
254 Return true if the least significant N_BYTES bytes of XVAL all have a
255 popcount in POP_MASK and false, otherwise. POP_MASK represents a subset
256 of integers which contains an integer N iff bit N of POP_MASK is set. */
259 avr_popcount_each_byte (rtx xval, int n_bytes, int pop_mask)
263 machine_mode mode = GET_MODE (xval);
265 if (VOIDmode == mode)
268 for (i = 0; i < n_bytes; i++)
270 rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
271 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
273 if (0 == (pop_mask & (1 << avr_popcount (val8))))
281 /* Access some RTX as INT_MODE. If X is a CONST_FIXED we can get
282 the bit representation of X by "casting" it to CONST_INT. */
285 avr_to_int_mode (rtx x)
287 machine_mode mode = GET_MODE (x);
289 return VOIDmode == mode
291 : simplify_gen_subreg (int_mode_for_mode (mode), x, mode, 0);
295 static const pass_data avr_pass_data_recompute_notes =
298 "", // name (will be patched)
299 OPTGROUP_NONE, // optinfo_flags
301 0, // properties_required
302 0, // properties_provided
303 0, // properties_destroyed
304 0, // todo_flags_start
305 TODO_df_finish | TODO_df_verify // todo_flags_finish
309 class avr_pass_recompute_notes : public rtl_opt_pass
312 avr_pass_recompute_notes (gcc::context *ctxt, const char *name)
313 : rtl_opt_pass (avr_pass_data_recompute_notes, ctxt)
318 virtual unsigned int execute (function*)
320 df_note_add_problem ();
325 }; // avr_pass_recompute_notes
329 avr_register_passes (void)
331 /* This avr-specific pass (re)computes insn notes, in particular REG_DEAD
332 notes which are used by `avr.c::reg_unused_after' and branch offset
333 computations. These notes must be correct, i.e. there must be no
334 dangling REG_DEAD notes; otherwise wrong code might result, cf. PR64331.
336 DF needs (correct) CFG, hence right before free_cfg is the last
337 opportunity to rectify notes. */
339 register_pass (new avr_pass_recompute_notes (g, "avr-notes-free-cfg"),
340 PASS_POS_INSERT_BEFORE, "*free_cfg", 1);
344 /* Set `avr_arch' as specified by `-mmcu='.
345 Return true on success. */
348 avr_set_core_architecture (void)
350 /* Search for mcu core architecture. */
353 avr_mmcu = AVR_MMCU_DEFAULT;
355 avr_arch = &avr_arch_types[0];
357 for (const avr_mcu_t *mcu = avr_mcu_types; ; mcu++)
359 if (NULL == mcu->name)
361 /* Reached the end of `avr_mcu_types'. This should actually never
362 happen as options are provided by device-specs. It could be a
363 typo in a device-specs or calling the compiler proper directly
364 with -mmcu=<device>. */
366 error ("unknown core architecture %qs specified with %qs",
368 avr_inform_core_architectures ();
371 else if (0 == strcmp (mcu->name, avr_mmcu)
372 // Is this a proper architecture ?
373 && NULL == mcu->macro)
375 avr_arch = &avr_arch_types[mcu->arch_id];
377 avr_n_flash = mcu->n_flash;
387 /* Implement `TARGET_OPTION_OVERRIDE'. */
390 avr_option_override (void)
392 /* Disable -fdelete-null-pointer-checks option for AVR target.
393 This option compiler assumes that dereferencing of a null pointer
394 would halt the program. For AVR this assumption is not true and
395 programs can safely dereference null pointers. Changes made by this
396 option may not work properly for AVR. So disable this option. */
398 flag_delete_null_pointer_checks = 0;
400 /* caller-save.c looks for call-clobbered hard registers that are assigned
401 to pseudos that cross calls and tries so save-restore them around calls
402 in order to reduce the number of stack slots needed.
404 This might lead to situations where reload is no more able to cope
405 with the challenge of AVR's very few address registers and fails to
406 perform the requested spills. */
409 flag_caller_saves = 0;
411 /* Allow optimizer to introduce store data races. This used to be the
412 default - it was changed because bigger targets did not see any
413 performance decrease. For the AVR though, disallowing data races
414 introduces additional code in LIM and increases reg pressure. */
416 maybe_set_param_value (PARAM_ALLOW_STORE_DATA_RACES, 1,
417 global_options.x_param_values,
418 global_options_set.x_param_values);
420 /* Unwind tables currently require a frame pointer for correctness,
421 see toplev.c:process_options(). */
423 if ((flag_unwind_tables
424 || flag_non_call_exceptions
425 || flag_asynchronous_unwind_tables)
426 && !ACCUMULATE_OUTGOING_ARGS)
428 flag_omit_frame_pointer = 0;
432 warning (OPT_fpic, "-fpic is not supported");
434 warning (OPT_fPIC, "-fPIC is not supported");
436 warning (OPT_fpie, "-fpie is not supported");
438 warning (OPT_fPIE, "-fPIE is not supported");
440 if (!avr_set_core_architecture())
443 /* RAM addresses of some SFRs common to all devices in respective arch. */
445 /* SREG: Status Register containing flags like I (global IRQ) */
446 avr_addr.sreg = 0x3F + avr_arch->sfr_offset;
448 /* RAMPZ: Address' high part when loading via ELPM */
449 avr_addr.rampz = 0x3B + avr_arch->sfr_offset;
451 avr_addr.rampy = 0x3A + avr_arch->sfr_offset;
452 avr_addr.rampx = 0x39 + avr_arch->sfr_offset;
453 avr_addr.rampd = 0x38 + avr_arch->sfr_offset;
454 avr_addr.ccp = (AVR_TINY ? 0x3C : 0x34) + avr_arch->sfr_offset;
456 /* SP: Stack Pointer (SP_H:SP_L) */
457 avr_addr.sp_l = 0x3D + avr_arch->sfr_offset;
458 avr_addr.sp_h = avr_addr.sp_l + 1;
460 init_machine_status = avr_init_machine_status;
462 avr_log_set_avr_log();
464 /* Register some avr-specific pass(es). There is no canonical place for
465 pass registration. This function is convenient. */
467 avr_register_passes ();
470 /* Function to set up the backend function structure. */
472 static struct machine_function *
473 avr_init_machine_status (void)
475 return ggc_cleared_alloc<machine_function> ();
479 /* Implement `INIT_EXPANDERS'. */
480 /* The function works like a singleton. */
483 avr_init_expanders (void)
487 for (regno = 0; regno < 32; regno ++)
488 all_regs_rtx[regno] = gen_rtx_REG (QImode, regno);
490 lpm_reg_rtx = all_regs_rtx[LPM_REGNO];
491 tmp_reg_rtx = all_regs_rtx[AVR_TMP_REGNO];
492 zero_reg_rtx = all_regs_rtx[AVR_ZERO_REGNO];
494 lpm_addr_reg_rtx = gen_rtx_REG (HImode, REG_Z);
496 sreg_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.sreg));
497 rampd_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampd));
498 rampx_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampx));
499 rampy_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampy));
500 rampz_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampz));
502 xstring_empty = gen_rtx_CONST_STRING (VOIDmode, "");
503 xstring_e = gen_rtx_CONST_STRING (VOIDmode, "e");
505 /* TINY core does not have regs r10-r16, but avr-dimode.md expects them
508 avr_have_dimode = false;
512 /* Implement `REGNO_REG_CLASS'. */
513 /* Return register class for register R. */
516 avr_regno_reg_class (int r)
518 static const enum reg_class reg_class_tab[] =
522 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
523 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
524 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
525 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
527 SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
528 SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
530 ADDW_REGS, ADDW_REGS,
532 POINTER_X_REGS, POINTER_X_REGS,
534 POINTER_Y_REGS, POINTER_Y_REGS,
536 POINTER_Z_REGS, POINTER_Z_REGS,
542 return reg_class_tab[r];
548 /* Implement `TARGET_SCALAR_MODE_SUPPORTED_P'. */
551 avr_scalar_mode_supported_p (machine_mode mode)
553 if (ALL_FIXED_POINT_MODE_P (mode))
559 return default_scalar_mode_supported_p (mode);
563 /* Return TRUE if DECL is a VAR_DECL located in flash and FALSE, otherwise. */
566 avr_decl_flash_p (tree decl)
568 if (TREE_CODE (decl) != VAR_DECL
569 || TREE_TYPE (decl) == error_mark_node)
574 return !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (decl)));
578 /* Return TRUE if DECL is a VAR_DECL located in the 24-bit flash
579 address space and FALSE, otherwise. */
582 avr_decl_memx_p (tree decl)
584 if (TREE_CODE (decl) != VAR_DECL
585 || TREE_TYPE (decl) == error_mark_node)
590 return (ADDR_SPACE_MEMX == TYPE_ADDR_SPACE (TREE_TYPE (decl)));
594 /* Return TRUE if X is a MEM rtx located in flash and FALSE, otherwise. */
597 avr_mem_flash_p (rtx x)
600 && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x)));
604 /* Return TRUE if X is a MEM rtx located in the 24-bit flash
605 address space and FALSE, otherwise. */
608 avr_mem_memx_p (rtx x)
611 && ADDR_SPACE_MEMX == MEM_ADDR_SPACE (x));
615 /* A helper for the subsequent function attribute used to dig for
616 attribute 'name' in a FUNCTION_DECL or FUNCTION_TYPE */
619 avr_lookup_function_attribute1 (const_tree func, const char *name)
621 if (FUNCTION_DECL == TREE_CODE (func))
623 if (NULL_TREE != lookup_attribute (name, DECL_ATTRIBUTES (func)))
628 func = TREE_TYPE (func);
631 gcc_assert (TREE_CODE (func) == FUNCTION_TYPE
632 || TREE_CODE (func) == METHOD_TYPE);
634 return NULL_TREE != lookup_attribute (name, TYPE_ATTRIBUTES (func));
637 /* Return nonzero if FUNC is a naked function. */
640 avr_naked_function_p (tree func)
642 return avr_lookup_function_attribute1 (func, "naked");
645 /* Return nonzero if FUNC is an interrupt function as specified
646 by the "interrupt" attribute. */
649 avr_interrupt_function_p (tree func)
651 return avr_lookup_function_attribute1 (func, "interrupt");
654 /* Return nonzero if FUNC is a signal function as specified
655 by the "signal" attribute. */
658 avr_signal_function_p (tree func)
660 return avr_lookup_function_attribute1 (func, "signal");
663 /* Return nonzero if FUNC is an OS_task function. */
666 avr_OS_task_function_p (tree func)
668 return avr_lookup_function_attribute1 (func, "OS_task");
671 /* Return nonzero if FUNC is an OS_main function. */
674 avr_OS_main_function_p (tree func)
676 return avr_lookup_function_attribute1 (func, "OS_main");
680 /* Implement `TARGET_SET_CURRENT_FUNCTION'. */
681 /* Sanity cheching for above function attributes. */
684 avr_set_current_function (tree decl)
689 if (decl == NULL_TREE
690 || current_function_decl == NULL_TREE
691 || current_function_decl == error_mark_node
693 || cfun->machine->attributes_checked_p)
696 loc = DECL_SOURCE_LOCATION (decl);
698 cfun->machine->is_naked = avr_naked_function_p (decl);
699 cfun->machine->is_signal = avr_signal_function_p (decl);
700 cfun->machine->is_interrupt = avr_interrupt_function_p (decl);
701 cfun->machine->is_OS_task = avr_OS_task_function_p (decl);
702 cfun->machine->is_OS_main = avr_OS_main_function_p (decl);
704 isr = cfun->machine->is_interrupt ? "interrupt" : "signal";
706 /* Too much attributes make no sense as they request conflicting features. */
708 if (cfun->machine->is_OS_task + cfun->machine->is_OS_main
709 + (cfun->machine->is_signal || cfun->machine->is_interrupt) > 1)
710 error_at (loc, "function attributes %qs, %qs and %qs are mutually"
711 " exclusive", "OS_task", "OS_main", isr);
713 /* 'naked' will hide effects of 'OS_task' and 'OS_main'. */
715 if (cfun->machine->is_naked
716 && (cfun->machine->is_OS_task || cfun->machine->is_OS_main))
717 warning_at (loc, OPT_Wattributes, "function attributes %qs and %qs have"
718 " no effect on %qs function", "OS_task", "OS_main", "naked");
720 if (cfun->machine->is_interrupt || cfun->machine->is_signal)
722 tree args = TYPE_ARG_TYPES (TREE_TYPE (decl));
723 tree ret = TREE_TYPE (TREE_TYPE (decl));
726 name = DECL_ASSEMBLER_NAME_SET_P (decl)
727 ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))
728 : IDENTIFIER_POINTER (DECL_NAME (decl));
730 /* Skip a leading '*' that might still prefix the assembler name,
731 e.g. in non-LTO runs. */
733 name = default_strip_name_encoding (name);
735 /* Silently ignore 'signal' if 'interrupt' is present. AVR-LibC startet
736 using this when it switched from SIGNAL and INTERRUPT to ISR. */
738 if (cfun->machine->is_interrupt)
739 cfun->machine->is_signal = 0;
741 /* Interrupt handlers must be void __vector (void) functions. */
743 if (args && TREE_CODE (TREE_VALUE (args)) != VOID_TYPE)
744 error_at (loc, "%qs function cannot have arguments", isr);
746 if (TREE_CODE (ret) != VOID_TYPE)
747 error_at (loc, "%qs function cannot return a value", isr);
749 /* If the function has the 'signal' or 'interrupt' attribute, ensure
750 that the name of the function is "__vector_NN" so as to catch
751 when the user misspells the vector name. */
753 if (!STR_PREFIX_P (name, "__vector"))
754 warning_at (loc, 0, "%qs appears to be a misspelled %s handler",
758 /* Don't print the above diagnostics more than once. */
760 cfun->machine->attributes_checked_p = 1;
764 /* Implement `ACCUMULATE_OUTGOING_ARGS'. */
767 avr_accumulate_outgoing_args (void)
770 return TARGET_ACCUMULATE_OUTGOING_ARGS;
772 /* FIXME: For setjmp and in avr_builtin_setjmp_frame_value we don't know
773 what offset is correct. In some cases it is relative to
774 virtual_outgoing_args_rtx and in others it is relative to
775 virtual_stack_vars_rtx. For example code see
776 gcc.c-torture/execute/built-in-setjmp.c
777 gcc.c-torture/execute/builtins/sprintf-chk.c */
779 return (TARGET_ACCUMULATE_OUTGOING_ARGS
780 && !(cfun->calls_setjmp
781 || cfun->has_nonlocal_label));
785 /* Report contribution of accumulated outgoing arguments to stack size. */
788 avr_outgoing_args_size (void)
790 return ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0;
794 /* Implement `STARTING_FRAME_OFFSET'. */
795 /* This is the offset from the frame pointer register to the first stack slot
796 that contains a variable living in the frame. */
799 avr_starting_frame_offset (void)
801 return 1 + avr_outgoing_args_size ();
805 /* Return the number of hard registers to push/pop in the prologue/epilogue
806 of the current function, and optionally store these registers in SET. */
809 avr_regs_to_save (HARD_REG_SET *set)
812 int int_or_sig_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
815 CLEAR_HARD_REG_SET (*set);
818 /* No need to save any registers if the function never returns or
819 has the "OS_task" or "OS_main" attribute. */
821 if (TREE_THIS_VOLATILE (current_function_decl)
822 || cfun->machine->is_OS_task
823 || cfun->machine->is_OS_main)
826 for (reg = 0; reg < 32; reg++)
828 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
829 any global register variables. */
834 if ((int_or_sig_p && !crtl->is_leaf && call_used_regs[reg])
835 || (df_regs_ever_live_p (reg)
836 && (int_or_sig_p || !call_used_regs[reg])
837 /* Don't record frame pointer registers here. They are treated
838 indivitually in prologue. */
839 && !(frame_pointer_needed
840 && (reg == REG_Y || reg == (REG_Y+1)))))
843 SET_HARD_REG_BIT (*set, reg);
851 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
854 avr_allocate_stack_slots_for_args (void)
856 return !cfun->machine->is_naked;
860 /* Return true if register FROM can be eliminated via register TO. */
863 avr_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
865 return ((frame_pointer_needed && to == FRAME_POINTER_REGNUM)
866 || !frame_pointer_needed);
870 /* Implement `TARGET_WARN_FUNC_RETURN'. */
873 avr_warn_func_return (tree decl)
875 /* Naked functions are implemented entirely in assembly, including the
876 return sequence, so suppress warnings about this. */
878 return !avr_naked_function_p (decl);
881 /* Compute offset between arg_pointer and frame_pointer. */
884 avr_initial_elimination_offset (int from, int to)
886 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
890 int offset = frame_pointer_needed ? 2 : 0;
891 int avr_pc_size = AVR_HAVE_EIJMP_EICALL ? 3 : 2;
893 offset += avr_regs_to_save (NULL);
894 return (get_frame_size () + avr_outgoing_args_size()
895 + avr_pc_size + 1 + offset);
900 /* Helper for the function below. */
903 avr_adjust_type_node (tree *node, machine_mode mode, int sat_p)
905 *node = make_node (FIXED_POINT_TYPE);
906 TYPE_SATURATING (*node) = sat_p;
907 TYPE_UNSIGNED (*node) = UNSIGNED_FIXED_POINT_MODE_P (mode);
908 TYPE_IBIT (*node) = GET_MODE_IBIT (mode);
909 TYPE_FBIT (*node) = GET_MODE_FBIT (mode);
910 TYPE_PRECISION (*node) = GET_MODE_BITSIZE (mode);
911 SET_TYPE_ALIGN (*node, 8);
912 SET_TYPE_MODE (*node, mode);
918 /* Implement `TARGET_BUILD_BUILTIN_VA_LIST'. */
921 avr_build_builtin_va_list (void)
923 /* avr-modes.def adjusts [U]TA to be 64-bit modes with 48 fractional bits.
924 This is more appropriate for the 8-bit machine AVR than 128-bit modes.
925 The ADJUST_IBIT/FBIT are handled in toplev:init_adjust_machine_modes()
926 which is auto-generated by genmodes, but the compiler assigns [U]DAmode
927 to the long long accum modes instead of the desired [U]TAmode.
929 Fix this now, right after node setup in tree.c:build_common_tree_nodes().
930 This must run before c-cppbuiltin.c:builtin_define_fixed_point_constants()
931 which built-in defines macros like __ULLACCUM_FBIT__ that are used by
932 libgcc to detect IBIT and FBIT. */
934 avr_adjust_type_node (&ta_type_node, TAmode, 0);
935 avr_adjust_type_node (&uta_type_node, UTAmode, 0);
936 avr_adjust_type_node (&sat_ta_type_node, TAmode, 1);
937 avr_adjust_type_node (&sat_uta_type_node, UTAmode, 1);
939 unsigned_long_long_accum_type_node = uta_type_node;
940 long_long_accum_type_node = ta_type_node;
941 sat_unsigned_long_long_accum_type_node = sat_uta_type_node;
942 sat_long_long_accum_type_node = sat_ta_type_node;
944 /* Dispatch to the default handler. */
946 return std_build_builtin_va_list ();
950 /* Implement `TARGET_BUILTIN_SETJMP_FRAME_VALUE'. */
951 /* Actual start of frame is virtual_stack_vars_rtx this is offset from
952 frame pointer by +STARTING_FRAME_OFFSET.
953 Using saved frame = virtual_stack_vars_rtx - STARTING_FRAME_OFFSET
954 avoids creating add/sub of offset in nonlocal goto and setjmp. */
957 avr_builtin_setjmp_frame_value (void)
959 rtx xval = gen_reg_rtx (Pmode);
960 emit_insn (gen_subhi3 (xval, virtual_stack_vars_rtx,
961 gen_int_mode (STARTING_FRAME_OFFSET, Pmode)));
966 /* Return contents of MEM at frame pointer + stack size + 1 (+2 if 3-byte PC).
967 This is return address of function. */
970 avr_return_addr_rtx (int count, rtx tem)
974 /* Can only return this function's return address. Others not supported. */
980 r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+2");
981 warning (0, "%<builtin_return_address%> contains only 2 bytes"
985 r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+1");
987 r = gen_rtx_PLUS (Pmode, tem, r);
988 r = gen_frame_mem (Pmode, memory_address (Pmode, r));
989 r = gen_rtx_ROTATE (HImode, r, GEN_INT (8));
993 /* Return 1 if the function epilogue is just a single "ret". */
996 avr_simple_epilogue (void)
998 return (! frame_pointer_needed
999 && get_frame_size () == 0
1000 && avr_outgoing_args_size() == 0
1001 && avr_regs_to_save (NULL) == 0
1002 && ! cfun->machine->is_interrupt
1003 && ! cfun->machine->is_signal
1004 && ! cfun->machine->is_naked
1005 && ! TREE_THIS_VOLATILE (current_function_decl));
1008 /* This function checks sequence of live registers. */
1011 sequent_regs_live (void)
1017 for (reg = 0; reg <= LAST_CALLEE_SAVED_REG; ++reg)
1019 if (fixed_regs[reg])
1021 /* Don't recognize sequences that contain global register
1030 if (!call_used_regs[reg])
1032 if (df_regs_ever_live_p (reg))
1042 if (!frame_pointer_needed)
1044 if (df_regs_ever_live_p (REG_Y))
1052 if (df_regs_ever_live_p (REG_Y+1))
1065 return (cur_seq == live_seq) ? live_seq : 0;
1068 /* Obtain the length sequence of insns. */
1071 get_sequence_length (rtx_insn *insns)
1076 for (insn = insns, length = 0; insn; insn = NEXT_INSN (insn))
1077 length += get_attr_length (insn);
1083 /* Implement `INCOMING_RETURN_ADDR_RTX'. */
1086 avr_incoming_return_addr_rtx (void)
1088 /* The return address is at the top of the stack. Note that the push
1089 was via post-decrement, which means the actual address is off by one. */
1090 return gen_frame_mem (HImode, plus_constant (Pmode, stack_pointer_rtx, 1));
1093 /* Helper for expand_prologue. Emit a push of a byte register. */
1096 emit_push_byte (unsigned regno, bool frame_related_p)
1101 mem = gen_rtx_POST_DEC (HImode, stack_pointer_rtx);
1102 mem = gen_frame_mem (QImode, mem);
1103 reg = gen_rtx_REG (QImode, regno);
1105 insn = emit_insn (gen_rtx_SET (mem, reg));
1106 if (frame_related_p)
1107 RTX_FRAME_RELATED_P (insn) = 1;
1109 cfun->machine->stack_usage++;
1113 /* Helper for expand_prologue. Emit a push of a SFR via tmp_reg.
1114 SFR is a MEM representing the memory location of the SFR.
1115 If CLR_P then clear the SFR after the push using zero_reg. */
1118 emit_push_sfr (rtx sfr, bool frame_related_p, bool clr_p)
1122 gcc_assert (MEM_P (sfr));
1124 /* IN __tmp_reg__, IO(SFR) */
1125 insn = emit_move_insn (tmp_reg_rtx, sfr);
1126 if (frame_related_p)
1127 RTX_FRAME_RELATED_P (insn) = 1;
1129 /* PUSH __tmp_reg__ */
1130 emit_push_byte (AVR_TMP_REGNO, frame_related_p);
1134 /* OUT IO(SFR), __zero_reg__ */
1135 insn = emit_move_insn (sfr, const0_rtx);
1136 if (frame_related_p)
1137 RTX_FRAME_RELATED_P (insn) = 1;
1142 avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set)
1145 bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
1146 int live_seq = sequent_regs_live ();
1148 HOST_WIDE_INT size_max
1149 = (HOST_WIDE_INT) GET_MODE_MASK (AVR_HAVE_8BIT_SP ? QImode : Pmode);
1151 bool minimize = (TARGET_CALL_PROLOGUES
1155 && !cfun->machine->is_OS_task
1156 && !cfun->machine->is_OS_main
1160 && (frame_pointer_needed
1161 || avr_outgoing_args_size() > 8
1162 || (AVR_2_BYTE_PC && live_seq > 6)
1166 int first_reg, reg, offset;
1168 emit_move_insn (gen_rtx_REG (HImode, REG_X),
1169 gen_int_mode (size, HImode));
1171 pattern = gen_call_prologue_saves (gen_int_mode (live_seq, HImode),
1172 gen_int_mode (live_seq+size, HImode));
1173 insn = emit_insn (pattern);
1174 RTX_FRAME_RELATED_P (insn) = 1;
1176 /* Describe the effect of the unspec_volatile call to prologue_saves.
1177 Note that this formulation assumes that add_reg_note pushes the
1178 notes to the front. Thus we build them in the reverse order of
1179 how we want dwarf2out to process them. */
1181 /* The function does always set frame_pointer_rtx, but whether that
1182 is going to be permanent in the function is frame_pointer_needed. */
1184 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1185 gen_rtx_SET ((frame_pointer_needed
1187 : stack_pointer_rtx),
1188 plus_constant (Pmode, stack_pointer_rtx,
1189 -(size + live_seq))));
1191 /* Note that live_seq always contains r28+r29, but the other
1192 registers to be saved are all below 18. */
1194 first_reg = (LAST_CALLEE_SAVED_REG + 1) - (live_seq - 2);
1196 for (reg = 29, offset = -live_seq + 1;
1198 reg = (reg == 28 ? LAST_CALLEE_SAVED_REG : reg - 1), ++offset)
1202 m = gen_rtx_MEM (QImode, plus_constant (Pmode, stack_pointer_rtx,
1204 r = gen_rtx_REG (QImode, reg);
1205 add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (m, r));
1208 cfun->machine->stack_usage += size + live_seq;
1210 else /* !minimize */
1214 for (reg = 0; reg < 32; ++reg)
1215 if (TEST_HARD_REG_BIT (set, reg))
1216 emit_push_byte (reg, true);
1218 if (frame_pointer_needed
1219 && (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main)))
1221 /* Push frame pointer. Always be consistent about the
1222 ordering of pushes -- epilogue_restores expects the
1223 register pair to be pushed low byte first. */
1225 emit_push_byte (REG_Y, true);
1226 emit_push_byte (REG_Y + 1, true);
1229 if (frame_pointer_needed
1232 insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1233 RTX_FRAME_RELATED_P (insn) = 1;
1238 /* Creating a frame can be done by direct manipulation of the
1239 stack or via the frame pointer. These two methods are:
1246 the optimum method depends on function type, stack and
1247 frame size. To avoid a complex logic, both methods are
1248 tested and shortest is selected.
1250 There is also the case where SIZE != 0 and no frame pointer is
1251 needed; this can occur if ACCUMULATE_OUTGOING_ARGS is on.
1252 In that case, insn (*) is not needed in that case.
1253 We use the X register as scratch. This is save because in X
1255 In an interrupt routine, the case of SIZE != 0 together with
1256 !frame_pointer_needed can only occur if the function is not a
1257 leaf function and thus X has already been saved. */
1260 HOST_WIDE_INT size_cfa = size, neg_size;
1261 rtx_insn *fp_plus_insns;
1264 gcc_assert (frame_pointer_needed
1268 fp = my_fp = (frame_pointer_needed
1270 : gen_rtx_REG (Pmode, REG_X));
1272 if (AVR_HAVE_8BIT_SP)
1274 /* The high byte (r29) does not change:
1275 Prefer SUBI (1 cycle) over SBIW (2 cycles, same size). */
1277 my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
1280 /* Cut down size and avoid size = 0 so that we don't run
1281 into ICE like PR52488 in the remainder. */
1283 if (size > size_max)
1285 /* Don't error so that insane code from newlib still compiles
1286 and does not break building newlib. As PR51345 is implemented
1287 now, there are multilib variants with -msp8.
1289 If user wants sanity checks he can use -Wstack-usage=
1292 For CFA we emit the original, non-saturated size so that
1293 the generic machinery is aware of the real stack usage and
1294 will print the above diagnostic as expected. */
1299 size = trunc_int_for_mode (size, GET_MODE (my_fp));
1300 neg_size = trunc_int_for_mode (-size, GET_MODE (my_fp));
1302 /************ Method 1: Adjust frame pointer ************/
1306 /* Normally, the dwarf2out frame-related-expr interpreter does
1307 not expect to have the CFA change once the frame pointer is
1308 set up. Thus, we avoid marking the move insn below and
1309 instead indicate that the entire operation is complete after
1310 the frame pointer subtraction is done. */
1312 insn = emit_move_insn (fp, stack_pointer_rtx);
1313 if (frame_pointer_needed)
1315 RTX_FRAME_RELATED_P (insn) = 1;
1316 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1317 gen_rtx_SET (fp, stack_pointer_rtx));
1320 insn = emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp),
1323 if (frame_pointer_needed)
1325 RTX_FRAME_RELATED_P (insn) = 1;
1326 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1327 gen_rtx_SET (fp, plus_constant (Pmode, fp,
1331 /* Copy to stack pointer. Note that since we've already
1332 changed the CFA to the frame pointer this operation
1333 need not be annotated if frame pointer is needed.
1334 Always move through unspec, see PR50063.
1335 For meaning of irq_state see movhi_sp_r insn. */
1337 if (cfun->machine->is_interrupt)
1340 if (TARGET_NO_INTERRUPTS
1341 || cfun->machine->is_signal
1342 || cfun->machine->is_OS_main)
1345 if (AVR_HAVE_8BIT_SP)
1348 insn = emit_insn (gen_movhi_sp_r (stack_pointer_rtx,
1349 fp, GEN_INT (irq_state)));
1350 if (!frame_pointer_needed)
1352 RTX_FRAME_RELATED_P (insn) = 1;
1353 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1354 gen_rtx_SET (stack_pointer_rtx,
1355 plus_constant (Pmode,
1360 fp_plus_insns = get_insns ();
1363 /************ Method 2: Adjust Stack pointer ************/
1365 /* Stack adjustment by means of RCALL . and/or PUSH __TMP_REG__
1366 can only handle specific offsets. */
1368 if (avr_sp_immediate_operand (gen_int_mode (-size, HImode), HImode))
1370 rtx_insn *sp_plus_insns;
1374 insn = emit_move_insn (stack_pointer_rtx,
1375 plus_constant (Pmode, stack_pointer_rtx,
1377 RTX_FRAME_RELATED_P (insn) = 1;
1378 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1379 gen_rtx_SET (stack_pointer_rtx,
1380 plus_constant (Pmode,
1383 if (frame_pointer_needed)
1385 insn = emit_move_insn (fp, stack_pointer_rtx);
1386 RTX_FRAME_RELATED_P (insn) = 1;
1389 sp_plus_insns = get_insns ();
1392 /************ Use shortest method ************/
1394 emit_insn (get_sequence_length (sp_plus_insns)
1395 < get_sequence_length (fp_plus_insns)
1401 emit_insn (fp_plus_insns);
1404 cfun->machine->stack_usage += size_cfa;
1405 } /* !minimize && size != 0 */
1410 /* Output function prologue. */
1413 avr_expand_prologue (void)
1418 size = get_frame_size() + avr_outgoing_args_size();
1420 cfun->machine->stack_usage = 0;
1422 /* Prologue: naked. */
1423 if (cfun->machine->is_naked)
1428 avr_regs_to_save (&set);
1430 if (cfun->machine->is_interrupt || cfun->machine->is_signal)
1432 /* Enable interrupts. */
1433 if (cfun->machine->is_interrupt)
1434 emit_insn (gen_enable_interrupt ());
1436 /* Push zero reg. */
1437 emit_push_byte (AVR_ZERO_REGNO, true);
1440 emit_push_byte (AVR_TMP_REGNO, true);
1443 /* ??? There's no dwarf2 column reserved for SREG. */
1444 emit_push_sfr (sreg_rtx, false, false /* clr */);
1446 /* Clear zero reg. */
1447 emit_move_insn (zero_reg_rtx, const0_rtx);
1449 /* Prevent any attempt to delete the setting of ZERO_REG! */
1450 emit_use (zero_reg_rtx);
1452 /* Push and clear RAMPD/X/Y/Z if present and low-part register is used.
1453 ??? There are no dwarf2 columns reserved for RAMPD/X/Y/Z. */
1456 emit_push_sfr (rampd_rtx, false /* frame-related */, true /* clr */);
1459 && TEST_HARD_REG_BIT (set, REG_X)
1460 && TEST_HARD_REG_BIT (set, REG_X + 1))
1462 emit_push_sfr (rampx_rtx, false /* frame-related */, true /* clr */);
1466 && (frame_pointer_needed
1467 || (TEST_HARD_REG_BIT (set, REG_Y)
1468 && TEST_HARD_REG_BIT (set, REG_Y + 1))))
1470 emit_push_sfr (rampy_rtx, false /* frame-related */, true /* clr */);
1474 && TEST_HARD_REG_BIT (set, REG_Z)
1475 && TEST_HARD_REG_BIT (set, REG_Z + 1))
1477 emit_push_sfr (rampz_rtx, false /* frame-related */, AVR_HAVE_RAMPD);
1479 } /* is_interrupt is_signal */
1481 avr_prologue_setup_frame (size, set);
1483 if (flag_stack_usage_info)
1484 current_function_static_stack_size = cfun->machine->stack_usage;
1488 /* Implement `TARGET_ASM_FUNCTION_END_PROLOGUE'. */
1489 /* Output summary at end of function prologue. */
1492 avr_asm_function_end_prologue (FILE *file)
1494 if (cfun->machine->is_naked)
1496 fputs ("/* prologue: naked */\n", file);
1500 if (cfun->machine->is_interrupt)
1502 fputs ("/* prologue: Interrupt */\n", file);
1504 else if (cfun->machine->is_signal)
1506 fputs ("/* prologue: Signal */\n", file);
1509 fputs ("/* prologue: function */\n", file);
1512 if (ACCUMULATE_OUTGOING_ARGS)
1513 fprintf (file, "/* outgoing args size = %d */\n",
1514 avr_outgoing_args_size());
1516 fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n",
1518 fprintf (file, "/* stack size = %d */\n",
1519 cfun->machine->stack_usage);
1520 /* Create symbol stack offset here so all functions have it. Add 1 to stack
1521 usage for offset so that SP + .L__stack_offset = return address. */
1522 fprintf (file, ".L__stack_usage = %d\n", cfun->machine->stack_usage);
1526 /* Implement `EPILOGUE_USES'. */
1529 avr_epilogue_uses (int regno ATTRIBUTE_UNUSED)
1531 if (reload_completed
1533 && (cfun->machine->is_interrupt || cfun->machine->is_signal))
1538 /* Helper for avr_expand_epilogue. Emit a pop of a byte register. */
1541 emit_pop_byte (unsigned regno)
1545 mem = gen_rtx_PRE_INC (HImode, stack_pointer_rtx);
1546 mem = gen_frame_mem (QImode, mem);
1547 reg = gen_rtx_REG (QImode, regno);
1549 emit_insn (gen_rtx_SET (reg, mem));
1552 /* Output RTL epilogue. */
1555 avr_expand_epilogue (bool sibcall_p)
1562 bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
1564 size = get_frame_size() + avr_outgoing_args_size();
1566 /* epilogue: naked */
1567 if (cfun->machine->is_naked)
1569 gcc_assert (!sibcall_p);
1571 emit_jump_insn (gen_return ());
1575 avr_regs_to_save (&set);
1576 live_seq = sequent_regs_live ();
1578 minimize = (TARGET_CALL_PROLOGUES
1581 && !cfun->machine->is_OS_task
1582 && !cfun->machine->is_OS_main
1587 || frame_pointer_needed
1590 /* Get rid of frame. */
1592 if (!frame_pointer_needed)
1594 emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1599 emit_move_insn (frame_pointer_rtx,
1600 plus_constant (Pmode, frame_pointer_rtx, size));
1603 emit_insn (gen_epilogue_restores (gen_int_mode (live_seq, HImode)));
1609 /* Try two methods to adjust stack and select shortest. */
1613 rtx_insn *fp_plus_insns;
1614 HOST_WIDE_INT size_max;
1616 gcc_assert (frame_pointer_needed
1620 fp = my_fp = (frame_pointer_needed
1622 : gen_rtx_REG (Pmode, REG_X));
1624 if (AVR_HAVE_8BIT_SP)
1626 /* The high byte (r29) does not change:
1627 Prefer SUBI (1 cycle) over SBIW (2 cycles). */
1629 my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
1632 /* For rationale see comment in prologue generation. */
1634 size_max = (HOST_WIDE_INT) GET_MODE_MASK (GET_MODE (my_fp));
1635 if (size > size_max)
1637 size = trunc_int_for_mode (size, GET_MODE (my_fp));
1639 /********** Method 1: Adjust fp register **********/
1643 if (!frame_pointer_needed)
1644 emit_move_insn (fp, stack_pointer_rtx);
1646 emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp), my_fp, size));
1648 /* Copy to stack pointer. */
1650 if (TARGET_NO_INTERRUPTS)
1653 if (AVR_HAVE_8BIT_SP)
1656 emit_insn (gen_movhi_sp_r (stack_pointer_rtx, fp,
1657 GEN_INT (irq_state)));
1659 fp_plus_insns = get_insns ();
1662 /********** Method 2: Adjust Stack pointer **********/
1664 if (avr_sp_immediate_operand (gen_int_mode (size, HImode), HImode))
1666 rtx_insn *sp_plus_insns;
1670 emit_move_insn (stack_pointer_rtx,
1671 plus_constant (Pmode, stack_pointer_rtx, size));
1673 sp_plus_insns = get_insns ();
1676 /************ Use shortest method ************/
1678 emit_insn (get_sequence_length (sp_plus_insns)
1679 < get_sequence_length (fp_plus_insns)
1684 emit_insn (fp_plus_insns);
1687 if (frame_pointer_needed
1688 && !(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
1690 /* Restore previous frame_pointer. See avr_expand_prologue for
1691 rationale for not using pophi. */
1693 emit_pop_byte (REG_Y + 1);
1694 emit_pop_byte (REG_Y);
1697 /* Restore used registers. */
1699 for (reg = 31; reg >= 0; --reg)
1700 if (TEST_HARD_REG_BIT (set, reg))
1701 emit_pop_byte (reg);
1705 /* Restore RAMPZ/Y/X/D using tmp_reg as scratch.
1706 The conditions to restore them must be tha same as in prologue. */
1709 && TEST_HARD_REG_BIT (set, REG_Z)
1710 && TEST_HARD_REG_BIT (set, REG_Z + 1))
1712 emit_pop_byte (TMP_REGNO);
1713 emit_move_insn (rampz_rtx, tmp_reg_rtx);
1717 && (frame_pointer_needed
1718 || (TEST_HARD_REG_BIT (set, REG_Y)
1719 && TEST_HARD_REG_BIT (set, REG_Y + 1))))
1721 emit_pop_byte (TMP_REGNO);
1722 emit_move_insn (rampy_rtx, tmp_reg_rtx);
1726 && TEST_HARD_REG_BIT (set, REG_X)
1727 && TEST_HARD_REG_BIT (set, REG_X + 1))
1729 emit_pop_byte (TMP_REGNO);
1730 emit_move_insn (rampx_rtx, tmp_reg_rtx);
1735 emit_pop_byte (TMP_REGNO);
1736 emit_move_insn (rampd_rtx, tmp_reg_rtx);
1739 /* Restore SREG using tmp_reg as scratch. */
1741 emit_pop_byte (AVR_TMP_REGNO);
1742 emit_move_insn (sreg_rtx, tmp_reg_rtx);
1744 /* Restore tmp REG. */
1745 emit_pop_byte (AVR_TMP_REGNO);
1747 /* Restore zero REG. */
1748 emit_pop_byte (AVR_ZERO_REGNO);
1752 emit_jump_insn (gen_return ());
1756 /* Implement `TARGET_ASM_FUNCTION_BEGIN_EPILOGUE'. */
1759 avr_asm_function_begin_epilogue (FILE *file)
1761 fprintf (file, "/* epilogue start */\n");
1765 /* Implement `TARGET_CANNOT_MODITY_JUMPS_P'. */
1768 avr_cannot_modify_jumps_p (void)
1771 /* Naked Functions must not have any instructions after
1772 their epilogue, see PR42240 */
1774 if (reload_completed
1776 && cfun->machine->is_naked)
1785 /* Implement `TARGET_MODE_DEPENDENT_ADDRESS_P'. */
1788 avr_mode_dependent_address_p (const_rtx addr ATTRIBUTE_UNUSED, addr_space_t as)
1790 /* FIXME: Non-generic addresses are not mode-dependent in themselves.
1791 This hook just serves to hack around PR rtl-optimization/52543 by
1792 claiming that non-generic addresses were mode-dependent so that
1793 lower-subreg.c will skip these addresses. lower-subreg.c sets up fake
1794 RTXes to probe SET and MEM costs and assumes that MEM is always in the
1795 generic address space which is not true. */
1797 return !ADDR_SPACE_GENERIC_P (as);
1801 /* Helper function for `avr_legitimate_address_p'. */
1804 avr_reg_ok_for_addr_p (rtx reg, addr_space_t as,
1805 RTX_CODE outer_code, bool strict)
1808 && (avr_regno_mode_code_ok_for_base_p (REGNO (reg), QImode,
1809 as, outer_code, UNKNOWN)
1811 && REGNO (reg) >= FIRST_PSEUDO_REGISTER)));
1815 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
1816 machine for a memory operand of mode MODE. */
1819 avr_legitimate_address_p (machine_mode mode, rtx x, bool strict)
1821 bool ok = CONSTANT_ADDRESS_P (x);
1823 switch (GET_CODE (x))
1826 ok = avr_reg_ok_for_addr_p (x, ADDR_SPACE_GENERIC,
1830 && GET_MODE_SIZE (mode) > 4
1831 && REG_X == REGNO (x))
1839 ok = avr_reg_ok_for_addr_p (XEXP (x, 0), ADDR_SPACE_GENERIC,
1840 GET_CODE (x), strict);
1845 rtx reg = XEXP (x, 0);
1846 rtx op1 = XEXP (x, 1);
1849 && CONST_INT_P (op1)
1850 && INTVAL (op1) >= 0)
1852 bool fit = IN_RANGE (INTVAL (op1), 0, MAX_LD_OFFSET (mode));
1857 || avr_reg_ok_for_addr_p (reg, ADDR_SPACE_GENERIC,
1860 if (reg == frame_pointer_rtx
1861 || reg == arg_pointer_rtx)
1866 else if (frame_pointer_needed
1867 && reg == frame_pointer_rtx)
1880 && CONSTANT_ADDRESS_P (x))
1882 /* avrtiny's load / store instructions only cover addresses 0..0xbf:
1883 IN / OUT range is 0..0x3f and LDS / STS can access 0x40..0xbf. */
1885 ok = (CONST_INT_P (x)
1886 && IN_RANGE (INTVAL (x), 0, 0xc0 - GET_MODE_SIZE (mode)));
1889 if (avr_log.legitimate_address_p)
1891 avr_edump ("\n%?: ret=%d, mode=%m strict=%d "
1892 "reload_completed=%d reload_in_progress=%d %s:",
1893 ok, mode, strict, reload_completed, reload_in_progress,
1894 reg_renumber ? "(reg_renumber)" : "");
1896 if (GET_CODE (x) == PLUS
1897 && REG_P (XEXP (x, 0))
1898 && CONST_INT_P (XEXP (x, 1))
1899 && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
1902 avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
1903 true_regnum (XEXP (x, 0)));
1906 avr_edump ("\n%r\n", x);
1913 /* Former implementation of TARGET_LEGITIMIZE_ADDRESS,
1914 now only a helper for avr_addr_space_legitimize_address. */
1915 /* Attempts to replace X with a valid
1916 memory address for an operand of mode MODE */
1919 avr_legitimize_address (rtx x, rtx oldx, machine_mode mode)
1921 bool big_offset_p = false;
1925 if (GET_CODE (oldx) == PLUS
1926 && REG_P (XEXP (oldx, 0)))
1928 if (REG_P (XEXP (oldx, 1)))
1929 x = force_reg (GET_MODE (oldx), oldx);
1930 else if (CONST_INT_P (XEXP (oldx, 1)))
1932 int offs = INTVAL (XEXP (oldx, 1));
1933 if (frame_pointer_rtx != XEXP (oldx, 0)
1934 && offs > MAX_LD_OFFSET (mode))
1936 big_offset_p = true;
1937 x = force_reg (GET_MODE (oldx), oldx);
1942 if (avr_log.legitimize_address)
1944 avr_edump ("\n%?: mode=%m\n %r\n", mode, oldx);
1947 avr_edump (" %s --> %r\n", big_offset_p ? "(big offset)" : "", x);
1954 /* Implement `LEGITIMIZE_RELOAD_ADDRESS'. */
1955 /* This will allow register R26/27 to be used where it is no worse than normal
1956 base pointers R28/29 or R30/31. For example, if base offset is greater
1957 than 63 bytes or for R++ or --R addressing. */
1960 avr_legitimize_reload_address (rtx *px, machine_mode mode,
1961 int opnum, int type, int addr_type,
1962 int ind_levels ATTRIBUTE_UNUSED,
1963 rtx (*mk_memloc)(rtx,int))
1967 if (avr_log.legitimize_reload_address)
1968 avr_edump ("\n%?:%m %r\n", mode, x);
1970 if (1 && (GET_CODE (x) == POST_INC
1971 || GET_CODE (x) == PRE_DEC))
1973 push_reload (XEXP (x, 0), XEXP (x, 0), &XEXP (x, 0), &XEXP (x, 0),
1974 POINTER_REGS, GET_MODE (x), GET_MODE (x), 0, 0,
1975 opnum, RELOAD_OTHER);
1977 if (avr_log.legitimize_reload_address)
1978 avr_edump (" RCLASS.1 = %R\n IN = %r\n OUT = %r\n",
1979 POINTER_REGS, XEXP (x, 0), XEXP (x, 0));
1984 if (GET_CODE (x) == PLUS
1985 && REG_P (XEXP (x, 0))
1986 && 0 == reg_equiv_constant (REGNO (XEXP (x, 0)))
1987 && CONST_INT_P (XEXP (x, 1))
1988 && INTVAL (XEXP (x, 1)) >= 1)
1990 bool fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
1994 if (reg_equiv_address (REGNO (XEXP (x, 0))) != 0)
1996 int regno = REGNO (XEXP (x, 0));
1997 rtx mem = mk_memloc (x, regno);
1999 push_reload (XEXP (mem, 0), NULL_RTX, &XEXP (mem, 0), NULL,
2000 POINTER_REGS, Pmode, VOIDmode, 0, 0,
2001 1, (enum reload_type) addr_type);
2003 if (avr_log.legitimize_reload_address)
2004 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
2005 POINTER_REGS, XEXP (mem, 0), NULL_RTX);
2007 push_reload (mem, NULL_RTX, &XEXP (x, 0), NULL,
2008 BASE_POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
2009 opnum, (enum reload_type) type);
2011 if (avr_log.legitimize_reload_address)
2012 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
2013 BASE_POINTER_REGS, mem, NULL_RTX);
2018 else if (! (frame_pointer_needed
2019 && XEXP (x, 0) == frame_pointer_rtx))
2021 push_reload (x, NULL_RTX, px, NULL,
2022 POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
2023 opnum, (enum reload_type) type);
2025 if (avr_log.legitimize_reload_address)
2026 avr_edump (" RCLASS.3 = %R\n IN = %r\n OUT = %r\n",
2027 POINTER_REGS, x, NULL_RTX);
2037 /* Implement `TARGET_SECONDARY_RELOAD' */
2040 avr_secondary_reload (bool in_p, rtx x,
2041 reg_class_t reload_class ATTRIBUTE_UNUSED,
2042 machine_mode mode, secondary_reload_info *sri)
2046 && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x))
2047 && ADDR_SPACE_MEMX != MEM_ADDR_SPACE (x))
2049 /* For the non-generic 16-bit spaces we need a d-class scratch. */
2056 case QImode: sri->icode = CODE_FOR_reload_inqi; break;
2057 case QQmode: sri->icode = CODE_FOR_reload_inqq; break;
2058 case UQQmode: sri->icode = CODE_FOR_reload_inuqq; break;
2060 case HImode: sri->icode = CODE_FOR_reload_inhi; break;
2061 case HQmode: sri->icode = CODE_FOR_reload_inhq; break;
2062 case HAmode: sri->icode = CODE_FOR_reload_inha; break;
2063 case UHQmode: sri->icode = CODE_FOR_reload_inuhq; break;
2064 case UHAmode: sri->icode = CODE_FOR_reload_inuha; break;
2066 case PSImode: sri->icode = CODE_FOR_reload_inpsi; break;
2068 case SImode: sri->icode = CODE_FOR_reload_insi; break;
2069 case SFmode: sri->icode = CODE_FOR_reload_insf; break;
2070 case SQmode: sri->icode = CODE_FOR_reload_insq; break;
2071 case SAmode: sri->icode = CODE_FOR_reload_insa; break;
2072 case USQmode: sri->icode = CODE_FOR_reload_inusq; break;
2073 case USAmode: sri->icode = CODE_FOR_reload_inusa; break;
2081 /* Helper function to print assembler resp. track instruction
2082 sequence lengths. Always return "".
2085 Output assembler code from template TPL with operands supplied
2086 by OPERANDS. This is just forwarding to output_asm_insn.
2089 If N_WORDS >= 0 Add N_WORDS to *PLEN.
2090 If N_WORDS < 0 Set *PLEN to -N_WORDS.
2091 Don't output anything.
2095 avr_asm_len (const char* tpl, rtx* operands, int* plen, int n_words)
2099 output_asm_insn (tpl, operands);
2113 /* Return a pointer register name as a string. */
2116 ptrreg_to_str (int regno)
2120 case REG_X: return "X";
2121 case REG_Y: return "Y";
2122 case REG_Z: return "Z";
2124 output_operand_lossage ("address operand requires constraint for"
2125 " X, Y, or Z register");
2130 /* Return the condition name as a string.
2131 Used in conditional jump constructing */
2134 cond_string (enum rtx_code code)
2143 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2148 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2164 /* Implement `TARGET_PRINT_OPERAND_ADDRESS'. */
2165 /* Output ADDR to FILE as address. */
2168 avr_print_operand_address (FILE *file, machine_mode /*mode*/, rtx addr)
2170 switch (GET_CODE (addr))
2173 fprintf (file, ptrreg_to_str (REGNO (addr)));
2177 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
2181 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
2185 if (CONSTANT_ADDRESS_P (addr)
2186 && text_segment_operand (addr, VOIDmode))
2189 if (GET_CODE (x) == CONST)
2191 if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x,1)) == CONST_INT)
2193 /* Assembler gs() will implant word address. Make offset
2194 a byte offset inside gs() for assembler. This is
2195 needed because the more logical (constant+gs(sym)) is not
2196 accepted by gas. For 128K and smaller devices this is ok.
2197 For large devices it will create a trampoline to offset
2198 from symbol which may not be what the user really wanted. */
2200 fprintf (file, "gs(");
2201 output_addr_const (file, XEXP (x,0));
2202 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC ")",
2203 2 * INTVAL (XEXP (x, 1)));
2205 if (warning (0, "pointer offset from symbol maybe incorrect"))
2207 output_addr_const (stderr, addr);
2208 fprintf(stderr,"\n");
2213 fprintf (file, "gs(");
2214 output_addr_const (file, addr);
2215 fprintf (file, ")");
2219 output_addr_const (file, addr);
2224 /* Implement `TARGET_PRINT_OPERAND_PUNCT_VALID_P'. */
2227 avr_print_operand_punct_valid_p (unsigned char code)
2229 return code == '~' || code == '!';
2233 /* Implement `TARGET_PRINT_OPERAND'. */
2234 /* Output X as assembler operand to file FILE.
2235 For a description of supported %-codes, see top of avr.md. */
2238 avr_print_operand (FILE *file, rtx x, int code)
2240 int abcd = 0, ef = 0, ij = 0;
2242 if (code >= 'A' && code <= 'D')
2244 else if (code == 'E' || code == 'F')
2246 else if (code == 'I' || code == 'J')
2251 if (!AVR_HAVE_JMP_CALL)
2254 else if (code == '!')
2256 if (AVR_HAVE_EIJMP_EICALL)
2259 else if (code == 't'
2262 static int t_regno = -1;
2263 static int t_nbits = -1;
2265 if (REG_P (x) && t_regno < 0 && code == 'T')
2267 t_regno = REGNO (x);
2268 t_nbits = GET_MODE_BITSIZE (GET_MODE (x));
2270 else if (CONST_INT_P (x) && t_regno >= 0
2271 && IN_RANGE (INTVAL (x), 0, t_nbits - 1))
2273 int bpos = INTVAL (x);
2275 fprintf (file, "%s", reg_names[t_regno + bpos / 8]);
2277 fprintf (file, ",%d", bpos % 8);
2282 fatal_insn ("operands to %T/%t must be reg + const_int:", x);
2284 else if (code == 'E' || code == 'F')
2286 rtx op = XEXP(x, 0);
2287 fprintf (file, reg_names[REGNO (op) + ef]);
2289 else if (code == 'I' || code == 'J')
2291 rtx op = XEXP(XEXP(x, 0), 0);
2292 fprintf (file, reg_names[REGNO (op) + ij]);
2296 if (x == zero_reg_rtx)
2297 fprintf (file, "__zero_reg__");
2298 else if (code == 'r' && REGNO (x) < 32)
2299 fprintf (file, "%d", (int) REGNO (x));
2301 fprintf (file, reg_names[REGNO (x) + abcd]);
2303 else if (CONST_INT_P (x))
2305 HOST_WIDE_INT ival = INTVAL (x);
2308 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival + abcd);
2309 else if (low_io_address_operand (x, VOIDmode)
2310 || high_io_address_operand (x, VOIDmode))
2312 if (AVR_HAVE_RAMPZ && ival == avr_addr.rampz)
2313 fprintf (file, "__RAMPZ__");
2314 else if (AVR_HAVE_RAMPY && ival == avr_addr.rampy)
2315 fprintf (file, "__RAMPY__");
2316 else if (AVR_HAVE_RAMPX && ival == avr_addr.rampx)
2317 fprintf (file, "__RAMPX__");
2318 else if (AVR_HAVE_RAMPD && ival == avr_addr.rampd)
2319 fprintf (file, "__RAMPD__");
2320 else if ((AVR_XMEGA || AVR_TINY) && ival == avr_addr.ccp)
2321 fprintf (file, "__CCP__");
2322 else if (ival == avr_addr.sreg) fprintf (file, "__SREG__");
2323 else if (ival == avr_addr.sp_l) fprintf (file, "__SP_L__");
2324 else if (ival == avr_addr.sp_h) fprintf (file, "__SP_H__");
2327 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
2328 ival - avr_arch->sfr_offset);
2332 fatal_insn ("bad address, not an I/O address:", x);
2336 rtx addr = XEXP (x, 0);
2340 if (!CONSTANT_P (addr))
2341 fatal_insn ("bad address, not a constant:", addr);
2342 /* Assembler template with m-code is data - not progmem section */
2343 if (text_segment_operand (addr, VOIDmode))
2344 if (warning (0, "accessing data memory with"
2345 " program memory address"))
2347 output_addr_const (stderr, addr);
2348 fprintf(stderr,"\n");
2350 output_addr_const (file, addr);
2352 else if (code == 'i')
2354 avr_print_operand (file, addr, 'i');
2356 else if (code == 'o')
2358 if (GET_CODE (addr) != PLUS)
2359 fatal_insn ("bad address, not (reg+disp):", addr);
2361 avr_print_operand (file, XEXP (addr, 1), 0);
2363 else if (code == 'b')
2365 if (GET_CODE (addr) != PLUS)
2366 fatal_insn ("bad address, not (reg+disp):", addr);
2368 avr_print_operand_address (file, VOIDmode, XEXP (addr, 0));
2370 else if (code == 'p' || code == 'r')
2372 if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
2373 fatal_insn ("bad address, not post_inc or pre_dec:", addr);
2377 avr_print_operand_address (file, VOIDmode, XEXP (addr, 0));
2379 avr_print_operand (file, XEXP (addr, 0), 0); /* r26, r28, r30 */
2381 else if (GET_CODE (addr) == PLUS)
2383 avr_print_operand_address (file, VOIDmode, XEXP (addr,0));
2384 if (REGNO (XEXP (addr, 0)) == REG_X)
2385 fatal_insn ("internal compiler error. Bad address:"
2388 avr_print_operand (file, XEXP (addr,1), code);
2391 avr_print_operand_address (file, VOIDmode, addr);
2393 else if (code == 'i')
2395 if (GET_CODE (x) == SYMBOL_REF && (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_IO))
2396 avr_print_operand_address
2397 (file, VOIDmode, plus_constant (HImode, x, -avr_arch->sfr_offset));
2399 fatal_insn ("bad address, not an I/O address:", x);
2401 else if (code == 'x')
2403 /* Constant progmem address - like used in jmp or call */
2404 if (0 == text_segment_operand (x, VOIDmode))
2405 if (warning (0, "accessing program memory"
2406 " with data memory address"))
2408 output_addr_const (stderr, x);
2409 fprintf(stderr,"\n");
2411 /* Use normal symbol for direct address no linker trampoline needed */
2412 output_addr_const (file, x);
2414 else if (CONST_FIXED_P (x))
2416 HOST_WIDE_INT ival = INTVAL (avr_to_int_mode (x));
2418 output_operand_lossage ("Unsupported code '%c' for fixed-point:",
2420 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival);
2422 else if (GET_CODE (x) == CONST_DOUBLE)
2425 if (GET_MODE (x) != SFmode)
2426 fatal_insn ("internal compiler error. Unknown mode:", x);
2427 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), val);
2428 fprintf (file, "0x%lx", val);
2430 else if (GET_CODE (x) == CONST_STRING)
2431 fputs (XSTR (x, 0), file);
2432 else if (code == 'j')
2433 fputs (cond_string (GET_CODE (x)), file);
2434 else if (code == 'k')
2435 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
2437 avr_print_operand_address (file, VOIDmode, x);
2441 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
2443 /* Prefer sequence of loads/stores for moves of size upto
2444 two - two pairs of load/store instructions are always better
2445 than the 5 instruction sequence for a loop (1 instruction
2446 for loop counter setup, and 4 for the body of the loop). */
2449 avr_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
2450 unsigned int align ATTRIBUTE_UNUSED,
2451 enum by_pieces_operation op,
2455 if (op != MOVE_BY_PIECES || (speed_p && (size > (MOVE_MAX_PIECES))))
2456 return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
2458 return size <= (MOVE_MAX_PIECES);
2462 /* Worker function for `NOTICE_UPDATE_CC'. */
2463 /* Update the condition code in the INSN. */
2466 avr_notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx_insn *insn)
2469 enum attr_cc cc = get_attr_cc (insn);
2479 rtx *op = recog_data.operand;
2482 /* Extract insn's operands. */
2483 extract_constrain_insn_cached (insn);
2491 avr_out_plus (insn, op, &len_dummy, &icc);
2492 cc = (enum attr_cc) icc;
2497 cc = (op[1] == CONST0_RTX (GET_MODE (op[0]))
2498 && reg_overlap_mentioned_p (op[0], zero_reg_rtx))
2499 /* Loading zero-reg with 0 uses CLR and thus clobbers cc0. */
2501 /* Any other "r,rL" combination does not alter cc0. */
2505 } /* inner switch */
2509 } /* outer swicth */
2514 /* Special values like CC_OUT_PLUS from above have been
2515 mapped to "standard" CC_* values so we never come here. */
2521 /* Insn does not affect CC at all, but it might set some registers
2522 that are stored in cc_status. If such a register is affected by
2523 the current insn, for example by means of a SET or a CLOBBER,
2524 then we must reset cc_status; cf. PR77326.
2526 Unfortunately, set_of cannot be used as reg_overlap_mentioned_p
2527 will abort on COMPARE (which might be found in cc_status.value1/2).
2528 Thus work out the registers set by the insn and regs mentioned
2529 in cc_status.value1/2. */
2531 if (cc_status.value1
2532 || cc_status.value2)
2534 HARD_REG_SET regs_used;
2535 HARD_REG_SET regs_set;
2536 CLEAR_HARD_REG_SET (regs_used);
2538 if (cc_status.value1
2539 && !CONSTANT_P (cc_status.value1))
2541 find_all_hard_regs (cc_status.value1, ®s_used);
2544 if (cc_status.value2
2545 && !CONSTANT_P (cc_status.value2))
2547 find_all_hard_regs (cc_status.value2, ®s_used);
2550 find_all_hard_reg_sets (insn, ®s_set, false);
2552 if (hard_reg_set_intersect_p (regs_used, regs_set))
2565 set = single_set (insn);
2569 cc_status.flags |= CC_NO_OVERFLOW;
2570 cc_status.value1 = SET_DEST (set);
2575 /* Insn like INC, DEC, NEG that set Z,N,V. We currently don't make use
2576 of this combination, cf. also PR61055. */
2581 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
2582 The V flag may or may not be known but that's ok because
2583 alter_cond will change tests to use EQ/NE. */
2584 set = single_set (insn);
2588 cc_status.value1 = SET_DEST (set);
2589 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
2594 set = single_set (insn);
2597 cc_status.value1 = SET_SRC (set);
2601 /* Insn doesn't leave CC in a usable state. */
2607 /* Choose mode for jump insn:
2608 1 - relative jump in range -63 <= x <= 62 ;
2609 2 - relative jump in range -2046 <= x <= 2045 ;
2610 3 - absolute jump (only for ATmega[16]03). */
2613 avr_jump_mode (rtx x, rtx_insn *insn)
2615 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_CODE (x) == LABEL_REF
2616 ? XEXP (x, 0) : x));
2617 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
2618 int jump_distance = cur_addr - dest_addr;
2620 if (-63 <= jump_distance && jump_distance <= 62)
2622 else if (-2046 <= jump_distance && jump_distance <= 2045)
2624 else if (AVR_HAVE_JMP_CALL)
2630 /* Return an AVR condition jump commands.
2631 X is a comparison RTX.
2632 LEN is a number returned by avr_jump_mode function.
2633 If REVERSE nonzero then condition code in X must be reversed. */
2636 ret_cond_branch (rtx x, int len, int reverse)
2638 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
2643 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2644 return (len == 1 ? ("breq .+2" CR_TAB
2646 len == 2 ? ("breq .+4" CR_TAB
2654 return (len == 1 ? ("breq .+2" CR_TAB
2656 len == 2 ? ("breq .+4" CR_TAB
2663 return (len == 1 ? ("breq .+2" CR_TAB
2665 len == 2 ? ("breq .+4" CR_TAB
2672 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2673 return (len == 1 ? ("breq %0" CR_TAB
2675 len == 2 ? ("breq .+2" CR_TAB
2682 return (len == 1 ? ("breq %0" CR_TAB
2684 len == 2 ? ("breq .+2" CR_TAB
2691 return (len == 1 ? ("breq %0" CR_TAB
2693 len == 2 ? ("breq .+2" CR_TAB
2707 return ("br%j1 .+2" CR_TAB
2710 return ("br%j1 .+4" CR_TAB
2721 return ("br%k1 .+2" CR_TAB
2724 return ("br%k1 .+4" CR_TAB
2733 /* Worker function for `FINAL_PRESCAN_INSN'. */
2734 /* Output insn cost for next insn. */
2737 avr_final_prescan_insn (rtx_insn *insn, rtx *operand ATTRIBUTE_UNUSED,
2738 int num_operands ATTRIBUTE_UNUSED)
2740 if (avr_log.rtx_costs)
2742 rtx set = single_set (insn);
2745 fprintf (asm_out_file, "/* DEBUG: cost = %d. */\n",
2746 set_src_cost (SET_SRC (set), GET_MODE (SET_DEST (set)),
2747 optimize_insn_for_speed_p ()));
2749 fprintf (asm_out_file, "/* DEBUG: pattern-cost = %d. */\n",
2750 rtx_cost (PATTERN (insn), VOIDmode, INSN, 0,
2751 optimize_insn_for_speed_p()));
2755 /* Return 0 if undefined, 1 if always true or always false. */
2758 avr_simplify_comparison_p (machine_mode mode, RTX_CODE op, rtx x)
2760 unsigned int max = (mode == QImode ? 0xff :
2761 mode == HImode ? 0xffff :
2762 mode == PSImode ? 0xffffff :
2763 mode == SImode ? 0xffffffff : 0);
2764 if (max && op && CONST_INT_P (x))
2766 if (unsigned_condition (op) != op)
2769 if (max != (INTVAL (x) & max)
2770 && INTVAL (x) != 0xff)
2777 /* Worker function for `FUNCTION_ARG_REGNO_P'. */
2778 /* Returns nonzero if REGNO is the number of a hard
2779 register in which function arguments are sometimes passed. */
2782 avr_function_arg_regno_p(int r)
2784 return (AVR_TINY ? r >= 20 && r <= 25 : r >= 8 && r <= 25);
2788 /* Worker function for `INIT_CUMULATIVE_ARGS'. */
2789 /* Initializing the variable cum for the state at the beginning
2790 of the argument list. */
2793 avr_init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
2794 tree fndecl ATTRIBUTE_UNUSED)
2796 cum->nregs = AVR_TINY ? 6 : 18;
2797 cum->regno = FIRST_CUM_REG;
2798 if (!libname && stdarg_p (fntype))
2801 /* Assume the calle may be tail called */
2803 cfun->machine->sibcall_fails = 0;
2806 /* Returns the number of registers to allocate for a function argument. */
2809 avr_num_arg_regs (machine_mode mode, const_tree type)
2813 if (mode == BLKmode)
2814 size = int_size_in_bytes (type);
2816 size = GET_MODE_SIZE (mode);
2818 /* Align all function arguments to start in even-numbered registers.
2819 Odd-sized arguments leave holes above them. */
2821 return (size + 1) & ~1;
2825 /* Implement `TARGET_FUNCTION_ARG'. */
2826 /* Controls whether a function argument is passed
2827 in a register, and which register. */
2830 avr_function_arg (cumulative_args_t cum_v, machine_mode mode,
2831 const_tree type, bool named ATTRIBUTE_UNUSED)
2833 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2834 int bytes = avr_num_arg_regs (mode, type);
2836 if (cum->nregs && bytes <= cum->nregs)
2837 return gen_rtx_REG (mode, cum->regno - bytes);
2843 /* Implement `TARGET_FUNCTION_ARG_ADVANCE'. */
2844 /* Update the summarizer variable CUM to advance past an argument
2845 in the argument list. */
2848 avr_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
2849 const_tree type, bool named ATTRIBUTE_UNUSED)
2851 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2852 int bytes = avr_num_arg_regs (mode, type);
2854 cum->nregs -= bytes;
2855 cum->regno -= bytes;
2857 /* A parameter is being passed in a call-saved register. As the original
2858 contents of these regs has to be restored before leaving the function,
2859 a function must not pass arguments in call-saved regs in order to get
2864 && !call_used_regs[cum->regno])
2866 /* FIXME: We ship info on failing tail-call in struct machine_function.
2867 This uses internals of calls.c:expand_call() and the way args_so_far
2868 is used. targetm.function_ok_for_sibcall() needs to be extended to
2869 pass &args_so_far, too. At present, CUMULATIVE_ARGS is target
2870 dependent so that such an extension is not wanted. */
2872 cfun->machine->sibcall_fails = 1;
2875 /* Test if all registers needed by the ABI are actually available. If the
2876 user has fixed a GPR needed to pass an argument, an (implicit) function
2877 call will clobber that fixed register. See PR45099 for an example. */
2884 for (regno = cum->regno; regno < cum->regno + bytes; regno++)
2885 if (fixed_regs[regno])
2886 warning (0, "fixed register %s used to pass parameter to function",
2890 if (cum->nregs <= 0)
2893 cum->regno = FIRST_CUM_REG;
2897 /* Implement `TARGET_FUNCTION_OK_FOR_SIBCALL' */
2898 /* Decide whether we can make a sibling call to a function. DECL is the
2899 declaration of the function being targeted by the call and EXP is the
2900 CALL_EXPR representing the call. */
2903 avr_function_ok_for_sibcall (tree decl_callee, tree exp_callee)
2907 /* Tail-calling must fail if callee-saved regs are used to pass
2908 function args. We must not tail-call when `epilogue_restores'
2909 is used. Unfortunately, we cannot tell at this point if that
2910 actually will happen or not, and we cannot step back from
2911 tail-calling. Thus, we inhibit tail-calling with -mcall-prologues. */
2913 if (cfun->machine->sibcall_fails
2914 || TARGET_CALL_PROLOGUES)
2919 fntype_callee = TREE_TYPE (CALL_EXPR_FN (exp_callee));
2923 decl_callee = TREE_TYPE (decl_callee);
2927 decl_callee = fntype_callee;
2929 while (FUNCTION_TYPE != TREE_CODE (decl_callee)
2930 && METHOD_TYPE != TREE_CODE (decl_callee))
2932 decl_callee = TREE_TYPE (decl_callee);
2936 /* Ensure that caller and callee have compatible epilogues */
2938 if (cfun->machine->is_interrupt
2939 || cfun->machine->is_signal
2940 || cfun->machine->is_naked
2941 || avr_naked_function_p (decl_callee)
2942 /* FIXME: For OS_task and OS_main, this might be over-conservative. */
2943 || (avr_OS_task_function_p (decl_callee)
2944 != cfun->machine->is_OS_task)
2945 || (avr_OS_main_function_p (decl_callee)
2946 != cfun->machine->is_OS_main))
2954 /***********************************************************************
2955 Functions for outputting various mov's for a various modes
2956 ************************************************************************/
2958 /* Return true if a value of mode MODE is read from flash by
2959 __load_* function from libgcc. */
2962 avr_load_libgcc_p (rtx op)
2964 machine_mode mode = GET_MODE (op);
2965 int n_bytes = GET_MODE_SIZE (mode);
2969 && avr_mem_flash_p (op));
2972 /* Return true if a value of mode MODE is read by __xload_* function. */
2975 avr_xload_libgcc_p (machine_mode mode)
2977 int n_bytes = GET_MODE_SIZE (mode);
2980 || avr_n_flash > 1);
2984 /* Fixme: This is a hack because secondary reloads don't works as expected.
2986 Find an unused d-register to be used as scratch in INSN.
2987 EXCLUDE is either NULL_RTX or some register. In the case where EXCLUDE
2988 is a register, skip all possible return values that overlap EXCLUDE.
2989 The policy for the returned register is similar to that of
2990 `reg_unused_after', i.e. the returned register may overlap the SET_DEST
2993 Return a QImode d-register or NULL_RTX if nothing found. */
2996 avr_find_unused_d_reg (rtx_insn *insn, rtx exclude)
2999 bool isr_p = (avr_interrupt_function_p (current_function_decl)
3000 || avr_signal_function_p (current_function_decl));
3002 for (regno = 16; regno < 32; regno++)
3004 rtx reg = all_regs_rtx[regno];
3007 && reg_overlap_mentioned_p (exclude, reg))
3008 || fixed_regs[regno])
3013 /* Try non-live register */
3015 if (!df_regs_ever_live_p (regno)
3016 && (TREE_THIS_VOLATILE (current_function_decl)
3017 || cfun->machine->is_OS_task
3018 || cfun->machine->is_OS_main
3019 || (!isr_p && call_used_regs[regno])))
3024 /* Any live register can be used if it is unused after.
3025 Prologue/epilogue will care for it as needed. */
3027 if (df_regs_ever_live_p (regno)
3028 && reg_unused_after (insn, reg))
3038 /* Helper function for the next function in the case where only restricted
3039 version of LPM instruction is available. */
3042 avr_out_lpm_no_lpmx (rtx_insn *insn, rtx *xop, int *plen)
3046 int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
3049 regno_dest = REGNO (dest);
3051 /* The implicit target register of LPM. */
3052 xop[3] = lpm_reg_rtx;
3054 switch (GET_CODE (addr))
3061 gcc_assert (REG_Z == REGNO (addr));
3069 avr_asm_len ("%4lpm", xop, plen, 1);
3071 if (regno_dest != LPM_REGNO)
3072 avr_asm_len ("mov %0,%3", xop, plen, 1);
3077 if (REGNO (dest) == REG_Z)
3078 return avr_asm_len ("%4lpm" CR_TAB
3083 "pop %A0", xop, plen, 6);
3085 avr_asm_len ("%4lpm" CR_TAB
3089 "mov %B0,%3", xop, plen, 5);
3091 if (!reg_unused_after (insn, addr))
3092 avr_asm_len ("sbiw %2,1", xop, plen, 1);
3101 gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
3104 if (regno_dest == LPM_REGNO)
3105 avr_asm_len ("%4lpm" CR_TAB
3106 "adiw %2,1", xop, plen, 2);
3108 avr_asm_len ("%4lpm" CR_TAB
3110 "adiw %2,1", xop, plen, 3);
3113 avr_asm_len ("%4lpm" CR_TAB
3115 "adiw %2,1", xop, plen, 3);
3118 avr_asm_len ("%4lpm" CR_TAB
3120 "adiw %2,1", xop, plen, 3);
3123 avr_asm_len ("%4lpm" CR_TAB
3125 "adiw %2,1", xop, plen, 3);
3127 break; /* POST_INC */
3129 } /* switch CODE (addr) */
3135 /* If PLEN == NULL: Ouput instructions to load a value from a memory location
3136 OP[1] in AS1 to register OP[0].
3137 If PLEN != 0 set *PLEN to the length in words of the instruction sequence.
3141 avr_out_lpm (rtx_insn *insn, rtx *op, int *plen)
3145 rtx src = SET_SRC (single_set (insn));
3147 int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
3150 addr_space_t as = MEM_ADDR_SPACE (src);
3157 warning (0, "writing to address space %qs not supported",
3158 avr_addrspace[MEM_ADDR_SPACE (dest)].name);
3163 addr = XEXP (src, 0);
3164 code = GET_CODE (addr);
3166 gcc_assert (REG_P (dest));
3167 gcc_assert (REG == code || POST_INC == code);
3171 xop[2] = lpm_addr_reg_rtx;
3172 xop[4] = xstring_empty;
3173 xop[5] = tmp_reg_rtx;
3174 xop[6] = XEXP (rampz_rtx, 0);
3176 segment = avr_addrspace[as].segment;
3178 /* Set RAMPZ as needed. */
3182 xop[4] = GEN_INT (segment);
3183 xop[3] = avr_find_unused_d_reg (insn, lpm_addr_reg_rtx);
3185 if (xop[3] != NULL_RTX)
3187 avr_asm_len ("ldi %3,%4" CR_TAB
3188 "out %i6,%3", xop, plen, 2);
3190 else if (segment == 1)
3192 avr_asm_len ("clr %5" CR_TAB
3194 "out %i6,%5", xop, plen, 3);
3198 avr_asm_len ("mov %5,%2" CR_TAB
3201 "mov %2,%5", xop, plen, 4);
3206 if (!AVR_HAVE_ELPMX)
3207 return avr_out_lpm_no_lpmx (insn, xop, plen);
3209 else if (!AVR_HAVE_LPMX)
3211 return avr_out_lpm_no_lpmx (insn, xop, plen);
3214 /* We have [E]LPMX: Output reading from Flash the comfortable way. */
3216 switch (GET_CODE (addr))
3223 gcc_assert (REG_Z == REGNO (addr));
3231 return avr_asm_len ("%4lpm %0,%a2", xop, plen, 1);
3234 if (REGNO (dest) == REG_Z)
3235 return avr_asm_len ("%4lpm %5,%a2+" CR_TAB
3236 "%4lpm %B0,%a2" CR_TAB
3237 "mov %A0,%5", xop, plen, 3);
3240 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3241 "%4lpm %B0,%a2", xop, plen, 2);
3243 if (!reg_unused_after (insn, addr))
3244 avr_asm_len ("sbiw %2,1", xop, plen, 1);
3251 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3252 "%4lpm %B0,%a2+" CR_TAB
3253 "%4lpm %C0,%a2", xop, plen, 3);
3255 if (!reg_unused_after (insn, addr))
3256 avr_asm_len ("sbiw %2,2", xop, plen, 1);
3262 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3263 "%4lpm %B0,%a2+", xop, plen, 2);
3265 if (REGNO (dest) == REG_Z - 2)
3266 return avr_asm_len ("%4lpm %5,%a2+" CR_TAB
3267 "%4lpm %C0,%a2" CR_TAB
3268 "mov %D0,%5", xop, plen, 3);
3271 avr_asm_len ("%4lpm %C0,%a2+" CR_TAB
3272 "%4lpm %D0,%a2", xop, plen, 2);
3274 if (!reg_unused_after (insn, addr))
3275 avr_asm_len ("sbiw %2,3", xop, plen, 1);
3285 gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
3288 avr_asm_len ("%4lpm %A0,%a2+", xop, plen, 1);
3289 if (n_bytes >= 2) avr_asm_len ("%4lpm %B0,%a2+", xop, plen, 1);
3290 if (n_bytes >= 3) avr_asm_len ("%4lpm %C0,%a2+", xop, plen, 1);
3291 if (n_bytes >= 4) avr_asm_len ("%4lpm %D0,%a2+", xop, plen, 1);
3293 break; /* POST_INC */
3295 } /* switch CODE (addr) */
3297 if (xop[4] == xstring_e && AVR_HAVE_RAMPD)
3299 /* Reset RAMPZ to 0 so that EBI devices don't read garbage from RAM. */
3301 xop[0] = zero_reg_rtx;
3302 avr_asm_len ("out %i6,%0", xop, plen, 1);
3309 /* Worker function for xload_8 insn. */
3312 avr_out_xload (rtx_insn *insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
3318 xop[2] = lpm_addr_reg_rtx;
3319 xop[3] = AVR_HAVE_LPMX ? op[0] : lpm_reg_rtx;
3321 avr_asm_len (AVR_HAVE_LPMX ? "lpm %3,%a2" : "lpm", xop, plen, -1);
3323 avr_asm_len ("sbrc %1,7" CR_TAB
3324 "ld %3,%a2", xop, plen, 2);
3326 if (REGNO (xop[0]) != REGNO (xop[3]))
3327 avr_asm_len ("mov %0,%3", xop, plen, 1);
3334 output_movqi (rtx_insn *insn, rtx operands[], int *plen)
3336 rtx dest = operands[0];
3337 rtx src = operands[1];
3339 if (avr_mem_flash_p (src)
3340 || avr_mem_flash_p (dest))
3342 return avr_out_lpm (insn, operands, plen);
3345 gcc_assert (1 == GET_MODE_SIZE (GET_MODE (dest)));
3349 if (REG_P (src)) /* mov r,r */
3351 if (test_hard_reg_class (STACK_REG, dest))
3352 return avr_asm_len ("out %0,%1", operands, plen, -1);
3353 else if (test_hard_reg_class (STACK_REG, src))
3354 return avr_asm_len ("in %0,%1", operands, plen, -1);
3356 return avr_asm_len ("mov %0,%1", operands, plen, -1);
3358 else if (CONSTANT_P (src))
3360 output_reload_in_const (operands, NULL_RTX, plen, false);
3363 else if (MEM_P (src))
3364 return out_movqi_r_mr (insn, operands, plen); /* mov r,m */
3366 else if (MEM_P (dest))
3371 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
3373 return out_movqi_mr_r (insn, xop, plen);
3381 output_movhi (rtx_insn *insn, rtx xop[], int *plen)
3386 gcc_assert (GET_MODE_SIZE (GET_MODE (dest)) == 2);
3388 if (avr_mem_flash_p (src)
3389 || avr_mem_flash_p (dest))
3391 return avr_out_lpm (insn, xop, plen);
3394 gcc_assert (2 == GET_MODE_SIZE (GET_MODE (dest)));
3398 if (REG_P (src)) /* mov r,r */
3400 if (test_hard_reg_class (STACK_REG, dest))
3402 if (AVR_HAVE_8BIT_SP)
3403 return avr_asm_len ("out __SP_L__,%A1", xop, plen, -1);
3406 return avr_asm_len ("out __SP_L__,%A1" CR_TAB
3407 "out __SP_H__,%B1", xop, plen, -2);
3409 /* Use simple load of SP if no interrupts are used. */
3411 return TARGET_NO_INTERRUPTS
3412 ? avr_asm_len ("out __SP_H__,%B1" CR_TAB
3413 "out __SP_L__,%A1", xop, plen, -2)
3414 : avr_asm_len ("in __tmp_reg__,__SREG__" CR_TAB
3416 "out __SP_H__,%B1" CR_TAB
3417 "out __SREG__,__tmp_reg__" CR_TAB
3418 "out __SP_L__,%A1", xop, plen, -5);
3420 else if (test_hard_reg_class (STACK_REG, src))
3422 return !AVR_HAVE_SPH
3423 ? avr_asm_len ("in %A0,__SP_L__" CR_TAB
3424 "clr %B0", xop, plen, -2)
3426 : avr_asm_len ("in %A0,__SP_L__" CR_TAB
3427 "in %B0,__SP_H__", xop, plen, -2);
3430 return AVR_HAVE_MOVW
3431 ? avr_asm_len ("movw %0,%1", xop, plen, -1)
3433 : avr_asm_len ("mov %A0,%A1" CR_TAB
3434 "mov %B0,%B1", xop, plen, -2);
3436 else if (CONSTANT_P (src))
3438 return output_reload_inhi (xop, NULL, plen);
3440 else if (MEM_P (src))
3442 return out_movhi_r_mr (insn, xop, plen); /* mov r,m */
3445 else if (MEM_P (dest))
3450 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
3452 return out_movhi_mr_r (insn, xop, plen);
3455 fatal_insn ("invalid insn:", insn);
3461 /* Same as out_movqi_r_mr, but TINY does not have ADIW or SBIW */
3464 avr_out_movqi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
3468 rtx x = XEXP (src, 0);
3470 avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3471 "ld %0,%b1" , op, plen, -3);
3473 if (!reg_overlap_mentioned_p (dest, XEXP (x,0))
3474 && !reg_unused_after (insn, XEXP (x,0)))
3475 avr_asm_len (TINY_SBIW (%I1, %J1, %o1), op, plen, 2);
3481 out_movqi_r_mr (rtx_insn *insn, rtx op[], int *plen)
3485 rtx x = XEXP (src, 0);
3487 if (CONSTANT_ADDRESS_P (x))
3489 int n_words = AVR_TINY ? 1 : 2;
3490 return optimize > 0 && io_address_operand (x, QImode)
3491 ? avr_asm_len ("in %0,%i1", op, plen, -1)
3492 : avr_asm_len ("lds %0,%m1", op, plen, -n_words);
3495 if (GET_CODE (x) == PLUS
3496 && REG_P (XEXP (x, 0))
3497 && CONST_INT_P (XEXP (x, 1)))
3499 /* memory access by reg+disp */
3501 int disp = INTVAL (XEXP (x, 1));
3504 return avr_out_movqi_r_mr_reg_disp_tiny (insn, op, plen);
3506 if (disp - GET_MODE_SIZE (GET_MODE (src)) >= 63)
3508 if (REGNO (XEXP (x, 0)) != REG_Y)
3509 fatal_insn ("incorrect insn:",insn);
3511 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
3512 return avr_asm_len ("adiw r28,%o1-63" CR_TAB
3513 "ldd %0,Y+63" CR_TAB
3514 "sbiw r28,%o1-63", op, plen, -3);
3516 return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
3517 "sbci r29,hi8(-%o1)" CR_TAB
3519 "subi r28,lo8(%o1)" CR_TAB
3520 "sbci r29,hi8(%o1)", op, plen, -5);
3522 else if (REGNO (XEXP (x, 0)) == REG_X)
3524 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
3525 it but I have this situation with extremal optimizing options. */
3527 avr_asm_len ("adiw r26,%o1" CR_TAB
3528 "ld %0,X", op, plen, -2);
3530 if (!reg_overlap_mentioned_p (dest, XEXP (x,0))
3531 && !reg_unused_after (insn, XEXP (x,0)))
3533 avr_asm_len ("sbiw r26,%o1", op, plen, 1);
3539 return avr_asm_len ("ldd %0,%1", op, plen, -1);
3542 return avr_asm_len ("ld %0,%1", op, plen, -1);
3546 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
3549 avr_out_movhi_r_mr_reg_no_disp_tiny (rtx op[], int *plen)
3553 rtx base = XEXP (src, 0);
3555 int reg_dest = true_regnum (dest);
3556 int reg_base = true_regnum (base);
3558 if (reg_dest == reg_base) /* R = (R) */
3559 return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
3561 "mov %A0,__tmp_reg__", op, plen, -3);
3563 return avr_asm_len ("ld %A0,%1" CR_TAB
3564 TINY_ADIW (%E1, %F1, 1) CR_TAB
3566 TINY_SBIW (%E1, %F1, 1), op, plen, -6);
3570 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
3573 avr_out_movhi_r_mr_reg_disp_tiny (rtx op[], int *plen)
3577 rtx base = XEXP (src, 0);
3579 int reg_dest = true_regnum (dest);
3580 int reg_base = true_regnum (XEXP (base, 0));
3582 if (reg_base == reg_dest)
3584 return avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3585 "ld __tmp_reg__,%b1+" CR_TAB
3587 "mov %A0,__tmp_reg__", op, plen, -5);
3591 return avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3592 "ld %A0,%b1+" CR_TAB
3594 TINY_SBIW (%I1, %J1, %o1+1), op, plen, -6);
3599 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
3602 avr_out_movhi_r_mr_pre_dec_tiny (rtx_insn *insn, rtx op[], int *plen)
3604 int mem_volatile_p = 0;
3607 rtx base = XEXP (src, 0);
3609 /* "volatile" forces reading low byte first, even if less efficient,
3610 for correct operation with 16-bit I/O registers. */
3611 mem_volatile_p = MEM_VOLATILE_P (src);
3613 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3614 fatal_insn ("incorrect insn:", insn);
3616 if (!mem_volatile_p)
3617 return avr_asm_len ("ld %B0,%1" CR_TAB
3618 "ld %A0,%1", op, plen, -2);
3620 return avr_asm_len (TINY_SBIW (%I1, %J1, 2) CR_TAB
3621 "ld %A0,%p1+" CR_TAB
3623 TINY_SBIW (%I1, %J1, 1), op, plen, -6);
3628 out_movhi_r_mr (rtx_insn *insn, rtx op[], int *plen)
3632 rtx base = XEXP (src, 0);
3633 int reg_dest = true_regnum (dest);
3634 int reg_base = true_regnum (base);
3635 /* "volatile" forces reading low byte first, even if less efficient,
3636 for correct operation with 16-bit I/O registers. */
3637 int mem_volatile_p = MEM_VOLATILE_P (src);
3642 return avr_out_movhi_r_mr_reg_no_disp_tiny (op, plen);
3644 if (reg_dest == reg_base) /* R = (R) */
3645 return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
3647 "mov %A0,__tmp_reg__", op, plen, -3);
3649 if (reg_base != REG_X)
3650 return avr_asm_len ("ld %A0,%1" CR_TAB
3651 "ldd %B0,%1+1", op, plen, -2);
3653 avr_asm_len ("ld %A0,X+" CR_TAB
3654 "ld %B0,X", op, plen, -2);
3656 if (!reg_unused_after (insn, base))
3657 avr_asm_len ("sbiw r26,1", op, plen, 1);
3661 else if (GET_CODE (base) == PLUS) /* (R + i) */
3663 int disp = INTVAL (XEXP (base, 1));
3664 int reg_base = true_regnum (XEXP (base, 0));
3667 return avr_out_movhi_r_mr_reg_disp_tiny (op, plen);
3669 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3671 if (REGNO (XEXP (base, 0)) != REG_Y)
3672 fatal_insn ("incorrect insn:",insn);
3674 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (src))
3675 ? avr_asm_len ("adiw r28,%o1-62" CR_TAB
3676 "ldd %A0,Y+62" CR_TAB
3677 "ldd %B0,Y+63" CR_TAB
3678 "sbiw r28,%o1-62", op, plen, -4)
3680 : avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
3681 "sbci r29,hi8(-%o1)" CR_TAB
3683 "ldd %B0,Y+1" CR_TAB
3684 "subi r28,lo8(%o1)" CR_TAB
3685 "sbci r29,hi8(%o1)", op, plen, -6);
3688 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
3689 it but I have this situation with extremal
3690 optimization options. */
3692 if (reg_base == REG_X)
3693 return reg_base == reg_dest
3694 ? avr_asm_len ("adiw r26,%o1" CR_TAB
3695 "ld __tmp_reg__,X+" CR_TAB
3697 "mov %A0,__tmp_reg__", op, plen, -4)
3699 : avr_asm_len ("adiw r26,%o1" CR_TAB
3702 "sbiw r26,%o1+1", op, plen, -4);
3704 return reg_base == reg_dest
3705 ? avr_asm_len ("ldd __tmp_reg__,%A1" CR_TAB
3706 "ldd %B0,%B1" CR_TAB
3707 "mov %A0,__tmp_reg__", op, plen, -3)
3709 : avr_asm_len ("ldd %A0,%A1" CR_TAB
3710 "ldd %B0,%B1", op, plen, -2);
3712 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3715 return avr_out_movhi_r_mr_pre_dec_tiny (insn, op, plen);
3717 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3718 fatal_insn ("incorrect insn:", insn);
3720 if (!mem_volatile_p)
3721 return avr_asm_len ("ld %B0,%1" CR_TAB
3722 "ld %A0,%1", op, plen, -2);
3724 return REGNO (XEXP (base, 0)) == REG_X
3725 ? avr_asm_len ("sbiw r26,2" CR_TAB
3728 "sbiw r26,1", op, plen, -4)
3730 : avr_asm_len ("sbiw %r1,2" CR_TAB
3732 "ldd %B0,%p1+1", op, plen, -3);
3734 else if (GET_CODE (base) == POST_INC) /* (R++) */
3736 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3737 fatal_insn ("incorrect insn:", insn);
3739 return avr_asm_len ("ld %A0,%1" CR_TAB
3740 "ld %B0,%1", op, plen, -2);
3742 else if (CONSTANT_ADDRESS_P (base))
3744 int n_words = AVR_TINY ? 2 : 4;
3745 return optimize > 0 && io_address_operand (base, HImode)
3746 ? avr_asm_len ("in %A0,%i1" CR_TAB
3747 "in %B0,%i1+1", op, plen, -2)
3749 : avr_asm_len ("lds %A0,%m1" CR_TAB
3750 "lds %B0,%m1+1", op, plen, -n_words);
3753 fatal_insn ("unknown move insn:",insn);
3758 avr_out_movsi_r_mr_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *l)
3762 rtx base = XEXP (src, 0);
3763 int reg_dest = true_regnum (dest);
3764 int reg_base = true_regnum (base);
3766 if (reg_dest == reg_base)
3768 /* "ld r26,-X" is undefined */
3769 return *l = 9, (TINY_ADIW (%E1, %F1, 3) CR_TAB
3772 "ld __tmp_reg__,-%1" CR_TAB
3773 TINY_SBIW (%E1, %F1, 1) CR_TAB
3775 "mov %B0,__tmp_reg__");
3777 else if (reg_dest == reg_base - 2)
3779 return *l = 5, ("ld %A0,%1+" CR_TAB
3781 "ld __tmp_reg__,%1+" CR_TAB
3783 "mov %C0,__tmp_reg__");
3785 else if (reg_unused_after (insn, base))
3787 return *l = 4, ("ld %A0,%1+" CR_TAB
3794 return *l = 6, ("ld %A0,%1+" CR_TAB
3798 TINY_SBIW (%E1, %F1, 3));
3804 avr_out_movsi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *l)
3808 rtx base = XEXP (src, 0);
3809 int reg_dest = true_regnum (dest);
3810 int reg_base = true_regnum (XEXP (base, 0));
3812 if (reg_dest == reg_base)
3814 /* "ld r26,-X" is undefined */
3815 return *l = 9, (TINY_ADIW (%I1, %J1, %o1+3) CR_TAB
3817 "ld %C0,-%b1" CR_TAB
3818 "ld __tmp_reg__,-%b1" CR_TAB
3819 TINY_SBIW (%I1, %J1, 1) CR_TAB
3821 "mov %B0,__tmp_reg__");
3823 else if (reg_dest == reg_base - 2)
3825 return *l = 7, (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3826 "ld %A0,%b1+" CR_TAB
3827 "ld %B0,%b1+" CR_TAB
3828 "ld __tmp_reg__,%b1+" CR_TAB
3830 "mov %C0,__tmp_reg__");
3832 else if (reg_unused_after (insn, XEXP (base, 0)))
3834 return *l = 6, (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3835 "ld %A0,%b1+" CR_TAB
3836 "ld %B0,%b1+" CR_TAB
3837 "ld %C0,%b1+" CR_TAB
3842 return *l = 8, (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3843 "ld %A0,%b1+" CR_TAB
3844 "ld %B0,%b1+" CR_TAB
3845 "ld %C0,%b1+" CR_TAB
3847 TINY_SBIW (%I1, %J1, %o1+3));
3852 out_movsi_r_mr (rtx_insn *insn, rtx op[], int *l)
3856 rtx base = XEXP (src, 0);
3857 int reg_dest = true_regnum (dest);
3858 int reg_base = true_regnum (base);
3867 return avr_out_movsi_r_mr_reg_no_disp_tiny (insn, op, l);
3869 if (reg_base == REG_X) /* (R26) */
3871 if (reg_dest == REG_X)
3872 /* "ld r26,-X" is undefined */
3873 return *l=7, ("adiw r26,3" CR_TAB
3876 "ld __tmp_reg__,-X" CR_TAB
3879 "mov r27,__tmp_reg__");
3880 else if (reg_dest == REG_X - 2)
3881 return *l=5, ("ld %A0,X+" CR_TAB
3883 "ld __tmp_reg__,X+" CR_TAB
3885 "mov %C0,__tmp_reg__");
3886 else if (reg_unused_after (insn, base))
3887 return *l=4, ("ld %A0,X+" CR_TAB
3892 return *l=5, ("ld %A0,X+" CR_TAB
3900 if (reg_dest == reg_base)
3901 return *l=5, ("ldd %D0,%1+3" CR_TAB
3902 "ldd %C0,%1+2" CR_TAB
3903 "ldd __tmp_reg__,%1+1" CR_TAB
3905 "mov %B0,__tmp_reg__");
3906 else if (reg_base == reg_dest + 2)
3907 return *l=5, ("ld %A0,%1" CR_TAB
3908 "ldd %B0,%1+1" CR_TAB
3909 "ldd __tmp_reg__,%1+2" CR_TAB
3910 "ldd %D0,%1+3" CR_TAB
3911 "mov %C0,__tmp_reg__");
3913 return *l=4, ("ld %A0,%1" CR_TAB
3914 "ldd %B0,%1+1" CR_TAB
3915 "ldd %C0,%1+2" CR_TAB
3919 else if (GET_CODE (base) == PLUS) /* (R + i) */
3921 int disp = INTVAL (XEXP (base, 1));
3924 return avr_out_movsi_r_mr_reg_disp_tiny (insn, op, l);
3926 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3928 if (REGNO (XEXP (base, 0)) != REG_Y)
3929 fatal_insn ("incorrect insn:",insn);
3931 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
3932 return *l = 6, ("adiw r28,%o1-60" CR_TAB
3933 "ldd %A0,Y+60" CR_TAB
3934 "ldd %B0,Y+61" CR_TAB
3935 "ldd %C0,Y+62" CR_TAB
3936 "ldd %D0,Y+63" CR_TAB
3939 return *l = 8, ("subi r28,lo8(-%o1)" CR_TAB
3940 "sbci r29,hi8(-%o1)" CR_TAB
3942 "ldd %B0,Y+1" CR_TAB
3943 "ldd %C0,Y+2" CR_TAB
3944 "ldd %D0,Y+3" CR_TAB
3945 "subi r28,lo8(%o1)" CR_TAB
3946 "sbci r29,hi8(%o1)");
3949 reg_base = true_regnum (XEXP (base, 0));
3950 if (reg_base == REG_X)
3953 if (reg_dest == REG_X)
3956 /* "ld r26,-X" is undefined */
3957 return ("adiw r26,%o1+3" CR_TAB
3960 "ld __tmp_reg__,-X" CR_TAB
3963 "mov r27,__tmp_reg__");
3966 if (reg_dest == REG_X - 2)
3967 return ("adiw r26,%o1" CR_TAB
3970 "ld __tmp_reg__,X+" CR_TAB
3972 "mov r26,__tmp_reg__");
3974 return ("adiw r26,%o1" CR_TAB
3981 if (reg_dest == reg_base)
3982 return *l=5, ("ldd %D0,%D1" CR_TAB
3983 "ldd %C0,%C1" CR_TAB
3984 "ldd __tmp_reg__,%B1" CR_TAB
3985 "ldd %A0,%A1" CR_TAB
3986 "mov %B0,__tmp_reg__");
3987 else if (reg_dest == reg_base - 2)
3988 return *l=5, ("ldd %A0,%A1" CR_TAB
3989 "ldd %B0,%B1" CR_TAB
3990 "ldd __tmp_reg__,%C1" CR_TAB
3991 "ldd %D0,%D1" CR_TAB
3992 "mov %C0,__tmp_reg__");
3993 return *l=4, ("ldd %A0,%A1" CR_TAB
3994 "ldd %B0,%B1" CR_TAB
3995 "ldd %C0,%C1" CR_TAB
3998 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3999 return *l=4, ("ld %D0,%1" CR_TAB
4003 else if (GET_CODE (base) == POST_INC) /* (R++) */
4004 return *l=4, ("ld %A0,%1" CR_TAB
4008 else if (CONSTANT_ADDRESS_P (base))
4010 if (io_address_operand (base, SImode))
4013 return ("in %A0,%i1" CR_TAB
4014 "in %B0,%i1+1" CR_TAB
4015 "in %C0,%i1+2" CR_TAB
4020 *l = AVR_TINY ? 4 : 8;
4021 return ("lds %A0,%m1" CR_TAB
4022 "lds %B0,%m1+1" CR_TAB
4023 "lds %C0,%m1+2" CR_TAB
4028 fatal_insn ("unknown move insn:",insn);
4033 avr_out_movsi_mr_r_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *l)
4037 rtx base = XEXP (dest, 0);
4038 int reg_base = true_regnum (base);
4039 int reg_src = true_regnum (src);
4041 if (reg_base == reg_src)
4043 /* "ld r26,-X" is undefined */
4044 if (reg_unused_after (insn, base))
4046 return *l = 7, ("mov __tmp_reg__, %B1" CR_TAB
4048 TINY_ADIW (%E0, %F0, 1) CR_TAB
4049 "st %0+,__tmp_reg__" CR_TAB
4055 return *l = 9, ("mov __tmp_reg__, %B1" CR_TAB
4057 TINY_ADIW (%E0, %F0, 1) CR_TAB
4058 "st %0+,__tmp_reg__" CR_TAB
4061 TINY_SBIW (%E0, %F0, 3));
4064 else if (reg_base == reg_src + 2)
4066 if (reg_unused_after (insn, base))
4067 return *l = 7, ("mov __zero_reg__,%C1" CR_TAB
4068 "mov __tmp_reg__,%D1" CR_TAB
4071 "st %0+,__zero_reg__" CR_TAB
4072 "st %0,__tmp_reg__" CR_TAB
4073 "clr __zero_reg__");
4075 return *l = 9, ("mov __zero_reg__,%C1" CR_TAB
4076 "mov __tmp_reg__,%D1" CR_TAB
4079 "st %0+,__zero_reg__" CR_TAB
4080 "st %0,__tmp_reg__" CR_TAB
4081 "clr __zero_reg__" CR_TAB
4082 TINY_SBIW (%E0, %F0, 3));
4085 return *l = 6, ("st %0+,%A1" CR_TAB
4089 TINY_SBIW (%E0, %F0, 3));
4093 avr_out_movsi_mr_r_reg_disp_tiny (rtx op[], int *l)
4097 rtx base = XEXP (dest, 0);
4098 int reg_base = REGNO (XEXP (base, 0));
4099 int reg_src =true_regnum (src);
4101 if (reg_base == reg_src)
4104 return ("mov __tmp_reg__,%A2" CR_TAB
4105 "mov __zero_reg__,%B2" CR_TAB
4106 TINY_ADIW (%I0, %J0, %o0) CR_TAB
4107 "st %b0+,__tmp_reg__" CR_TAB
4108 "st %b0+,__zero_reg__" CR_TAB
4109 "st %b0+,%C2" CR_TAB
4111 "clr __zero_reg__" CR_TAB
4112 TINY_SBIW (%I0, %J0, %o0+3));
4114 else if (reg_src == reg_base - 2)
4117 return ("mov __tmp_reg__,%C2" CR_TAB
4118 "mov __zero_reg__,%D2" CR_TAB
4119 TINY_ADIW (%I0, %J0, %o0) CR_TAB
4120 "st %b0+,%A0" CR_TAB
4121 "st %b0+,%B0" CR_TAB
4122 "st %b0+,__tmp_reg__" CR_TAB
4123 "st %b0,__zero_reg__" CR_TAB
4124 "clr __zero_reg__" CR_TAB
4125 TINY_SBIW (%I0, %J0, %o0+3));
4128 return (TINY_ADIW (%I0, %J0, %o0) CR_TAB
4129 "st %b0+,%A1" CR_TAB
4130 "st %b0+,%B1" CR_TAB
4131 "st %b0+,%C1" CR_TAB
4133 TINY_SBIW (%I0, %J0, %o0+3));
4137 out_movsi_mr_r (rtx_insn *insn, rtx op[], int *l)
4141 rtx base = XEXP (dest, 0);
4142 int reg_base = true_regnum (base);
4143 int reg_src = true_regnum (src);
4149 if (CONSTANT_ADDRESS_P (base))
4151 if (io_address_operand (base, SImode))
4153 return *l=4,("out %i0, %A1" CR_TAB
4154 "out %i0+1,%B1" CR_TAB
4155 "out %i0+2,%C1" CR_TAB
4160 *l = AVR_TINY ? 4 : 8;
4161 return ("sts %m0,%A1" CR_TAB
4162 "sts %m0+1,%B1" CR_TAB
4163 "sts %m0+2,%C1" CR_TAB
4168 if (reg_base > 0) /* (r) */
4171 return avr_out_movsi_mr_r_reg_no_disp_tiny (insn, op, l);
4173 if (reg_base == REG_X) /* (R26) */
4175 if (reg_src == REG_X)
4177 /* "st X+,r26" is undefined */
4178 if (reg_unused_after (insn, base))
4179 return *l=6, ("mov __tmp_reg__,r27" CR_TAB
4182 "st X+,__tmp_reg__" CR_TAB
4186 return *l=7, ("mov __tmp_reg__,r27" CR_TAB
4189 "st X+,__tmp_reg__" CR_TAB
4194 else if (reg_base == reg_src + 2)
4196 if (reg_unused_after (insn, base))
4197 return *l=7, ("mov __zero_reg__,%C1" CR_TAB
4198 "mov __tmp_reg__,%D1" CR_TAB
4201 "st %0+,__zero_reg__" CR_TAB
4202 "st %0,__tmp_reg__" CR_TAB
4203 "clr __zero_reg__");
4205 return *l=8, ("mov __zero_reg__,%C1" CR_TAB
4206 "mov __tmp_reg__,%D1" CR_TAB
4209 "st %0+,__zero_reg__" CR_TAB
4210 "st %0,__tmp_reg__" CR_TAB
4211 "clr __zero_reg__" CR_TAB
4214 return *l=5, ("st %0+,%A1" CR_TAB
4221 return *l=4, ("st %0,%A1" CR_TAB
4222 "std %0+1,%B1" CR_TAB
4223 "std %0+2,%C1" CR_TAB
4226 else if (GET_CODE (base) == PLUS) /* (R + i) */
4228 int disp = INTVAL (XEXP (base, 1));
4231 return avr_out_movsi_mr_r_reg_disp_tiny (op, l);
4233 reg_base = REGNO (XEXP (base, 0));
4234 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
4236 if (reg_base != REG_Y)
4237 fatal_insn ("incorrect insn:",insn);
4239 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
4240 return *l = 6, ("adiw r28,%o0-60" CR_TAB
4241 "std Y+60,%A1" CR_TAB
4242 "std Y+61,%B1" CR_TAB
4243 "std Y+62,%C1" CR_TAB
4244 "std Y+63,%D1" CR_TAB
4247 return *l = 8, ("subi r28,lo8(-%o0)" CR_TAB
4248 "sbci r29,hi8(-%o0)" CR_TAB
4250 "std Y+1,%B1" CR_TAB
4251 "std Y+2,%C1" CR_TAB
4252 "std Y+3,%D1" CR_TAB
4253 "subi r28,lo8(%o0)" CR_TAB
4254 "sbci r29,hi8(%o0)");
4256 if (reg_base == REG_X)
4259 if (reg_src == REG_X)
4262 return ("mov __tmp_reg__,r26" CR_TAB
4263 "mov __zero_reg__,r27" CR_TAB
4264 "adiw r26,%o0" CR_TAB
4265 "st X+,__tmp_reg__" CR_TAB
4266 "st X+,__zero_reg__" CR_TAB
4269 "clr __zero_reg__" CR_TAB
4272 else if (reg_src == REG_X - 2)
4275 return ("mov __tmp_reg__,r26" CR_TAB
4276 "mov __zero_reg__,r27" CR_TAB
4277 "adiw r26,%o0" CR_TAB
4280 "st X+,__tmp_reg__" CR_TAB
4281 "st X,__zero_reg__" CR_TAB
4282 "clr __zero_reg__" CR_TAB
4286 return ("adiw r26,%o0" CR_TAB
4293 return *l=4, ("std %A0,%A1" CR_TAB
4294 "std %B0,%B1" CR_TAB
4295 "std %C0,%C1" CR_TAB
4298 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4299 return *l=4, ("st %0,%D1" CR_TAB
4303 else if (GET_CODE (base) == POST_INC) /* (R++) */
4304 return *l=4, ("st %0,%A1" CR_TAB
4308 fatal_insn ("unknown move insn:",insn);
4313 output_movsisf (rtx_insn *insn, rtx operands[], int *l)
4316 rtx dest = operands[0];
4317 rtx src = operands[1];
4320 if (avr_mem_flash_p (src)
4321 || avr_mem_flash_p (dest))
4323 return avr_out_lpm (insn, operands, real_l);
4329 gcc_assert (4 == GET_MODE_SIZE (GET_MODE (dest)));
4332 if (REG_P (src)) /* mov r,r */
4334 if (true_regnum (dest) > true_regnum (src))
4339 return ("movw %C0,%C1" CR_TAB
4343 return ("mov %D0,%D1" CR_TAB
4344 "mov %C0,%C1" CR_TAB
4345 "mov %B0,%B1" CR_TAB
4353 return ("movw %A0,%A1" CR_TAB
4357 return ("mov %A0,%A1" CR_TAB
4358 "mov %B0,%B1" CR_TAB
4359 "mov %C0,%C1" CR_TAB
4363 else if (CONSTANT_P (src))
4365 return output_reload_insisf (operands, NULL_RTX, real_l);
4367 else if (MEM_P (src))
4368 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
4370 else if (MEM_P (dest))
4374 if (src == CONST0_RTX (GET_MODE (dest)))
4375 operands[1] = zero_reg_rtx;
4377 templ = out_movsi_mr_r (insn, operands, real_l);
4380 output_asm_insn (templ, operands);
4385 fatal_insn ("invalid insn:", insn);
4390 /* Handle loads of 24-bit types from memory to register. */
4393 avr_out_load_psi_reg_no_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
4397 rtx base = XEXP (src, 0);
4398 int reg_dest = true_regnum (dest);
4399 int reg_base = true_regnum (base);
4401 if (reg_base == reg_dest)
4403 return avr_asm_len (TINY_ADIW (%E1, %F1, 2) CR_TAB
4405 "ld __tmp_reg__,-%1" CR_TAB
4406 TINY_SBIW (%E1, %F1, 1) CR_TAB
4408 "mov %B0,__tmp_reg__", op, plen, -8);
4412 avr_asm_len ("ld %A0,%1+" CR_TAB
4414 "ld %C0,%1", op, plen, -3);
4416 if (reg_dest != reg_base - 2 &&
4417 !reg_unused_after (insn, base))
4419 avr_asm_len (TINY_SBIW (%E1, %F1, 2), op, plen, 2);
4426 avr_out_load_psi_reg_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
4430 rtx base = XEXP (src, 0);
4431 int reg_dest = true_regnum (dest);
4432 int reg_base = true_regnum (base);
4434 reg_base = true_regnum (XEXP (base, 0));
4435 if (reg_base == reg_dest)
4437 return avr_asm_len (TINY_ADIW (%I1, %J1, %o1+2) CR_TAB
4439 "ld __tmp_reg__,-%b1" CR_TAB
4440 TINY_SBIW (%I1, %J1, 1) CR_TAB
4442 "mov %B0,__tmp_reg__", op, plen, -8);
4446 avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
4447 "ld %A0,%b1+" CR_TAB
4448 "ld %B0,%b1+" CR_TAB
4449 "ld %C0,%b1", op, plen, -5);
4451 if (reg_dest != (reg_base - 2)
4452 && !reg_unused_after (insn, XEXP (base, 0)))
4453 avr_asm_len (TINY_SBIW (%I1, %J1, %o1+2), op, plen, 2);
4460 avr_out_load_psi (rtx_insn *insn, rtx *op, int *plen)
4464 rtx base = XEXP (src, 0);
4465 int reg_dest = true_regnum (dest);
4466 int reg_base = true_regnum (base);
4471 return avr_out_load_psi_reg_no_disp_tiny (insn, op, plen);
4473 if (reg_base == REG_X) /* (R26) */
4475 if (reg_dest == REG_X)
4476 /* "ld r26,-X" is undefined */
4477 return avr_asm_len ("adiw r26,2" CR_TAB
4479 "ld __tmp_reg__,-X" CR_TAB
4482 "mov r27,__tmp_reg__", op, plen, -6);
4485 avr_asm_len ("ld %A0,X+" CR_TAB
4487 "ld %C0,X", op, plen, -3);
4489 if (reg_dest != REG_X - 2
4490 && !reg_unused_after (insn, base))
4492 avr_asm_len ("sbiw r26,2", op, plen, 1);
4498 else /* reg_base != REG_X */
4500 if (reg_dest == reg_base)
4501 return avr_asm_len ("ldd %C0,%1+2" CR_TAB
4502 "ldd __tmp_reg__,%1+1" CR_TAB
4504 "mov %B0,__tmp_reg__", op, plen, -4);
4506 return avr_asm_len ("ld %A0,%1" CR_TAB
4507 "ldd %B0,%1+1" CR_TAB
4508 "ldd %C0,%1+2", op, plen, -3);
4511 else if (GET_CODE (base) == PLUS) /* (R + i) */
4513 int disp = INTVAL (XEXP (base, 1));
4516 return avr_out_load_psi_reg_disp_tiny (insn, op, plen);
4518 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
4520 if (REGNO (XEXP (base, 0)) != REG_Y)
4521 fatal_insn ("incorrect insn:",insn);
4523 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
4524 return avr_asm_len ("adiw r28,%o1-61" CR_TAB
4525 "ldd %A0,Y+61" CR_TAB
4526 "ldd %B0,Y+62" CR_TAB
4527 "ldd %C0,Y+63" CR_TAB
4528 "sbiw r28,%o1-61", op, plen, -5);
4530 return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
4531 "sbci r29,hi8(-%o1)" CR_TAB
4533 "ldd %B0,Y+1" CR_TAB
4534 "ldd %C0,Y+2" CR_TAB
4535 "subi r28,lo8(%o1)" CR_TAB
4536 "sbci r29,hi8(%o1)", op, plen, -7);
4539 reg_base = true_regnum (XEXP (base, 0));
4540 if (reg_base == REG_X)
4543 if (reg_dest == REG_X)
4545 /* "ld r26,-X" is undefined */
4546 return avr_asm_len ("adiw r26,%o1+2" CR_TAB
4548 "ld __tmp_reg__,-X" CR_TAB
4551 "mov r27,__tmp_reg__", op, plen, -6);
4554 avr_asm_len ("adiw r26,%o1" CR_TAB
4557 "ld %C0,X", op, plen, -4);
4559 if (reg_dest != REG_W
4560 && !reg_unused_after (insn, XEXP (base, 0)))
4561 avr_asm_len ("sbiw r26,%o1+2", op, plen, 1);
4566 if (reg_dest == reg_base)
4567 return avr_asm_len ("ldd %C0,%C1" CR_TAB
4568 "ldd __tmp_reg__,%B1" CR_TAB
4569 "ldd %A0,%A1" CR_TAB
4570 "mov %B0,__tmp_reg__", op, plen, -4);
4572 return avr_asm_len ("ldd %A0,%A1" CR_TAB
4573 "ldd %B0,%B1" CR_TAB
4574 "ldd %C0,%C1", op, plen, -3);
4576 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4577 return avr_asm_len ("ld %C0,%1" CR_TAB
4579 "ld %A0,%1", op, plen, -3);
4580 else if (GET_CODE (base) == POST_INC) /* (R++) */
4581 return avr_asm_len ("ld %A0,%1" CR_TAB
4583 "ld %C0,%1", op, plen, -3);
4585 else if (CONSTANT_ADDRESS_P (base))
4587 int n_words = AVR_TINY ? 3 : 6;
4588 return avr_asm_len ("lds %A0,%m1" CR_TAB
4589 "lds %B0,%m1+1" CR_TAB
4590 "lds %C0,%m1+2", op, plen , -n_words);
4593 fatal_insn ("unknown move insn:",insn);
4599 avr_out_store_psi_reg_no_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
4603 rtx base = XEXP (dest, 0);
4604 int reg_base = true_regnum (base);
4605 int reg_src = true_regnum (src);
4607 if (reg_base == reg_src)
4609 avr_asm_len ("st %0,%A1" CR_TAB
4610 "mov __tmp_reg__,%B1" CR_TAB
4611 TINY_ADIW (%E0, %F0, 1) CR_TAB /* st X+, r27 is undefined */
4612 "st %0+,__tmp_reg__" CR_TAB
4613 "st %0,%C1", op, plen, -6);
4616 else if (reg_src == reg_base - 2)
4618 avr_asm_len ("st %0,%A1" CR_TAB
4619 "mov __tmp_reg__,%C1" CR_TAB
4620 TINY_ADIW (%E0, %F0, 1) CR_TAB
4622 "st %0,__tmp_reg__", op, plen, 6);
4626 avr_asm_len ("st %0+,%A1" CR_TAB
4628 "st %0,%C1", op, plen, -3);
4631 if (!reg_unused_after (insn, base))
4632 avr_asm_len (TINY_SBIW (%E0, %F0, 2), op, plen, 2);
4638 avr_out_store_psi_reg_disp_tiny (rtx *op, int *plen)
4642 rtx base = XEXP (dest, 0);
4643 int reg_base = REGNO (XEXP (base, 0));
4644 int reg_src = true_regnum (src);
4646 if (reg_src == reg_base)
4648 return avr_asm_len ("mov __tmp_reg__,%A1" CR_TAB
4649 "mov __zero_reg__,%B1" CR_TAB
4650 TINY_ADIW (%I0, %J0, %o0) CR_TAB
4651 "st %b0+,__tmp_reg__" CR_TAB
4652 "st %b0+,__zero_reg__" CR_TAB
4654 "clr __zero_reg__" CR_TAB
4655 TINY_SBIW (%I0, %J0, %o0+2), op, plen, -10);
4657 else if (reg_src == reg_base - 2)
4659 return avr_asm_len ("mov __tmp_reg__,%C1" CR_TAB
4660 TINY_ADIW (%I0, %J0, %o0) CR_TAB
4661 "st %b0+,%A1" CR_TAB
4662 "st %b0+,%B1" CR_TAB
4663 "st %b0,__tmp_reg__" CR_TAB
4664 TINY_SBIW (%I0, %J0, %o0+2), op, plen, -8);
4667 return avr_asm_len (TINY_ADIW (%I0, %J0, %o0) CR_TAB
4668 "st %b0+,%A1" CR_TAB
4669 "st %b0+,%B1" CR_TAB
4671 TINY_SBIW (%I0, %J0, %o0+2), op, plen, -7);
4674 /* Handle store of 24-bit type from register or zero to memory. */
4677 avr_out_store_psi (rtx_insn *insn, rtx *op, int *plen)
4681 rtx base = XEXP (dest, 0);
4682 int reg_base = true_regnum (base);
4684 if (CONSTANT_ADDRESS_P (base))
4686 int n_words = AVR_TINY ? 3 : 6;
4687 return avr_asm_len ("sts %m0,%A1" CR_TAB
4688 "sts %m0+1,%B1" CR_TAB
4689 "sts %m0+2,%C1", op, plen, -n_words);
4692 if (reg_base > 0) /* (r) */
4695 return avr_out_store_psi_reg_no_disp_tiny (insn, op, plen);
4697 if (reg_base == REG_X) /* (R26) */
4699 gcc_assert (!reg_overlap_mentioned_p (base, src));
4701 avr_asm_len ("st %0+,%A1" CR_TAB
4703 "st %0,%C1", op, plen, -3);
4705 if (!reg_unused_after (insn, base))
4706 avr_asm_len ("sbiw r26,2", op, plen, 1);
4711 return avr_asm_len ("st %0,%A1" CR_TAB
4712 "std %0+1,%B1" CR_TAB
4713 "std %0+2,%C1", op, plen, -3);
4715 else if (GET_CODE (base) == PLUS) /* (R + i) */
4717 int disp = INTVAL (XEXP (base, 1));
4720 return avr_out_store_psi_reg_disp_tiny (op, plen);
4722 reg_base = REGNO (XEXP (base, 0));
4724 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
4726 if (reg_base != REG_Y)
4727 fatal_insn ("incorrect insn:",insn);
4729 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
4730 return avr_asm_len ("adiw r28,%o0-61" CR_TAB
4731 "std Y+61,%A1" CR_TAB
4732 "std Y+62,%B1" CR_TAB
4733 "std Y+63,%C1" CR_TAB
4734 "sbiw r28,%o0-61", op, plen, -5);
4736 return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
4737 "sbci r29,hi8(-%o0)" CR_TAB
4739 "std Y+1,%B1" CR_TAB
4740 "std Y+2,%C1" CR_TAB
4741 "subi r28,lo8(%o0)" CR_TAB
4742 "sbci r29,hi8(%o0)", op, plen, -7);
4744 if (reg_base == REG_X)
4747 gcc_assert (!reg_overlap_mentioned_p (XEXP (base, 0), src));
4749 avr_asm_len ("adiw r26,%o0" CR_TAB
4752 "st X,%C1", op, plen, -4);
4754 if (!reg_unused_after (insn, XEXP (base, 0)))
4755 avr_asm_len ("sbiw r26,%o0+2", op, plen, 1);
4760 return avr_asm_len ("std %A0,%A1" CR_TAB
4761 "std %B0,%B1" CR_TAB
4762 "std %C0,%C1", op, plen, -3);
4764 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4765 return avr_asm_len ("st %0,%C1" CR_TAB
4767 "st %0,%A1", op, plen, -3);
4768 else if (GET_CODE (base) == POST_INC) /* (R++) */
4769 return avr_asm_len ("st %0,%A1" CR_TAB
4771 "st %0,%C1", op, plen, -3);
4773 fatal_insn ("unknown move insn:",insn);
4778 /* Move around 24-bit stuff. */
4781 avr_out_movpsi (rtx_insn *insn, rtx *op, int *plen)
4786 if (avr_mem_flash_p (src)
4787 || avr_mem_flash_p (dest))
4789 return avr_out_lpm (insn, op, plen);
4792 if (register_operand (dest, VOIDmode))
4794 if (register_operand (src, VOIDmode)) /* mov r,r */
4796 if (true_regnum (dest) > true_regnum (src))
4798 avr_asm_len ("mov %C0,%C1", op, plen, -1);
4801 return avr_asm_len ("movw %A0,%A1", op, plen, 1);
4803 return avr_asm_len ("mov %B0,%B1" CR_TAB
4804 "mov %A0,%A1", op, plen, 2);
4809 avr_asm_len ("movw %A0,%A1", op, plen, -1);
4811 avr_asm_len ("mov %A0,%A1" CR_TAB
4812 "mov %B0,%B1", op, plen, -2);
4814 return avr_asm_len ("mov %C0,%C1", op, plen, 1);
4817 else if (CONSTANT_P (src))
4819 return avr_out_reload_inpsi (op, NULL_RTX, plen);
4821 else if (MEM_P (src))
4822 return avr_out_load_psi (insn, op, plen); /* mov r,m */
4824 else if (MEM_P (dest))
4829 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
4831 return avr_out_store_psi (insn, xop, plen);
4834 fatal_insn ("invalid insn:", insn);
4839 avr_out_movqi_mr_r_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
4843 rtx x = XEXP (dest, 0);
4845 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
4847 avr_asm_len ("mov __tmp_reg__,%1" CR_TAB
4848 TINY_ADIW (%I0, %J0, %o0) CR_TAB
4849 "st %b0,__tmp_reg__", op, plen, -4);
4853 avr_asm_len (TINY_ADIW (%I0, %J0, %o0) CR_TAB
4854 "st %b0,%1" , op, plen, -3);
4857 if (!reg_unused_after (insn, XEXP (x,0)))
4858 avr_asm_len (TINY_SBIW (%I0, %J0, %o0), op, plen, 2);
4864 out_movqi_mr_r (rtx_insn *insn, rtx op[], int *plen)
4868 rtx x = XEXP (dest, 0);
4870 if (CONSTANT_ADDRESS_P (x))
4872 int n_words = AVR_TINY ? 1 : 2;
4873 return optimize > 0 && io_address_operand (x, QImode)
4874 ? avr_asm_len ("out %i0,%1", op, plen, -1)
4875 : avr_asm_len ("sts %m0,%1", op, plen, -n_words);
4877 else if (GET_CODE (x) == PLUS
4878 && REG_P (XEXP (x, 0))
4879 && CONST_INT_P (XEXP (x, 1)))
4881 /* memory access by reg+disp */
4883 int disp = INTVAL (XEXP (x, 1));
4886 return avr_out_movqi_mr_r_reg_disp_tiny (insn, op, plen);
4888 if (disp - GET_MODE_SIZE (GET_MODE (dest)) >= 63)
4890 if (REGNO (XEXP (x, 0)) != REG_Y)
4891 fatal_insn ("incorrect insn:",insn);
4893 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
4894 return avr_asm_len ("adiw r28,%o0-63" CR_TAB
4895 "std Y+63,%1" CR_TAB
4896 "sbiw r28,%o0-63", op, plen, -3);
4898 return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
4899 "sbci r29,hi8(-%o0)" CR_TAB
4901 "subi r28,lo8(%o0)" CR_TAB
4902 "sbci r29,hi8(%o0)", op, plen, -5);
4904 else if (REGNO (XEXP (x,0)) == REG_X)
4906 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
4908 avr_asm_len ("mov __tmp_reg__,%1" CR_TAB
4909 "adiw r26,%o0" CR_TAB
4910 "st X,__tmp_reg__", op, plen, -3);
4914 avr_asm_len ("adiw r26,%o0" CR_TAB
4915 "st X,%1", op, plen, -2);
4918 if (!reg_unused_after (insn, XEXP (x,0)))
4919 avr_asm_len ("sbiw r26,%o0", op, plen, 1);
4924 return avr_asm_len ("std %0,%1", op, plen, -1);
4927 return avr_asm_len ("st %0,%1", op, plen, -1);
4931 /* Helper for the next function for XMEGA. It does the same
4932 but with low byte first. */
4935 avr_out_movhi_mr_r_xmega (rtx_insn *insn, rtx op[], int *plen)
4939 rtx base = XEXP (dest, 0);
4940 int reg_base = true_regnum (base);
4941 int reg_src = true_regnum (src);
4943 /* "volatile" forces writing low byte first, even if less efficient,
4944 for correct operation with 16-bit I/O registers like SP. */
4945 int mem_volatile_p = MEM_VOLATILE_P (dest);
4947 if (CONSTANT_ADDRESS_P (base))
4949 int n_words = AVR_TINY ? 2 : 4;
4950 return optimize > 0 && io_address_operand (base, HImode)
4951 ? avr_asm_len ("out %i0,%A1" CR_TAB
4952 "out %i0+1,%B1", op, plen, -2)
4954 : avr_asm_len ("sts %m0,%A1" CR_TAB
4955 "sts %m0+1,%B1", op, plen, -n_words);
4960 if (reg_base != REG_X)
4961 return avr_asm_len ("st %0,%A1" CR_TAB
4962 "std %0+1,%B1", op, plen, -2);
4964 if (reg_src == REG_X)
4965 /* "st X+,r26" and "st -X,r26" are undefined. */
4966 avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
4969 "st X,__tmp_reg__", op, plen, -4);
4971 avr_asm_len ("st X+,%A1" CR_TAB
4972 "st X,%B1", op, plen, -2);
4974 return reg_unused_after (insn, base)
4976 : avr_asm_len ("sbiw r26,1", op, plen, 1);
4978 else if (GET_CODE (base) == PLUS)
4980 int disp = INTVAL (XEXP (base, 1));
4981 reg_base = REGNO (XEXP (base, 0));
4982 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
4984 if (reg_base != REG_Y)
4985 fatal_insn ("incorrect insn:",insn);
4987 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))
4988 ? avr_asm_len ("adiw r28,%o0-62" CR_TAB
4989 "std Y+62,%A1" CR_TAB
4990 "std Y+63,%B1" CR_TAB
4991 "sbiw r28,%o0-62", op, plen, -4)
4993 : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
4994 "sbci r29,hi8(-%o0)" CR_TAB
4996 "std Y+1,%B1" CR_TAB
4997 "subi r28,lo8(%o0)" CR_TAB
4998 "sbci r29,hi8(%o0)", op, plen, -6);
5001 if (reg_base != REG_X)
5002 return avr_asm_len ("std %A0,%A1" CR_TAB
5003 "std %B0,%B1", op, plen, -2);
5005 return reg_src == REG_X
5006 ? avr_asm_len ("mov __tmp_reg__,r26" CR_TAB
5007 "mov __zero_reg__,r27" CR_TAB
5008 "adiw r26,%o0" CR_TAB
5009 "st X+,__tmp_reg__" CR_TAB
5010 "st X,__zero_reg__" CR_TAB
5011 "clr __zero_reg__" CR_TAB
5012 "sbiw r26,%o0+1", op, plen, -7)
5014 : avr_asm_len ("adiw r26,%o0" CR_TAB
5017 "sbiw r26,%o0+1", op, plen, -4);
5019 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
5021 if (!mem_volatile_p)
5022 return avr_asm_len ("st %0,%B1" CR_TAB
5023 "st %0,%A1", op, plen, -2);
5025 return REGNO (XEXP (base, 0)) == REG_X
5026 ? avr_asm_len ("sbiw r26,2" CR_TAB
5029 "sbiw r26,1", op, plen, -4)
5031 : avr_asm_len ("sbiw %r0,2" CR_TAB
5033 "std %p0+1,%B1", op, plen, -3);
5035 else if (GET_CODE (base) == POST_INC) /* (R++) */
5037 return avr_asm_len ("st %0,%A1" CR_TAB
5038 "st %0,%B1", op, plen, -2);
5041 fatal_insn ("unknown move insn:",insn);
5046 avr_out_movhi_mr_r_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
5050 rtx base = XEXP (dest, 0);
5051 int reg_base = true_regnum (base);
5052 int reg_src = true_regnum (src);
5053 int mem_volatile_p = MEM_VOLATILE_P (dest);
5055 if (reg_base == reg_src)
5057 return !mem_volatile_p && reg_unused_after (insn, src)
5058 ? avr_asm_len ("mov __tmp_reg__,%B1" CR_TAB
5060 TINY_ADIW (%E0, %F0, 1) CR_TAB
5061 "st %0,__tmp_reg__", op, plen, -5)
5062 : avr_asm_len ("mov __tmp_reg__,%B1" CR_TAB
5063 TINY_ADIW (%E0, %F0, 1) CR_TAB
5064 "st %0,__tmp_reg__" CR_TAB
5065 TINY_SBIW (%E0, %F0, 1) CR_TAB
5066 "st %0, %A1", op, plen, -7);
5069 return !mem_volatile_p && reg_unused_after (insn, base)
5070 ? avr_asm_len ("st %0+,%A1" CR_TAB
5071 "st %0,%B1", op, plen, -2)
5072 : avr_asm_len (TINY_ADIW (%E0, %F0, 1) CR_TAB
5074 "st -%0,%A1", op, plen, -4);
5078 avr_out_movhi_mr_r_reg_disp_tiny (rtx op[], int *plen)
5082 rtx base = XEXP (dest, 0);
5083 int reg_base = REGNO (XEXP (base, 0));
5084 int reg_src = true_regnum (src);
5086 return reg_src == reg_base
5087 ? avr_asm_len ("mov __tmp_reg__,%A1" CR_TAB
5088 "mov __zero_reg__,%B1" CR_TAB
5089 TINY_ADIW (%I0, %J0, %o0+1) CR_TAB
5090 "st %b0,__zero_reg__" CR_TAB
5091 "st -%b0,__tmp_reg__" CR_TAB
5092 "clr __zero_reg__" CR_TAB
5093 TINY_SBIW (%I0, %J0, %o0), op, plen, -9)
5095 : avr_asm_len (TINY_ADIW (%I0, %J0, %o0+1) CR_TAB
5097 "st -%b0,%A1" CR_TAB
5098 TINY_SBIW (%I0, %J0, %o0), op, plen, -6);
5102 avr_out_movhi_mr_r_post_inc_tiny (rtx op[], int *plen)
5104 return avr_asm_len (TINY_ADIW (%I0, %J0, 1) CR_TAB
5106 "st -%p0,%A1" CR_TAB
5107 TINY_ADIW (%I0, %J0, 2), op, plen, -6);
5111 out_movhi_mr_r (rtx_insn *insn, rtx op[], int *plen)
5115 rtx base = XEXP (dest, 0);
5116 int reg_base = true_regnum (base);
5117 int reg_src = true_regnum (src);
5120 /* "volatile" forces writing high-byte first (no-xmega) resp.
5121 low-byte first (xmega) even if less efficient, for correct
5122 operation with 16-bit I/O registers like. */
5125 return avr_out_movhi_mr_r_xmega (insn, op, plen);
5127 mem_volatile_p = MEM_VOLATILE_P (dest);
5129 if (CONSTANT_ADDRESS_P (base))
5131 int n_words = AVR_TINY ? 2 : 4;
5132 return optimize > 0 && io_address_operand (base, HImode)
5133 ? avr_asm_len ("out %i0+1,%B1" CR_TAB
5134 "out %i0,%A1", op, plen, -2)
5136 : avr_asm_len ("sts %m0+1,%B1" CR_TAB
5137 "sts %m0,%A1", op, plen, -n_words);
5143 return avr_out_movhi_mr_r_reg_no_disp_tiny (insn, op, plen);
5145 if (reg_base != REG_X)
5146 return avr_asm_len ("std %0+1,%B1" CR_TAB
5147 "st %0,%A1", op, plen, -2);
5149 if (reg_src == REG_X)
5150 /* "st X+,r26" and "st -X,r26" are undefined. */
5151 return !mem_volatile_p && reg_unused_after (insn, src)
5152 ? avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
5155 "st X,__tmp_reg__", op, plen, -4)
5157 : avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
5159 "st X,__tmp_reg__" CR_TAB
5161 "st X,r26", op, plen, -5);
5163 return !mem_volatile_p && reg_unused_after (insn, base)
5164 ? avr_asm_len ("st X+,%A1" CR_TAB
5165 "st X,%B1", op, plen, -2)
5166 : avr_asm_len ("adiw r26,1" CR_TAB
5168 "st -X,%A1", op, plen, -3);
5170 else if (GET_CODE (base) == PLUS)
5172 int disp = INTVAL (XEXP (base, 1));
5175 return avr_out_movhi_mr_r_reg_disp_tiny (op, plen);
5177 reg_base = REGNO (XEXP (base, 0));
5178 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
5180 if (reg_base != REG_Y)
5181 fatal_insn ("incorrect insn:",insn);
5183 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))
5184 ? avr_asm_len ("adiw r28,%o0-62" CR_TAB
5185 "std Y+63,%B1" CR_TAB
5186 "std Y+62,%A1" CR_TAB
5187 "sbiw r28,%o0-62", op, plen, -4)
5189 : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
5190 "sbci r29,hi8(-%o0)" CR_TAB
5191 "std Y+1,%B1" CR_TAB
5193 "subi r28,lo8(%o0)" CR_TAB
5194 "sbci r29,hi8(%o0)", op, plen, -6);
5197 if (reg_base != REG_X)
5198 return avr_asm_len ("std %B0,%B1" CR_TAB
5199 "std %A0,%A1", op, plen, -2);
5201 return reg_src == REG_X
5202 ? avr_asm_len ("mov __tmp_reg__,r26" CR_TAB
5203 "mov __zero_reg__,r27" CR_TAB
5204 "adiw r26,%o0+1" CR_TAB
5205 "st X,__zero_reg__" CR_TAB
5206 "st -X,__tmp_reg__" CR_TAB
5207 "clr __zero_reg__" CR_TAB
5208 "sbiw r26,%o0", op, plen, -7)
5210 : avr_asm_len ("adiw r26,%o0+1" CR_TAB
5213 "sbiw r26,%o0", op, plen, -4);
5215 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
5217 return avr_asm_len ("st %0,%B1" CR_TAB
5218 "st %0,%A1", op, plen, -2);
5220 else if (GET_CODE (base) == POST_INC) /* (R++) */
5222 if (!mem_volatile_p)
5223 return avr_asm_len ("st %0,%A1" CR_TAB
5224 "st %0,%B1", op, plen, -2);
5227 return avr_out_movhi_mr_r_post_inc_tiny (op, plen);
5229 return REGNO (XEXP (base, 0)) == REG_X
5230 ? avr_asm_len ("adiw r26,1" CR_TAB
5233 "adiw r26,2", op, plen, -4)
5235 : avr_asm_len ("std %p0+1,%B1" CR_TAB
5237 "adiw %r0,2", op, plen, -3);
5239 fatal_insn ("unknown move insn:",insn);
5243 /* Return 1 if frame pointer for current function required. */
5246 avr_frame_pointer_required_p (void)
5248 return (cfun->calls_alloca
5249 || cfun->calls_setjmp
5250 || cfun->has_nonlocal_label
5251 || crtl->args.info.nregs == 0
5252 || get_frame_size () > 0);
5255 /* Returns the condition of compare insn INSN, or UNKNOWN. */
5258 compare_condition (rtx_insn *insn)
5260 rtx_insn *next = next_real_insn (insn);
5262 if (next && JUMP_P (next))
5264 rtx pat = PATTERN (next);
5265 rtx src = SET_SRC (pat);
5267 if (IF_THEN_ELSE == GET_CODE (src))
5268 return GET_CODE (XEXP (src, 0));
5275 /* Returns true iff INSN is a tst insn that only tests the sign. */
5278 compare_sign_p (rtx_insn *insn)
5280 RTX_CODE cond = compare_condition (insn);
5281 return (cond == GE || cond == LT);
5285 /* Returns true iff the next insn is a JUMP_INSN with a condition
5286 that needs to be swapped (GT, GTU, LE, LEU). */
5289 compare_diff_p (rtx_insn *insn)
5291 RTX_CODE cond = compare_condition (insn);
5292 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
5295 /* Returns true iff INSN is a compare insn with the EQ or NE condition. */
5298 compare_eq_p (rtx_insn *insn)
5300 RTX_CODE cond = compare_condition (insn);
5301 return (cond == EQ || cond == NE);
5305 /* Output compare instruction
5307 compare (XOP[0], XOP[1])
5309 for a register XOP[0] and a compile-time constant XOP[1]. Return "".
5310 XOP[2] is an 8-bit scratch register as needed.
5312 PLEN == NULL: Output instructions.
5313 PLEN != NULL: Set *PLEN to the length (in words) of the sequence.
5314 Don't output anything. */
5317 avr_out_compare (rtx_insn *insn, rtx *xop, int *plen)
5319 /* Register to compare and value to compare against. */
5323 /* MODE of the comparison. */
5326 /* Number of bytes to operate on. */
5327 int i, n_bytes = GET_MODE_SIZE (GET_MODE (xreg));
5329 /* Value (0..0xff) held in clobber register xop[2] or -1 if unknown. */
5330 int clobber_val = -1;
5332 /* Map fixed mode operands to integer operands with the same binary
5333 representation. They are easier to handle in the remainder. */
5335 if (CONST_FIXED_P (xval))
5337 xreg = avr_to_int_mode (xop[0]);
5338 xval = avr_to_int_mode (xop[1]);
5341 mode = GET_MODE (xreg);
5343 gcc_assert (REG_P (xreg));
5344 gcc_assert ((CONST_INT_P (xval) && n_bytes <= 4)
5345 || (const_double_operand (xval, VOIDmode) && n_bytes == 8));
5350 /* Comparisons == +/-1 and != +/-1 can be done similar to camparing
5351 against 0 by ORing the bytes. This is one instruction shorter.
5352 Notice that 64-bit comparisons are always against reg:ALL8 18 (ACC_A)
5353 and therefore don't use this. */
5355 if (!test_hard_reg_class (LD_REGS, xreg)
5356 && compare_eq_p (insn)
5357 && reg_unused_after (insn, xreg))
5359 if (xval == const1_rtx)
5361 avr_asm_len ("dec %A0" CR_TAB
5362 "or %A0,%B0", xop, plen, 2);
5365 avr_asm_len ("or %A0,%C0", xop, plen, 1);
5368 avr_asm_len ("or %A0,%D0", xop, plen, 1);
5372 else if (xval == constm1_rtx)
5375 avr_asm_len ("and %A0,%D0", xop, plen, 1);
5378 avr_asm_len ("and %A0,%C0", xop, plen, 1);
5380 return avr_asm_len ("and %A0,%B0" CR_TAB
5381 "com %A0", xop, plen, 2);
5385 for (i = 0; i < n_bytes; i++)
5387 /* We compare byte-wise. */
5388 rtx reg8 = simplify_gen_subreg (QImode, xreg, mode, i);
5389 rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
5391 /* 8-bit value to compare with this byte. */
5392 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
5394 /* Registers R16..R31 can operate with immediate. */
5395 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
5398 xop[1] = gen_int_mode (val8, QImode);
5400 /* Word registers >= R24 can use SBIW/ADIW with 0..63. */
5403 && test_hard_reg_class (ADDW_REGS, reg8))
5405 int val16 = trunc_int_for_mode (INTVAL (xval), HImode);
5407 if (IN_RANGE (val16, 0, 63)
5409 || reg_unused_after (insn, xreg)))
5412 avr_asm_len (TINY_SBIW (%A0, %B0, %1), xop, plen, 2);
5414 avr_asm_len ("sbiw %0,%1", xop, plen, 1);
5421 && IN_RANGE (val16, -63, -1)
5422 && compare_eq_p (insn)
5423 && reg_unused_after (insn, xreg))
5426 ? avr_asm_len (TINY_ADIW (%A0, %B0, %n1), xop, plen, 2)
5427 : avr_asm_len ("adiw %0,%n1", xop, plen, 1);
5431 /* Comparing against 0 is easy. */
5436 ? "cp %0,__zero_reg__"
5437 : "cpc %0,__zero_reg__", xop, plen, 1);
5441 /* Upper registers can compare and subtract-with-carry immediates.
5442 Notice that compare instructions do the same as respective subtract
5443 instruction; the only difference is that comparisons don't write
5444 the result back to the target register. */
5450 avr_asm_len ("cpi %0,%1", xop, plen, 1);
5453 else if (reg_unused_after (insn, xreg))
5455 avr_asm_len ("sbci %0,%1", xop, plen, 1);
5460 /* Must load the value into the scratch register. */
5462 gcc_assert (REG_P (xop[2]));
5464 if (clobber_val != (int) val8)
5465 avr_asm_len ("ldi %2,%1", xop, plen, 1);
5466 clobber_val = (int) val8;
5470 : "cpc %0,%2", xop, plen, 1);
5477 /* Prepare operands of compare_const_di2 to be used with avr_out_compare. */
5480 avr_out_compare64 (rtx_insn *insn, rtx *op, int *plen)
5484 xop[0] = gen_rtx_REG (DImode, 18);
5488 return avr_out_compare (insn, xop, plen);
5491 /* Output test instruction for HImode. */
5494 avr_out_tsthi (rtx_insn *insn, rtx *op, int *plen)
5496 if (compare_sign_p (insn))
5498 avr_asm_len ("tst %B0", op, plen, -1);
5500 else if (reg_unused_after (insn, op[0])
5501 && compare_eq_p (insn))
5503 /* Faster than sbiw if we can clobber the operand. */
5504 avr_asm_len ("or %A0,%B0", op, plen, -1);
5508 avr_out_compare (insn, op, plen);
5515 /* Output test instruction for PSImode. */
5518 avr_out_tstpsi (rtx_insn *insn, rtx *op, int *plen)
5520 if (compare_sign_p (insn))
5522 avr_asm_len ("tst %C0", op, plen, -1);
5524 else if (reg_unused_after (insn, op[0])
5525 && compare_eq_p (insn))
5527 /* Faster than sbiw if we can clobber the operand. */
5528 avr_asm_len ("or %A0,%B0" CR_TAB
5529 "or %A0,%C0", op, plen, -2);
5533 avr_out_compare (insn, op, plen);
5540 /* Output test instruction for SImode. */
5543 avr_out_tstsi (rtx_insn *insn, rtx *op, int *plen)
5545 if (compare_sign_p (insn))
5547 avr_asm_len ("tst %D0", op, plen, -1);
5549 else if (reg_unused_after (insn, op[0])
5550 && compare_eq_p (insn))
5552 /* Faster than sbiw if we can clobber the operand. */
5553 avr_asm_len ("or %A0,%B0" CR_TAB
5555 "or %A0,%D0", op, plen, -3);
5559 avr_out_compare (insn, op, plen);
5566 /* Generate asm equivalent for various shifts. This only handles cases
5567 that are not already carefully hand-optimized in ?sh??i3_out.
5569 OPERANDS[0] resp. %0 in TEMPL is the operand to be shifted.
5570 OPERANDS[2] is the shift count as CONST_INT, MEM or REG.
5571 OPERANDS[3] is a QImode scratch register from LD regs if
5572 available and SCRATCH, otherwise (no scratch available)
5574 TEMPL is an assembler template that shifts by one position.
5575 T_LEN is the length of this template. */
5578 out_shift_with_cnt (const char *templ, rtx_insn *insn, rtx operands[],
5579 int *plen, int t_len)
5581 bool second_label = true;
5582 bool saved_in_tmp = false;
5583 bool use_zero_reg = false;
5586 op[0] = operands[0];
5587 op[1] = operands[1];
5588 op[2] = operands[2];
5589 op[3] = operands[3];
5594 if (CONST_INT_P (operands[2]))
5596 bool scratch = (GET_CODE (PATTERN (insn)) == PARALLEL
5597 && REG_P (operands[3]));
5598 int count = INTVAL (operands[2]);
5599 int max_len = 10; /* If larger than this, always use a loop. */
5604 if (count < 8 && !scratch)
5605 use_zero_reg = true;
5608 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
5610 if (t_len * count <= max_len)
5612 /* Output shifts inline with no loop - faster. */
5615 avr_asm_len (templ, op, plen, t_len);
5622 avr_asm_len ("ldi %3,%2", op, plen, 1);
5624 else if (use_zero_reg)
5626 /* Hack to save one word: use __zero_reg__ as loop counter.
5627 Set one bit, then shift in a loop until it is 0 again. */
5629 op[3] = zero_reg_rtx;
5631 avr_asm_len ("set" CR_TAB
5632 "bld %3,%2-1", op, plen, 2);
5636 /* No scratch register available, use one from LD_REGS (saved in
5637 __tmp_reg__) that doesn't overlap with registers to shift. */
5639 op[3] = all_regs_rtx[((REGNO (op[0]) - 1) & 15) + 16];
5640 op[4] = tmp_reg_rtx;
5641 saved_in_tmp = true;
5643 avr_asm_len ("mov %4,%3" CR_TAB
5644 "ldi %3,%2", op, plen, 2);
5647 second_label = false;
5649 else if (MEM_P (op[2]))
5653 op_mov[0] = op[3] = tmp_reg_rtx;
5656 out_movqi_r_mr (insn, op_mov, plen);
5658 else if (register_operand (op[2], QImode))
5662 if (!reg_unused_after (insn, op[2])
5663 || reg_overlap_mentioned_p (op[0], op[2]))
5665 op[3] = tmp_reg_rtx;
5666 avr_asm_len ("mov %3,%2", op, plen, 1);
5670 fatal_insn ("bad shift insn:", insn);
5673 avr_asm_len ("rjmp 2f", op, plen, 1);
5675 avr_asm_len ("1:", op, plen, 0);
5676 avr_asm_len (templ, op, plen, t_len);
5679 avr_asm_len ("2:", op, plen, 0);
5681 avr_asm_len (use_zero_reg ? "lsr %3" : "dec %3", op, plen, 1);
5682 avr_asm_len (second_label ? "brpl 1b" : "brne 1b", op, plen, 1);
5685 avr_asm_len ("mov %3,%4", op, plen, 1);
5689 /* 8bit shift left ((char)x << i) */
5692 ashlqi3_out (rtx_insn *insn, rtx operands[], int *len)
5694 if (GET_CODE (operands[2]) == CONST_INT)
5701 switch (INTVAL (operands[2]))
5704 if (INTVAL (operands[2]) < 8)
5716 return ("lsl %0" CR_TAB
5721 return ("lsl %0" CR_TAB
5726 if (test_hard_reg_class (LD_REGS, operands[0]))
5729 return ("swap %0" CR_TAB
5733 return ("lsl %0" CR_TAB
5739 if (test_hard_reg_class (LD_REGS, operands[0]))
5742 return ("swap %0" CR_TAB
5747 return ("lsl %0" CR_TAB
5754 if (test_hard_reg_class (LD_REGS, operands[0]))
5757 return ("swap %0" CR_TAB
5763 return ("lsl %0" CR_TAB
5772 return ("ror %0" CR_TAB
5777 else if (CONSTANT_P (operands[2]))
5778 fatal_insn ("internal compiler error. Incorrect shift:", insn);
5780 out_shift_with_cnt ("lsl %0",
5781 insn, operands, len, 1);
5786 /* 16bit shift left ((short)x << i) */
5789 ashlhi3_out (rtx_insn *insn, rtx operands[], int *len)
5791 if (GET_CODE (operands[2]) == CONST_INT)
5793 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
5794 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
5801 switch (INTVAL (operands[2]))
5804 if (INTVAL (operands[2]) < 16)
5808 return ("clr %B0" CR_TAB
5812 if (optimize_size && scratch)
5817 return ("swap %A0" CR_TAB
5819 "andi %B0,0xf0" CR_TAB
5820 "eor %B0,%A0" CR_TAB
5821 "andi %A0,0xf0" CR_TAB
5827 return ("swap %A0" CR_TAB
5829 "ldi %3,0xf0" CR_TAB
5831 "eor %B0,%A0" CR_TAB
5835 break; /* optimize_size ? 6 : 8 */
5839 break; /* scratch ? 5 : 6 */
5843 return ("lsl %A0" CR_TAB
5847 "andi %B0,0xf0" CR_TAB
5848 "eor %B0,%A0" CR_TAB
5849 "andi %A0,0xf0" CR_TAB
5855 return ("lsl %A0" CR_TAB
5859 "ldi %3,0xf0" CR_TAB
5861 "eor %B0,%A0" CR_TAB
5869 break; /* scratch ? 5 : 6 */
5871 return ("clr __tmp_reg__" CR_TAB
5874 "ror __tmp_reg__" CR_TAB
5877 "ror __tmp_reg__" CR_TAB
5878 "mov %B0,%A0" CR_TAB
5879 "mov %A0,__tmp_reg__");
5883 return ("lsr %B0" CR_TAB
5884 "mov %B0,%A0" CR_TAB
5890 return *len = 2, ("mov %B0,%A1" CR_TAB
5895 return ("mov %B0,%A0" CR_TAB
5901 return ("mov %B0,%A0" CR_TAB
5908 return ("mov %B0,%A0" CR_TAB
5918 return ("mov %B0,%A0" CR_TAB
5926 return ("mov %B0,%A0" CR_TAB
5929 "ldi %3,0xf0" CR_TAB
5933 return ("mov %B0,%A0" CR_TAB
5944 return ("mov %B0,%A0" CR_TAB
5950 if (AVR_HAVE_MUL && scratch)
5953 return ("ldi %3,0x20" CR_TAB
5957 "clr __zero_reg__");
5959 if (optimize_size && scratch)
5964 return ("mov %B0,%A0" CR_TAB
5968 "ldi %3,0xe0" CR_TAB
5974 return ("set" CR_TAB
5979 "clr __zero_reg__");
5982 return ("mov %B0,%A0" CR_TAB
5991 if (AVR_HAVE_MUL && ldi_ok)
5994 return ("ldi %B0,0x40" CR_TAB
5995 "mul %A0,%B0" CR_TAB
5998 "clr __zero_reg__");
6000 if (AVR_HAVE_MUL && scratch)
6003 return ("ldi %3,0x40" CR_TAB
6007 "clr __zero_reg__");
6009 if (optimize_size && ldi_ok)
6012 return ("mov %B0,%A0" CR_TAB
6013 "ldi %A0,6" "\n1:\t"
6018 if (optimize_size && scratch)
6021 return ("clr %B0" CR_TAB
6030 return ("clr %B0" CR_TAB
6037 out_shift_with_cnt ("lsl %A0" CR_TAB
6038 "rol %B0", insn, operands, len, 2);
6043 /* 24-bit shift left */
6046 avr_out_ashlpsi3 (rtx_insn *insn, rtx *op, int *plen)
6051 if (CONST_INT_P (op[2]))
6053 switch (INTVAL (op[2]))
6056 if (INTVAL (op[2]) < 24)
6059 return avr_asm_len ("clr %A0" CR_TAB
6061 "clr %C0", op, plen, 3);
6065 int reg0 = REGNO (op[0]);
6066 int reg1 = REGNO (op[1]);
6069 return avr_asm_len ("mov %C0,%B1" CR_TAB
6070 "mov %B0,%A1" CR_TAB
6071 "clr %A0", op, plen, 3);
6073 return avr_asm_len ("clr %A0" CR_TAB
6074 "mov %B0,%A1" CR_TAB
6075 "mov %C0,%B1", op, plen, 3);
6080 int reg0 = REGNO (op[0]);
6081 int reg1 = REGNO (op[1]);
6083 if (reg0 + 2 != reg1)
6084 avr_asm_len ("mov %C0,%A0", op, plen, 1);
6086 return avr_asm_len ("clr %B0" CR_TAB
6087 "clr %A0", op, plen, 2);
6091 return avr_asm_len ("clr %C0" CR_TAB
6095 "clr %A0", op, plen, 5);
6099 out_shift_with_cnt ("lsl %A0" CR_TAB
6101 "rol %C0", insn, op, plen, 3);
6106 /* 32bit shift left ((long)x << i) */
6109 ashlsi3_out (rtx_insn *insn, rtx operands[], int *len)
6111 if (GET_CODE (operands[2]) == CONST_INT)
6119 switch (INTVAL (operands[2]))
6122 if (INTVAL (operands[2]) < 32)
6126 return *len = 3, ("clr %D0" CR_TAB
6130 return ("clr %D0" CR_TAB
6137 int reg0 = true_regnum (operands[0]);
6138 int reg1 = true_regnum (operands[1]);
6141 return ("mov %D0,%C1" CR_TAB
6142 "mov %C0,%B1" CR_TAB
6143 "mov %B0,%A1" CR_TAB
6146 return ("clr %A0" CR_TAB
6147 "mov %B0,%A1" CR_TAB
6148 "mov %C0,%B1" CR_TAB
6154 int reg0 = true_regnum (operands[0]);
6155 int reg1 = true_regnum (operands[1]);
6156 if (reg0 + 2 == reg1)
6157 return *len = 2, ("clr %B0" CR_TAB
6160 return *len = 3, ("movw %C0,%A1" CR_TAB
6164 return *len = 4, ("mov %C0,%A1" CR_TAB
6165 "mov %D0,%B1" CR_TAB
6172 return ("mov %D0,%A1" CR_TAB
6179 return ("clr %D0" CR_TAB
6188 out_shift_with_cnt ("lsl %A0" CR_TAB
6191 "rol %D0", insn, operands, len, 4);
6195 /* 8bit arithmetic shift right ((signed char)x >> i) */
6198 ashrqi3_out (rtx_insn *insn, rtx operands[], int *len)
6200 if (GET_CODE (operands[2]) == CONST_INT)
6207 switch (INTVAL (operands[2]))
6215 return ("asr %0" CR_TAB
6220 return ("asr %0" CR_TAB
6226 return ("asr %0" CR_TAB
6233 return ("asr %0" CR_TAB
6241 return ("bst %0,6" CR_TAB
6247 if (INTVAL (operands[2]) < 8)
6254 return ("lsl %0" CR_TAB
6258 else if (CONSTANT_P (operands[2]))
6259 fatal_insn ("internal compiler error. Incorrect shift:", insn);
6261 out_shift_with_cnt ("asr %0",
6262 insn, operands, len, 1);
6267 /* 16bit arithmetic shift right ((signed short)x >> i) */
6270 ashrhi3_out (rtx_insn *insn, rtx operands[], int *len)
6272 if (GET_CODE (operands[2]) == CONST_INT)
6274 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
6275 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
6282 switch (INTVAL (operands[2]))
6286 /* XXX try to optimize this too? */
6291 break; /* scratch ? 5 : 6 */
6293 return ("mov __tmp_reg__,%A0" CR_TAB
6294 "mov %A0,%B0" CR_TAB
6295 "lsl __tmp_reg__" CR_TAB
6297 "sbc %B0,%B0" CR_TAB
6298 "lsl __tmp_reg__" CR_TAB
6304 return ("lsl %A0" CR_TAB
6305 "mov %A0,%B0" CR_TAB
6311 int reg0 = true_regnum (operands[0]);
6312 int reg1 = true_regnum (operands[1]);
6315 return *len = 3, ("mov %A0,%B0" CR_TAB
6319 return *len = 4, ("mov %A0,%B1" CR_TAB
6327 return ("mov %A0,%B0" CR_TAB
6329 "sbc %B0,%B0" CR_TAB
6334 return ("mov %A0,%B0" CR_TAB
6336 "sbc %B0,%B0" CR_TAB
6341 if (AVR_HAVE_MUL && ldi_ok)
6344 return ("ldi %A0,0x20" CR_TAB
6345 "muls %B0,%A0" CR_TAB
6347 "sbc %B0,%B0" CR_TAB
6348 "clr __zero_reg__");
6350 if (optimize_size && scratch)
6353 return ("mov %A0,%B0" CR_TAB
6355 "sbc %B0,%B0" CR_TAB
6361 if (AVR_HAVE_MUL && ldi_ok)
6364 return ("ldi %A0,0x10" CR_TAB
6365 "muls %B0,%A0" CR_TAB
6367 "sbc %B0,%B0" CR_TAB
6368 "clr __zero_reg__");
6370 if (optimize_size && scratch)
6373 return ("mov %A0,%B0" CR_TAB
6375 "sbc %B0,%B0" CR_TAB
6382 if (AVR_HAVE_MUL && ldi_ok)
6385 return ("ldi %A0,0x08" CR_TAB
6386 "muls %B0,%A0" CR_TAB
6388 "sbc %B0,%B0" CR_TAB
6389 "clr __zero_reg__");
6392 break; /* scratch ? 5 : 7 */
6394 return ("mov %A0,%B0" CR_TAB
6396 "sbc %B0,%B0" CR_TAB
6405 return ("lsl %B0" CR_TAB
6406 "sbc %A0,%A0" CR_TAB
6408 "mov %B0,%A0" CR_TAB
6412 if (INTVAL (operands[2]) < 16)
6418 return *len = 3, ("lsl %B0" CR_TAB
6419 "sbc %A0,%A0" CR_TAB
6424 out_shift_with_cnt ("asr %B0" CR_TAB
6425 "ror %A0", insn, operands, len, 2);
6430 /* 24-bit arithmetic shift right */
6433 avr_out_ashrpsi3 (rtx_insn *insn, rtx *op, int *plen)
6435 int dest = REGNO (op[0]);
6436 int src = REGNO (op[1]);
6438 if (CONST_INT_P (op[2]))
6443 switch (INTVAL (op[2]))
6447 return avr_asm_len ("mov %A0,%B1" CR_TAB
6448 "mov %B0,%C1" CR_TAB
6451 "dec %C0", op, plen, 5);
6453 return avr_asm_len ("clr %C0" CR_TAB
6456 "mov %B0,%C1" CR_TAB
6457 "mov %A0,%B1", op, plen, 5);
6460 if (dest != src + 2)
6461 avr_asm_len ("mov %A0,%C1", op, plen, 1);
6463 return avr_asm_len ("clr %B0" CR_TAB
6466 "mov %C0,%B0", op, plen, 4);
6469 if (INTVAL (op[2]) < 24)
6475 return avr_asm_len ("lsl %C0" CR_TAB
6476 "sbc %A0,%A0" CR_TAB
6477 "mov %B0,%A0" CR_TAB
6478 "mov %C0,%A0", op, plen, 4);
6482 out_shift_with_cnt ("asr %C0" CR_TAB
6484 "ror %A0", insn, op, plen, 3);
6489 /* 32-bit arithmetic shift right ((signed long)x >> i) */
6492 ashrsi3_out (rtx_insn *insn, rtx operands[], int *len)
6494 if (GET_CODE (operands[2]) == CONST_INT)
6502 switch (INTVAL (operands[2]))
6506 int reg0 = true_regnum (operands[0]);
6507 int reg1 = true_regnum (operands[1]);
6510 return ("mov %A0,%B1" CR_TAB
6511 "mov %B0,%C1" CR_TAB
6512 "mov %C0,%D1" CR_TAB
6517 return ("clr %D0" CR_TAB
6520 "mov %C0,%D1" CR_TAB
6521 "mov %B0,%C1" CR_TAB
6527 int reg0 = true_regnum (operands[0]);
6528 int reg1 = true_regnum (operands[1]);
6530 if (reg0 == reg1 + 2)
6531 return *len = 4, ("clr %D0" CR_TAB
6536 return *len = 5, ("movw %A0,%C1" CR_TAB
6542 return *len = 6, ("mov %B0,%D1" CR_TAB
6543 "mov %A0,%C1" CR_TAB
6551 return *len = 6, ("mov %A0,%D1" CR_TAB
6555 "mov %B0,%D0" CR_TAB
6559 if (INTVAL (operands[2]) < 32)
6566 return *len = 4, ("lsl %D0" CR_TAB
6567 "sbc %A0,%A0" CR_TAB
6568 "mov %B0,%A0" CR_TAB
6571 return *len = 5, ("lsl %D0" CR_TAB
6572 "sbc %A0,%A0" CR_TAB
6573 "mov %B0,%A0" CR_TAB
6574 "mov %C0,%A0" CR_TAB
6579 out_shift_with_cnt ("asr %D0" CR_TAB
6582 "ror %A0", insn, operands, len, 4);
6586 /* 8-bit logic shift right ((unsigned char)x >> i) */
6589 lshrqi3_out (rtx_insn *insn, rtx operands[], int *len)
6591 if (GET_CODE (operands[2]) == CONST_INT)
6598 switch (INTVAL (operands[2]))
6601 if (INTVAL (operands[2]) < 8)
6613 return ("lsr %0" CR_TAB
6617 return ("lsr %0" CR_TAB
6622 if (test_hard_reg_class (LD_REGS, operands[0]))
6625 return ("swap %0" CR_TAB
6629 return ("lsr %0" CR_TAB
6635 if (test_hard_reg_class (LD_REGS, operands[0]))
6638 return ("swap %0" CR_TAB
6643 return ("lsr %0" CR_TAB
6650 if (test_hard_reg_class (LD_REGS, operands[0]))
6653 return ("swap %0" CR_TAB
6659 return ("lsr %0" CR_TAB
6668 return ("rol %0" CR_TAB
6673 else if (CONSTANT_P (operands[2]))
6674 fatal_insn ("internal compiler error. Incorrect shift:", insn);
6676 out_shift_with_cnt ("lsr %0",
6677 insn, operands, len, 1);
6681 /* 16-bit logic shift right ((unsigned short)x >> i) */
6684 lshrhi3_out (rtx_insn *insn, rtx operands[], int *len)
6686 if (GET_CODE (operands[2]) == CONST_INT)
6688 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
6689 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
6696 switch (INTVAL (operands[2]))
6699 if (INTVAL (operands[2]) < 16)
6703 return ("clr %B0" CR_TAB
6707 if (optimize_size && scratch)
6712 return ("swap %B0" CR_TAB
6714 "andi %A0,0x0f" CR_TAB
6715 "eor %A0,%B0" CR_TAB
6716 "andi %B0,0x0f" CR_TAB
6722 return ("swap %B0" CR_TAB
6724 "ldi %3,0x0f" CR_TAB
6726 "eor %A0,%B0" CR_TAB
6730 break; /* optimize_size ? 6 : 8 */
6734 break; /* scratch ? 5 : 6 */
6738 return ("lsr %B0" CR_TAB
6742 "andi %A0,0x0f" CR_TAB
6743 "eor %A0,%B0" CR_TAB
6744 "andi %B0,0x0f" CR_TAB
6750 return ("lsr %B0" CR_TAB
6754 "ldi %3,0x0f" CR_TAB
6756 "eor %A0,%B0" CR_TAB
6764 break; /* scratch ? 5 : 6 */
6766 return ("clr __tmp_reg__" CR_TAB
6769 "rol __tmp_reg__" CR_TAB
6772 "rol __tmp_reg__" CR_TAB
6773 "mov %A0,%B0" CR_TAB
6774 "mov %B0,__tmp_reg__");
6778 return ("lsl %A0" CR_TAB
6779 "mov %A0,%B0" CR_TAB
6781 "sbc %B0,%B0" CR_TAB
6785 return *len = 2, ("mov %A0,%B1" CR_TAB
6790 return ("mov %A0,%B0" CR_TAB
6796 return ("mov %A0,%B0" CR_TAB
6803 return ("mov %A0,%B0" CR_TAB
6813 return ("mov %A0,%B0" CR_TAB
6821 return ("mov %A0,%B0" CR_TAB
6824 "ldi %3,0x0f" CR_TAB
6828 return ("mov %A0,%B0" CR_TAB
6839 return ("mov %A0,%B0" CR_TAB
6845 if (AVR_HAVE_MUL && scratch)
6848 return ("ldi %3,0x08" CR_TAB
6852 "clr __zero_reg__");
6854 if (optimize_size && scratch)
6859 return ("mov %A0,%B0" CR_TAB
6863 "ldi %3,0x07" CR_TAB
6869 return ("set" CR_TAB
6874 "clr __zero_reg__");
6877 return ("mov %A0,%B0" CR_TAB
6886 if (AVR_HAVE_MUL && ldi_ok)
6889 return ("ldi %A0,0x04" CR_TAB
6890 "mul %B0,%A0" CR_TAB
6893 "clr __zero_reg__");
6895 if (AVR_HAVE_MUL && scratch)
6898 return ("ldi %3,0x04" CR_TAB
6902 "clr __zero_reg__");
6904 if (optimize_size && ldi_ok)
6907 return ("mov %A0,%B0" CR_TAB
6908 "ldi %B0,6" "\n1:\t"
6913 if (optimize_size && scratch)
6916 return ("clr %A0" CR_TAB
6925 return ("clr %A0" CR_TAB
6932 out_shift_with_cnt ("lsr %B0" CR_TAB
6933 "ror %A0", insn, operands, len, 2);
6938 /* 24-bit logic shift right */
6941 avr_out_lshrpsi3 (rtx_insn *insn, rtx *op, int *plen)
6943 int dest = REGNO (op[0]);
6944 int src = REGNO (op[1]);
6946 if (CONST_INT_P (op[2]))
6951 switch (INTVAL (op[2]))
6955 return avr_asm_len ("mov %A0,%B1" CR_TAB
6956 "mov %B0,%C1" CR_TAB
6957 "clr %C0", op, plen, 3);
6959 return avr_asm_len ("clr %C0" CR_TAB
6960 "mov %B0,%C1" CR_TAB
6961 "mov %A0,%B1", op, plen, 3);
6964 if (dest != src + 2)
6965 avr_asm_len ("mov %A0,%C1", op, plen, 1);
6967 return avr_asm_len ("clr %B0" CR_TAB
6968 "clr %C0", op, plen, 2);
6971 if (INTVAL (op[2]) < 24)
6977 return avr_asm_len ("clr %A0" CR_TAB
6981 "clr %C0", op, plen, 5);
6985 out_shift_with_cnt ("lsr %C0" CR_TAB
6987 "ror %A0", insn, op, plen, 3);
6992 /* 32-bit logic shift right ((unsigned int)x >> i) */
6995 lshrsi3_out (rtx_insn *insn, rtx operands[], int *len)
6997 if (GET_CODE (operands[2]) == CONST_INT)
7005 switch (INTVAL (operands[2]))
7008 if (INTVAL (operands[2]) < 32)
7012 return *len = 3, ("clr %D0" CR_TAB
7016 return ("clr %D0" CR_TAB
7023 int reg0 = true_regnum (operands[0]);
7024 int reg1 = true_regnum (operands[1]);
7027 return ("mov %A0,%B1" CR_TAB
7028 "mov %B0,%C1" CR_TAB
7029 "mov %C0,%D1" CR_TAB
7032 return ("clr %D0" CR_TAB
7033 "mov %C0,%D1" CR_TAB
7034 "mov %B0,%C1" CR_TAB
7040 int reg0 = true_regnum (operands[0]);
7041 int reg1 = true_regnum (operands[1]);
7043 if (reg0 == reg1 + 2)
7044 return *len = 2, ("clr %C0" CR_TAB
7047 return *len = 3, ("movw %A0,%C1" CR_TAB
7051 return *len = 4, ("mov %B0,%D1" CR_TAB
7052 "mov %A0,%C1" CR_TAB
7058 return *len = 4, ("mov %A0,%D1" CR_TAB
7065 return ("clr %A0" CR_TAB
7074 out_shift_with_cnt ("lsr %D0" CR_TAB
7077 "ror %A0", insn, operands, len, 4);
7082 /* Output addition of register XOP[0] and compile time constant XOP[2].
7083 CODE == PLUS: perform addition by using ADD instructions or
7084 CODE == MINUS: perform addition by using SUB instructions:
7086 XOP[0] = XOP[0] + XOP[2]
7088 Or perform addition/subtraction with register XOP[2] depending on CODE:
7090 XOP[0] = XOP[0] +/- XOP[2]
7092 If PLEN == NULL, print assembler instructions to perform the operation;
7093 otherwise, set *PLEN to the length of the instruction sequence (in words)
7094 printed with PLEN == NULL. XOP[3] is an 8-bit scratch register or NULL_RTX.
7095 Set *PCC to effect on cc0 according to respective CC_* insn attribute.
7097 CODE_SAT == UNKNOWN: Perform ordinary, non-saturating operation.
7098 CODE_SAT != UNKNOWN: Perform operation and saturate according to CODE_SAT.
7099 If CODE_SAT != UNKNOWN then SIGN contains the sign of the summand resp.
7100 the subtrahend in the original insn, provided it is a compile time constant.
7101 In all other cases, SIGN is 0.
7103 If OUT_LABEL is true, print the final 0: label which is needed for
7104 saturated addition / subtraction. The only case where OUT_LABEL = false
7105 is useful is for saturated addition / subtraction performed during
7106 fixed-point rounding, cf. `avr_out_round'. */
7109 avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc,
7110 enum rtx_code code_sat, int sign, bool out_label)
7112 /* MODE of the operation. */
7113 machine_mode mode = GET_MODE (xop[0]);
7115 /* INT_MODE of the same size. */
7116 machine_mode imode = int_mode_for_mode (mode);
7118 /* Number of bytes to operate on. */
7119 int i, n_bytes = GET_MODE_SIZE (mode);
7121 /* Value (0..0xff) held in clobber register op[3] or -1 if unknown. */
7122 int clobber_val = -1;
7124 /* op[0]: 8-bit destination register
7125 op[1]: 8-bit const int
7126 op[2]: 8-bit scratch register */
7129 /* Started the operation? Before starting the operation we may skip
7130 adding 0. This is no more true after the operation started because
7131 carry must be taken into account. */
7132 bool started = false;
7134 /* Value to add. There are two ways to add VAL: R += VAL and R -= -VAL. */
7137 /* Output a BRVC instruction. Only needed with saturation. */
7138 bool out_brvc = true;
7145 *pcc = MINUS == code ? (int) CC_SET_CZN : (int) CC_CLOBBER;
7147 for (i = 0; i < n_bytes; i++)
7149 /* We operate byte-wise on the destination. */
7150 op[0] = simplify_gen_subreg (QImode, xop[0], mode, i);
7151 op[1] = simplify_gen_subreg (QImode, xop[2], mode, i);
7154 avr_asm_len (code == PLUS ? "add %0,%1" : "sub %0,%1",
7157 avr_asm_len (code == PLUS ? "adc %0,%1" : "sbc %0,%1",
7161 if (reg_overlap_mentioned_p (xop[0], xop[2]))
7163 gcc_assert (REGNO (xop[0]) == REGNO (xop[2]));
7172 /* Except in the case of ADIW with 16-bit register (see below)
7173 addition does not set cc0 in a usable way. */
7175 *pcc = (MINUS == code) ? CC_SET_CZN : CC_CLOBBER;
7177 if (CONST_FIXED_P (xval))
7178 xval = avr_to_int_mode (xval);
7180 /* Adding/Subtracting zero is a no-op. */
7182 if (xval == const0_rtx)
7189 xval = simplify_unary_operation (NEG, imode, xval, imode);
7193 if (SS_PLUS == code_sat && MINUS == code
7195 && 0x80 == (INTVAL (simplify_gen_subreg (QImode, xval, imode, n_bytes-1))
7196 & GET_MODE_MASK (QImode)))
7198 /* We compute x + 0x80 by means of SUB instructions. We negated the
7199 constant subtrahend above and are left with x - (-128) so that we
7200 need something like SUBI r,128 which does not exist because SUBI sets
7201 V according to the sign of the subtrahend. Notice the only case
7202 where this must be done is when NEG overflowed in case [2s] because
7203 the V computation needs the right sign of the subtrahend. */
7205 rtx msb = simplify_gen_subreg (QImode, xop[0], mode, n_bytes-1);
7207 avr_asm_len ("subi %0,128" CR_TAB
7208 "brmi 0f", &msb, plen, 2);
7214 for (i = 0; i < n_bytes; i++)
7216 /* We operate byte-wise on the destination. */
7217 rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
7218 rtx xval8 = simplify_gen_subreg (QImode, xval, imode, i);
7220 /* 8-bit value to operate with this byte. */
7221 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
7223 /* Registers R16..R31 can operate with immediate. */
7224 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
7227 op[1] = gen_int_mode (val8, QImode);
7229 /* To get usable cc0 no low-bytes must have been skipped. */
7237 && test_hard_reg_class (ADDW_REGS, reg8))
7239 rtx xval16 = simplify_gen_subreg (HImode, xval, imode, i);
7240 unsigned int val16 = UINTVAL (xval16) & GET_MODE_MASK (HImode);
7242 /* Registers R24, X, Y, Z can use ADIW/SBIW with constants < 64
7243 i.e. operate word-wise. */
7250 avr_asm_len (code == PLUS ? "adiw %0,%1" : "sbiw %0,%1",
7253 if (n_bytes == 2 && PLUS == code)
7265 avr_asm_len (code == PLUS
7266 ? "adc %0,__zero_reg__" : "sbc %0,__zero_reg__",
7270 else if ((val8 == 1 || val8 == 0xff)
7271 && UNKNOWN == code_sat
7273 && i == n_bytes - 1)
7275 avr_asm_len ((code == PLUS) ^ (val8 == 1) ? "dec %0" : "inc %0",
7285 gcc_assert (plen != NULL || (op[2] && REG_P (op[2])));
7287 if (plen != NULL && UNKNOWN != code_sat)
7289 /* This belongs to the x + 0x80 corner case. The code with
7290 ADD instruction is not smaller, thus make this case
7291 expensive so that the caller won't pick it. */
7297 if (clobber_val != (int) val8)
7298 avr_asm_len ("ldi %2,%1", op, plen, 1);
7299 clobber_val = (int) val8;
7301 avr_asm_len (started ? "adc %0,%2" : "add %0,%2", op, plen, 1);
7308 avr_asm_len (started ? "sbci %0,%1" : "subi %0,%1", op, plen, 1);
7311 gcc_assert (plen != NULL || REG_P (op[2]));
7313 if (clobber_val != (int) val8)
7314 avr_asm_len ("ldi %2,%1", op, plen, 1);
7315 clobber_val = (int) val8;
7317 avr_asm_len (started ? "sbc %0,%2" : "sub %0,%2", op, plen, 1);
7329 } /* for all sub-bytes */
7333 if (UNKNOWN == code_sat)
7336 *pcc = (int) CC_CLOBBER;
7338 /* Vanilla addition/subtraction is done. We are left with saturation.
7340 We have to compute A = A <op> B where A is a register and
7341 B is a register or a non-zero compile time constant CONST.
7342 A is register class "r" if unsigned && B is REG. Otherwise, A is in "d".
7343 B stands for the original operand $2 in INSN. In the case of B = CONST,
7344 SIGN in { -1, 1 } is the sign of B. Otherwise, SIGN is 0.
7346 CODE is the instruction flavor we use in the asm sequence to perform <op>.
7350 operation | code | sat if | b is | sat value | case
7351 -----------------+-------+----------+--------------+-----------+-------
7352 + as a + b | add | C == 1 | const, reg | u+ = 0xff | [1u]
7353 + as a - (-b) | sub | C == 0 | const | u+ = 0xff | [2u]
7354 - as a - b | sub | C == 1 | const, reg | u- = 0 | [3u]
7355 - as a + (-b) | add | C == 0 | const | u- = 0 | [4u]
7359 operation | code | sat if | b is | sat value | case
7360 -----------------+-------+----------+--------------+-----------+-------
7361 + as a + b | add | V == 1 | const, reg | s+ | [1s]
7362 + as a - (-b) | sub | V == 1 | const | s+ | [2s]
7363 - as a - b | sub | V == 1 | const, reg | s- | [3s]
7364 - as a + (-b) | add | V == 1 | const | s- | [4s]
7366 s+ = b < 0 ? -0x80 : 0x7f
7367 s- = b < 0 ? 0x7f : -0x80
7369 The cases a - b actually perform a - (-(-b)) if B is CONST.
7372 op[0] = simplify_gen_subreg (QImode, xop[0], mode, n_bytes-1);
7374 ? simplify_gen_subreg (QImode, xop[0], mode, n_bytes-2)
7377 bool need_copy = true;
7378 int len_call = 1 + AVR_HAVE_JMP_CALL;
7389 avr_asm_len ("brvc 0f", op, plen, 1);
7391 if (reg_overlap_mentioned_p (xop[0], xop[2]))
7396 avr_asm_len ("ldi %0,0x7f" CR_TAB
7397 "adc %0,__zero_reg__", op, plen, 2);
7399 avr_asm_len ("ldi %0,0x7f" CR_TAB
7400 "ldi %1,0xff" CR_TAB
7401 "adc %1,__zero_reg__" CR_TAB
7402 "adc %0,__zero_reg__", op, plen, 4);
7404 else if (sign == 0 && PLUS == code)
7408 op[2] = simplify_gen_subreg (QImode, xop[2], mode, n_bytes-1);
7411 avr_asm_len ("ldi %0,0x80" CR_TAB
7413 "dec %0", op, plen, 3);
7415 avr_asm_len ("ldi %0,0x80" CR_TAB
7418 "sbci %0,0", op, plen, 4);
7420 else if (sign == 0 && MINUS == code)
7424 op[2] = simplify_gen_subreg (QImode, xop[2], mode, n_bytes-1);
7427 avr_asm_len ("ldi %0,0x7f" CR_TAB
7429 "inc %0", op, plen, 3);
7431 avr_asm_len ("ldi %0,0x7f" CR_TAB
7434 "sbci %0,-1", op, plen, 4);
7436 else if ((sign < 0) ^ (SS_MINUS == code_sat))
7438 /* [1s,const,B < 0] [2s,B < 0] */
7439 /* [3s,const,B > 0] [4s,B > 0] */
7443 avr_asm_len ("%~call __clr_8", op, plen, len_call);
7447 avr_asm_len ("ldi %0,0x80", op, plen, 1);
7448 if (n_bytes > 1 && need_copy)
7449 avr_asm_len ("clr %1", op, plen, 1);
7451 else if ((sign > 0) ^ (SS_MINUS == code_sat))
7453 /* [1s,const,B > 0] [2s,B > 0] */
7454 /* [3s,const,B < 0] [4s,B < 0] */
7458 avr_asm_len ("sec" CR_TAB
7459 "%~call __sbc_8", op, plen, 1 + len_call);
7463 avr_asm_len ("ldi %0,0x7f", op, plen, 1);
7464 if (n_bytes > 1 && need_copy)
7465 avr_asm_len ("ldi %1,0xff", op, plen, 1);
7475 avr_asm_len (PLUS == code ? "brcc 0f" : "brcs 0f", op, plen, 1);
7480 avr_asm_len ("sec", op, plen, 1);
7481 avr_asm_len ("%~call __sbc_8", op, plen, len_call);
7487 if (MINUS == code && !test_hard_reg_class (LD_REGS, op[0]))
7488 avr_asm_len ("sec" CR_TAB
7489 "sbc %0,%0", op, plen, 2);
7491 avr_asm_len (PLUS == code ? "sbc %0,%0" : "ldi %0,0xff",
7494 break; /* US_PLUS */
7499 avr_asm_len (PLUS == code ? "brcs 0f" : "brcc 0f", op, plen, 1);
7503 avr_asm_len ("%~call __clr_8", op, plen, len_call);
7507 avr_asm_len ("clr %0", op, plen, 1);
7512 /* We set the MSB in the unsigned case and the 2 MSBs in the signed case.
7513 Now copy the right value to the LSBs. */
7515 if (need_copy && n_bytes > 1)
7517 if (US_MINUS == code_sat || US_PLUS == code_sat)
7519 avr_asm_len ("mov %1,%0", op, plen, 1);
7525 avr_asm_len ("movw %0,%1", op, plen, 1);
7527 avr_asm_len ("mov %A0,%1" CR_TAB
7528 "mov %B0,%1", op, plen, 2);
7531 else if (n_bytes > 2)
7534 avr_asm_len ("mov %A0,%1" CR_TAB
7535 "mov %B0,%1", op, plen, 2);
7539 if (need_copy && n_bytes == 8)
7542 avr_asm_len ("movw %r0+2,%0" CR_TAB
7543 "movw %r0+4,%0", xop, plen, 2);
7545 avr_asm_len ("mov %r0+2,%0" CR_TAB
7546 "mov %r0+3,%0" CR_TAB
7547 "mov %r0+4,%0" CR_TAB
7548 "mov %r0+5,%0", xop, plen, 4);
7552 avr_asm_len ("0:", op, plen, 0);
7556 /* Output addition/subtraction of register XOP[0] and a constant XOP[2] that
7557 is ont a compile-time constant:
7559 XOP[0] = XOP[0] +/- XOP[2]
7561 This is a helper for the function below. The only insns that need this
7562 are additions/subtraction for pointer modes, i.e. HImode and PSImode. */
7565 avr_out_plus_symbol (rtx *xop, enum rtx_code code, int *plen, int *pcc)
7567 machine_mode mode = GET_MODE (xop[0]);
7569 /* Only pointer modes want to add symbols. */
7571 gcc_assert (mode == HImode || mode == PSImode);
7573 *pcc = MINUS == code ? (int) CC_SET_CZN : (int) CC_SET_N;
7575 avr_asm_len (PLUS == code
7576 ? "subi %A0,lo8(-(%2))" CR_TAB "sbci %B0,hi8(-(%2))"
7577 : "subi %A0,lo8(%2)" CR_TAB "sbci %B0,hi8(%2)",
7580 if (PSImode == mode)
7581 avr_asm_len (PLUS == code
7582 ? "sbci %C0,hlo8(-(%2))"
7583 : "sbci %C0,hlo8(%2)", xop, plen, 1);
7588 /* Prepare operands of addition/subtraction to be used with avr_out_plus_1.
7590 INSN is a single_set insn or an insn pattern with a binary operation as
7591 SET_SRC that is one of: PLUS, SS_PLUS, US_PLUS, MINUS, SS_MINUS, US_MINUS.
7593 XOP are the operands of INSN. In the case of 64-bit operations with
7594 constant XOP[] has just one element: The summand/subtrahend in XOP[0].
7595 The non-saturating insns up to 32 bits may or may not supply a "d" class
7598 If PLEN == NULL output the instructions.
7599 If PLEN != NULL set *PLEN to the length of the sequence in words.
7601 PCC is a pointer to store the instructions' effect on cc0.
7604 PLEN and PCC default to NULL.
7606 OUT_LABEL defaults to TRUE. For a description, see AVR_OUT_PLUS_1.
7611 avr_out_plus (rtx insn, rtx *xop, int *plen, int *pcc, bool out_label)
7613 int cc_plus, cc_minus, cc_dummy;
7614 int len_plus, len_minus;
7616 rtx xpattern = INSN_P (insn) ? single_set (as_a <rtx_insn *> (insn)) : insn;
7617 rtx xdest = SET_DEST (xpattern);
7618 machine_mode mode = GET_MODE (xdest);
7619 machine_mode imode = int_mode_for_mode (mode);
7620 int n_bytes = GET_MODE_SIZE (mode);
7621 enum rtx_code code_sat = GET_CODE (SET_SRC (xpattern));
7623 = (PLUS == code_sat || SS_PLUS == code_sat || US_PLUS == code_sat
7629 /* PLUS and MINUS don't saturate: Use modular wrap-around. */
7631 if (PLUS == code_sat || MINUS == code_sat)
7634 if (n_bytes <= 4 && REG_P (xop[2]))
7636 avr_out_plus_1 (xop, plen, code, pcc, code_sat, 0, out_label);
7642 op[0] = gen_rtx_REG (DImode, ACC_A);
7643 op[1] = gen_rtx_REG (DImode, ACC_A);
7644 op[2] = avr_to_int_mode (xop[0]);
7649 && !CONST_INT_P (xop[2])
7650 && !CONST_FIXED_P (xop[2]))
7652 return avr_out_plus_symbol (xop, code, plen, pcc);
7655 op[0] = avr_to_int_mode (xop[0]);
7656 op[1] = avr_to_int_mode (xop[1]);
7657 op[2] = avr_to_int_mode (xop[2]);
7660 /* Saturations and 64-bit operations don't have a clobber operand.
7661 For the other cases, the caller will provide a proper XOP[3]. */
7663 xpattern = INSN_P (insn) ? PATTERN (insn) : insn;
7664 op[3] = PARALLEL == GET_CODE (xpattern) ? xop[3] : NULL_RTX;
7666 /* Saturation will need the sign of the original operand. */
7668 rtx xmsb = simplify_gen_subreg (QImode, op[2], imode, n_bytes-1);
7669 int sign = INTVAL (xmsb) < 0 ? -1 : 1;
7671 /* If we subtract and the subtrahend is a constant, then negate it
7672 so that avr_out_plus_1 can be used. */
7675 op[2] = simplify_unary_operation (NEG, imode, op[2], imode);
7677 /* Work out the shortest sequence. */
7679 avr_out_plus_1 (op, &len_minus, MINUS, &cc_minus, code_sat, sign, out_label);
7680 avr_out_plus_1 (op, &len_plus, PLUS, &cc_plus, code_sat, sign, out_label);
7684 *plen = (len_minus <= len_plus) ? len_minus : len_plus;
7685 *pcc = (len_minus <= len_plus) ? cc_minus : cc_plus;
7687 else if (len_minus <= len_plus)
7688 avr_out_plus_1 (op, NULL, MINUS, pcc, code_sat, sign, out_label);
7690 avr_out_plus_1 (op, NULL, PLUS, pcc, code_sat, sign, out_label);
7696 /* Output bit operation (IOR, AND, XOR) with register XOP[0] and compile
7697 time constant XOP[2]:
7699 XOP[0] = XOP[0] <op> XOP[2]
7701 and return "". If PLEN == NULL, print assembler instructions to perform the
7702 operation; otherwise, set *PLEN to the length of the instruction sequence
7703 (in words) printed with PLEN == NULL. XOP[3] is either an 8-bit clobber
7704 register or SCRATCH if no clobber register is needed for the operation.
7705 INSN is an INSN_P or a pattern of an insn. */
7708 avr_out_bitop (rtx insn, rtx *xop, int *plen)
7710 /* CODE and MODE of the operation. */
7711 rtx xpattern = INSN_P (insn) ? single_set (as_a <rtx_insn *> (insn)) : insn;
7712 enum rtx_code code = GET_CODE (SET_SRC (xpattern));
7713 machine_mode mode = GET_MODE (xop[0]);
7715 /* Number of bytes to operate on. */
7716 int i, n_bytes = GET_MODE_SIZE (mode);
7718 /* Value of T-flag (0 or 1) or -1 if unknow. */
7721 /* Value (0..0xff) held in clobber register op[3] or -1 if unknown. */
7722 int clobber_val = -1;
7724 /* op[0]: 8-bit destination register
7725 op[1]: 8-bit const int
7726 op[2]: 8-bit clobber register or SCRATCH
7727 op[3]: 8-bit register containing 0xff or NULL_RTX */
7736 for (i = 0; i < n_bytes; i++)
7738 /* We operate byte-wise on the destination. */
7739 rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
7740 rtx xval8 = simplify_gen_subreg (QImode, xop[2], mode, i);
7742 /* 8-bit value to operate with this byte. */
7743 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
7745 /* Number of bits set in the current byte of the constant. */
7746 int pop8 = avr_popcount (val8);
7748 /* Registers R16..R31 can operate with immediate. */
7749 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
7752 op[1] = GEN_INT (val8);
7761 avr_asm_len ("ori %0,%1", op, plen, 1);
7765 avr_asm_len ("set", op, plen, 1);
7768 op[1] = GEN_INT (exact_log2 (val8));
7769 avr_asm_len ("bld %0,%1", op, plen, 1);
7773 if (op[3] != NULL_RTX)
7774 avr_asm_len ("mov %0,%3", op, plen, 1);
7776 avr_asm_len ("clr %0" CR_TAB
7777 "dec %0", op, plen, 2);
7783 if (clobber_val != (int) val8)
7784 avr_asm_len ("ldi %2,%1", op, plen, 1);
7785 clobber_val = (int) val8;
7787 avr_asm_len ("or %0,%2", op, plen, 1);
7797 avr_asm_len ("clr %0", op, plen, 1);
7799 avr_asm_len ("andi %0,%1", op, plen, 1);
7803 avr_asm_len ("clt", op, plen, 1);
7806 op[1] = GEN_INT (exact_log2 (GET_MODE_MASK (QImode) & ~val8));
7807 avr_asm_len ("bld %0,%1", op, plen, 1);
7811 if (clobber_val != (int) val8)
7812 avr_asm_len ("ldi %2,%1", op, plen, 1);
7813 clobber_val = (int) val8;
7815 avr_asm_len ("and %0,%2", op, plen, 1);
7825 avr_asm_len ("com %0", op, plen, 1);
7826 else if (ld_reg_p && val8 == (1 << 7))
7827 avr_asm_len ("subi %0,%1", op, plen, 1);
7830 if (clobber_val != (int) val8)
7831 avr_asm_len ("ldi %2,%1", op, plen, 1);
7832 clobber_val = (int) val8;
7834 avr_asm_len ("eor %0,%2", op, plen, 1);
7840 /* Unknown rtx_code */
7843 } /* for all sub-bytes */
7849 /* Output sign extension from XOP[1] to XOP[0] and return "".
7850 If PLEN == NULL, print assembler instructions to perform the operation;
7851 otherwise, set *PLEN to the length of the instruction sequence (in words)
7852 as printed with PLEN == NULL. */
7855 avr_out_sign_extend (rtx_insn *insn, rtx *xop, int *plen)
7857 // Size in bytes of source resp. destination operand.
7858 unsigned n_src = GET_MODE_SIZE (GET_MODE (xop[1]));
7859 unsigned n_dest = GET_MODE_SIZE (GET_MODE (xop[0]));
7860 rtx r_msb = all_regs_rtx[REGNO (xop[1]) + n_src - 1];
7865 // Copy destination to source
7867 if (REGNO (xop[0]) != REGNO (xop[1]))
7869 gcc_assert (n_src <= 2);
7872 avr_asm_len (AVR_HAVE_MOVW
7874 : "mov %B0,%B1", xop, plen, 1);
7875 if (n_src == 1 || !AVR_HAVE_MOVW)
7876 avr_asm_len ("mov %A0,%A1", xop, plen, 1);
7879 // Set Carry to the sign bit MSB.7...
7881 if (REGNO (xop[0]) == REGNO (xop[1])
7882 || !reg_unused_after (insn, r_msb))
7884 avr_asm_len ("mov __tmp_reg__,%0", &r_msb, plen, 1);
7885 r_msb = tmp_reg_rtx;
7888 avr_asm_len ("lsl %0", &r_msb, plen, 1);
7890 // ...and propagate it to all the new sign bits
7892 for (unsigned n = n_src; n < n_dest; n++)
7893 avr_asm_len ("sbc %0,%0", &all_regs_rtx[REGNO (xop[0]) + n], plen, 1);
7899 /* PLEN == NULL: Output code to add CONST_INT OP[0] to SP.
7900 PLEN != NULL: Set *PLEN to the length of that sequence.
7904 avr_out_addto_sp (rtx *op, int *plen)
7906 int pc_len = AVR_2_BYTE_PC ? 2 : 3;
7907 int addend = INTVAL (op[0]);
7914 if (flag_verbose_asm || flag_print_asm_name)
7915 avr_asm_len (ASM_COMMENT_START "SP -= %n0", op, plen, 0);
7917 while (addend <= -pc_len)
7920 avr_asm_len ("rcall .", op, plen, 1);
7923 while (addend++ < 0)
7924 avr_asm_len ("push __zero_reg__", op, plen, 1);
7926 else if (addend > 0)
7928 if (flag_verbose_asm || flag_print_asm_name)
7929 avr_asm_len (ASM_COMMENT_START "SP += %0", op, plen, 0);
7931 while (addend-- > 0)
7932 avr_asm_len ("pop __tmp_reg__", op, plen, 1);
7939 /* Outputs instructions needed for fixed point type conversion.
7940 This includes converting between any fixed point type, as well
7941 as converting to any integer type. Conversion between integer
7942 types is not supported.
7944 Converting signed fractional types requires a bit shift if converting
7945 to or from any unsigned fractional type because the decimal place is
7946 shifted by 1 bit. When the destination is a signed fractional, the sign
7947 is stored in either the carry or T bit. */
7950 avr_out_fract (rtx_insn *insn, rtx operands[], bool intsigned, int *plen)
7954 RTX_CODE shift = UNKNOWN;
7955 bool sign_in_carry = false;
7956 bool msb_in_carry = false;
7957 bool lsb_in_tmp_reg = false;
7958 bool lsb_in_carry = false;
7959 bool frac_rounded = false;
7960 const char *code_ashift = "lsl %0";
7963 #define MAY_CLOBBER(RR) \
7964 /* Shorthand used below. */ \
7966 && IN_RANGE (RR, dest.regno_msb - sign_bytes + 1, dest.regno_msb)) \
7967 || (offset && IN_RANGE (RR, dest.regno, dest.regno_msb)) \
7968 || (reg_unused_after (insn, all_regs_rtx[RR]) \
7969 && !IN_RANGE (RR, dest.regno, dest.regno_msb)))
7973 /* bytes : Length of operand in bytes.
7974 ibyte : Length of integral part in bytes.
7975 fbyte, fbit : Length of fractional part in bytes, bits. */
7978 unsigned fbit, bytes, ibyte, fbyte;
7979 unsigned regno, regno_msb;
7980 } dest, src, *val[2] = { &dest, &src };
7985 /* Step 0: Determine information on source and destination operand we
7986 ====== will need in the remainder. */
7988 for (i = 0; i < sizeof (val) / sizeof (*val); i++)
7992 xop[i] = operands[i];
7994 mode = GET_MODE (xop[i]);
7996 val[i]->bytes = GET_MODE_SIZE (mode);
7997 val[i]->regno = REGNO (xop[i]);
7998 val[i]->regno_msb = REGNO (xop[i]) + val[i]->bytes - 1;
8000 if (SCALAR_INT_MODE_P (mode))
8002 val[i]->sbit = intsigned;
8005 else if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
8007 val[i]->sbit = SIGNED_SCALAR_FIXED_POINT_MODE_P (mode);
8008 val[i]->fbit = GET_MODE_FBIT (mode);
8011 fatal_insn ("unsupported fixed-point conversion", insn);
8013 val[i]->fbyte = (1 + val[i]->fbit) / BITS_PER_UNIT;
8014 val[i]->ibyte = val[i]->bytes - val[i]->fbyte;
8017 // Byte offset of the decimal point taking into account different place
8018 // of the decimal point in input and output and different register numbers
8019 // of input and output.
8020 int offset = dest.regno - src.regno + dest.fbyte - src.fbyte;
8022 // Number of destination bytes that will come from sign / zero extension.
8023 int sign_bytes = (dest.ibyte - src.ibyte) * (dest.ibyte > src.ibyte);
8025 // Number of bytes at the low end to be filled with zeros.
8026 int zero_bytes = (dest.fbyte - src.fbyte) * (dest.fbyte > src.fbyte);
8028 // Do we have a 16-Bit register that is cleared?
8029 rtx clrw = NULL_RTX;
8031 bool sign_extend = src.sbit && sign_bytes;
8033 if (0 == dest.fbit % 8 && 7 == src.fbit % 8)
8035 else if (7 == dest.fbit % 8 && 0 == src.fbit % 8)
8037 else if (dest.fbit % 8 == src.fbit % 8)
8042 /* If we need to round the fraction part, we might need to save/round it
8043 before clobbering any of it in Step 1. Also, we might want to do
8044 the rounding now to make use of LD_REGS. */
8045 if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
8046 && SCALAR_ACCUM_MODE_P (GET_MODE (xop[1]))
8047 && !TARGET_FRACT_CONV_TRUNC)
8051 (offset ? dest.regno_msb - sign_bytes : dest.regno + zero_bytes - 1)
8052 && dest.regno - offset -1 >= dest.regno);
8053 unsigned s0 = dest.regno - offset -1;
8054 bool use_src = true;
8056 unsigned copied_msb = src.regno_msb;
8057 bool have_carry = false;
8059 if (src.ibyte > dest.ibyte)
8060 copied_msb -= src.ibyte - dest.ibyte;
8062 for (sn = s0; sn <= copied_msb; sn++)
8063 if (!IN_RANGE (sn, dest.regno, dest.regno_msb)
8064 && !reg_unused_after (insn, all_regs_rtx[sn]))
8066 if (use_src && TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], s0))
8068 avr_asm_len ("tst %0" CR_TAB "brpl 0f",
8069 &all_regs_rtx[src.regno_msb], plen, 2);
8073 if (TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], sn))
8074 avr_asm_len ("cpi %0,1", &all_regs_rtx[sn], plen, 1);
8076 avr_asm_len ("sec" CR_TAB
8077 "cpc %0,__zero_reg__",
8078 &all_regs_rtx[sn], plen, 2);
8082 avr_asm_len ("cpc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
8084 avr_asm_len (have_carry ? "sbci %0,128" : "subi %0,129",
8085 &all_regs_rtx[s0], plen, 1);
8086 for (sn = src.regno + src.fbyte; sn <= copied_msb; sn++)
8087 avr_asm_len ("sbci %0,255", &all_regs_rtx[sn], plen, 1);
8088 avr_asm_len ("\n0:", NULL, plen, 0);
8089 frac_rounded = true;
8091 else if (use_src && overlap)
8093 avr_asm_len ("clr __tmp_reg__" CR_TAB
8095 "dec __tmp_reg__", xop, plen, 1);
8099 avr_asm_len ("add %0,__tmp_reg__", &all_regs_rtx[sn], plen, 1);
8104 avr_asm_len ("adc %0,__tmp_reg__", &all_regs_rtx[sn], plen, 1);
8107 avr_asm_len ("clt" CR_TAB
8108 "bld __tmp_reg__,7" CR_TAB
8109 "adc %0,__tmp_reg__",
8110 &all_regs_rtx[s0], plen, 1);
8112 avr_asm_len ("lsr __tmp_reg" CR_TAB
8113 "add %0,__tmp_reg__",
8114 &all_regs_rtx[s0], plen, 2);
8115 for (sn = src.regno + src.fbyte; sn <= copied_msb; sn++)
8116 avr_asm_len ("adc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
8117 frac_rounded = true;
8122 = (TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], s0)
8123 && (IN_RANGE (s0, dest.regno, dest.regno_msb)
8124 || reg_unused_after (insn, all_regs_rtx[s0])));
8125 xop[2] = all_regs_rtx[s0];
8126 unsigned sn = src.regno;
8127 if (!use_src || sn == s0)
8128 avr_asm_len ("mov __tmp_reg__,%2", xop, plen, 1);
8129 /* We need to consider to-be-discarded bits
8130 if the value is negative. */
8133 avr_asm_len ("tst %0" CR_TAB
8135 &all_regs_rtx[src.regno_msb], plen, 2);
8136 /* Test to-be-discarded bytes for any nozero bits.
8137 ??? Could use OR or SBIW to test two registers at once. */
8139 avr_asm_len ("cp %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
8142 avr_asm_len ("cpc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
8143 /* Set bit 0 in __tmp_reg__ if any of the lower bits was set. */
8145 avr_asm_len ("breq 0f" CR_TAB
8147 "\n0:\t" "mov __tmp_reg__,%2",
8150 avr_asm_len ("breq 0f" CR_TAB
8152 "bld __tmp_reg__,0\n0:",
8155 lsb_in_tmp_reg = true;
8159 /* Step 1: Clear bytes at the low end and copy payload bits from source
8160 ====== to destination. */
8162 int step = offset < 0 ? 1 : -1;
8163 unsigned d0 = offset < 0 ? dest.regno : dest.regno_msb;
8165 // We cleared at least that number of registers.
8168 for (; d0 >= dest.regno && d0 <= dest.regno_msb; d0 += step)
8170 // Next regno of destination is needed for MOVW
8171 unsigned d1 = d0 + step;
8173 // Current and next regno of source
8174 signed s0 = d0 - offset;
8175 signed s1 = s0 + step;
8177 // Must current resp. next regno be CLRed? This applies to the low
8178 // bytes of the destination that have no associated source bytes.
8179 bool clr0 = s0 < (signed) src.regno;
8180 bool clr1 = s1 < (signed) src.regno && d1 >= dest.regno;
8182 // First gather what code to emit (if any) and additional step to
8183 // apply if a MOVW is in use. xop[2] is destination rtx and xop[3]
8184 // is the source rtx for the current loop iteration.
8185 const char *code = NULL;
8190 if (AVR_HAVE_MOVW && clr1 && clrw)
8192 xop[2] = all_regs_rtx[d0 & ~1];
8194 code = "movw %2,%3";
8199 xop[2] = all_regs_rtx[d0];
8204 && d0 % 2 == (step > 0))
8206 clrw = all_regs_rtx[d0 & ~1];
8210 else if (offset && s0 <= (signed) src.regno_msb)
8212 int movw = AVR_HAVE_MOVW && offset % 2 == 0
8213 && d0 % 2 == (offset > 0)
8214 && d1 <= dest.regno_msb && d1 >= dest.regno
8215 && s1 <= (signed) src.regno_msb && s1 >= (signed) src.regno;
8217 xop[2] = all_regs_rtx[d0 & ~movw];
8218 xop[3] = all_regs_rtx[s0 & ~movw];
8219 code = movw ? "movw %2,%3" : "mov %2,%3";
8220 stepw = step * movw;
8225 if (sign_extend && shift != ASHIFT && !sign_in_carry
8226 && (d0 == src.regno_msb || d0 + stepw == src.regno_msb))
8228 /* We are going to override the sign bit. If we sign-extend,
8229 store the sign in the Carry flag. This is not needed if
8230 the destination will be ASHIFT in the remainder because
8231 the ASHIFT will set Carry without extra instruction. */
8233 avr_asm_len ("lsl %0", &all_regs_rtx[src.regno_msb], plen, 1);
8234 sign_in_carry = true;
8237 unsigned src_msb = dest.regno_msb - sign_bytes - offset + 1;
8239 if (!sign_extend && shift == ASHIFTRT && !msb_in_carry
8240 && src.ibyte > dest.ibyte
8241 && (d0 == src_msb || d0 + stepw == src_msb))
8243 /* We are going to override the MSB. If we shift right,
8244 store the MSB in the Carry flag. This is only needed if
8245 we don't sign-extend becaue with sign-extension the MSB
8246 (the sign) will be produced by the sign extension. */
8248 avr_asm_len ("lsr %0", &all_regs_rtx[src_msb], plen, 1);
8249 msb_in_carry = true;
8252 unsigned src_lsb = dest.regno - offset -1;
8254 if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry
8256 && (d0 == src_lsb || d0 + stepw == src_lsb))
8258 /* We are going to override the new LSB; store it into carry. */
8260 avr_asm_len ("lsl %0", &all_regs_rtx[src_lsb], plen, 1);
8261 code_ashift = "rol %0";
8262 lsb_in_carry = true;
8265 avr_asm_len (code, xop, plen, 1);
8270 /* Step 2: Shift destination left by 1 bit position. This might be needed
8271 ====== for signed input and unsigned output. */
8273 if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry)
8275 unsigned s0 = dest.regno - offset -1;
8277 /* n1169 4.1.4 says:
8278 "Conversions from a fixed-point to an integer type round toward zero."
8279 Hence, converting a fract type to integer only gives a non-zero result
8281 if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
8282 && SCALAR_FRACT_MODE_P (GET_MODE (xop[1]))
8283 && !TARGET_FRACT_CONV_TRUNC)
8285 gcc_assert (s0 == src.regno_msb);
8286 /* Check if the input is -1. We do that by checking if negating
8287 the input causes an integer overflow. */
8288 unsigned sn = src.regno;
8289 avr_asm_len ("cp __zero_reg__,%0", &all_regs_rtx[sn++], plen, 1);
8291 avr_asm_len ("cpc __zero_reg__,%0", &all_regs_rtx[sn++], plen, 1);
8293 /* Overflow goes with set carry. Clear carry otherwise. */
8294 avr_asm_len ("brvs 0f" CR_TAB
8295 "clc\n0:", NULL, plen, 2);
8297 /* Likewise, when converting from accumulator types to integer, we
8298 need to round up negative values. */
8299 else if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
8300 && SCALAR_ACCUM_MODE_P (GET_MODE (xop[1]))
8301 && !TARGET_FRACT_CONV_TRUNC
8304 bool have_carry = false;
8306 xop[2] = all_regs_rtx[s0];
8307 if (!lsb_in_tmp_reg && !MAY_CLOBBER (s0))
8308 avr_asm_len ("mov __tmp_reg__,%2", xop, plen, 1);
8309 avr_asm_len ("tst %0" CR_TAB "brpl 0f",
8310 &all_regs_rtx[src.regno_msb], plen, 2);
8311 if (!lsb_in_tmp_reg)
8313 unsigned sn = src.regno;
8316 avr_asm_len ("cp __zero_reg__,%0", &all_regs_rtx[sn],
8321 avr_asm_len ("cpc __zero_reg__,%0", &all_regs_rtx[sn], plen, 1);
8322 lsb_in_tmp_reg = !MAY_CLOBBER (s0);
8324 /* Add in C and the rounding value 127. */
8325 /* If the destination msb is a sign byte, and in LD_REGS,
8326 grab it as a temporary. */
8328 && TEST_HARD_REG_BIT (reg_class_contents[LD_REGS],
8331 xop[3] = all_regs_rtx[dest.regno_msb];
8332 avr_asm_len ("ldi %3,127", xop, plen, 1);
8333 avr_asm_len ((have_carry && lsb_in_tmp_reg ? "adc __tmp_reg__,%3"
8334 : have_carry ? "adc %2,%3"
8335 : lsb_in_tmp_reg ? "add __tmp_reg__,%3"
8341 /* Fall back to use __zero_reg__ as a temporary. */
8342 avr_asm_len ("dec __zero_reg__", NULL, plen, 1);
8344 avr_asm_len ("clt" CR_TAB
8345 "bld __zero_reg__,7", NULL, plen, 2);
8347 avr_asm_len ("lsr __zero_reg__", NULL, plen, 1);
8348 avr_asm_len (have_carry && lsb_in_tmp_reg
8349 ? "adc __tmp_reg__,__zero_reg__"
8350 : have_carry ? "adc %2,__zero_reg__"
8351 : lsb_in_tmp_reg ? "add __tmp_reg__,__zero_reg__"
8352 : "add %2,__zero_reg__",
8354 avr_asm_len ("eor __zero_reg__,__zero_reg__", NULL, plen, 1);
8357 for (d0 = dest.regno + zero_bytes;
8358 d0 <= dest.regno_msb - sign_bytes; d0++)
8359 avr_asm_len ("adc %0,__zero_reg__", &all_regs_rtx[d0], plen, 1);
8361 avr_asm_len (lsb_in_tmp_reg
8362 ? "\n0:\t" "lsl __tmp_reg__"
8363 : "\n0:\t" "lsl %2",
8366 else if (MAY_CLOBBER (s0))
8367 avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1);
8369 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
8370 "lsl __tmp_reg__", &all_regs_rtx[s0], plen, 2);
8372 code_ashift = "rol %0";
8373 lsb_in_carry = true;
8376 if (shift == ASHIFT)
8378 for (d0 = dest.regno + zero_bytes;
8379 d0 <= dest.regno_msb - sign_bytes; d0++)
8381 avr_asm_len (code_ashift, &all_regs_rtx[d0], plen, 1);
8382 code_ashift = "rol %0";
8385 lsb_in_carry = false;
8386 sign_in_carry = true;
8389 /* Step 4a: Store MSB in carry if we don't already have it or will produce
8390 ======= it in sign-extension below. */
8392 if (!sign_extend && shift == ASHIFTRT && !msb_in_carry
8393 && src.ibyte > dest.ibyte)
8395 unsigned s0 = dest.regno_msb - sign_bytes - offset + 1;
8397 if (MAY_CLOBBER (s0))
8398 avr_asm_len ("lsr %0", &all_regs_rtx[s0], plen, 1);
8400 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
8401 "lsr __tmp_reg__", &all_regs_rtx[s0], plen, 2);
8403 msb_in_carry = true;
8406 /* Step 3: Sign-extend or zero-extend the destination as needed.
8409 if (sign_extend && !sign_in_carry)
8411 unsigned s0 = src.regno_msb;
8413 if (MAY_CLOBBER (s0))
8414 avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1);
8416 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
8417 "lsl __tmp_reg__", &all_regs_rtx[s0], plen, 2);
8419 sign_in_carry = true;
8422 gcc_assert (sign_in_carry + msb_in_carry + lsb_in_carry <= 1);
8424 unsigned copies = 0;
8425 rtx movw = sign_extend ? NULL_RTX : clrw;
8427 for (d0 = dest.regno_msb - sign_bytes + 1; d0 <= dest.regno_msb; d0++)
8429 if (AVR_HAVE_MOVW && movw
8430 && d0 % 2 == 0 && d0 + 1 <= dest.regno_msb)
8432 xop[2] = all_regs_rtx[d0];
8434 avr_asm_len ("movw %2,%3", xop, plen, 1);
8439 avr_asm_len (sign_extend ? "sbc %0,%0" : "clr %0",
8440 &all_regs_rtx[d0], plen, 1);
8442 if (++copies >= 2 && !movw && d0 % 2 == 1)
8443 movw = all_regs_rtx[d0-1];
8448 /* Step 4: Right shift the destination. This might be needed for
8449 ====== conversions from unsigned to signed. */
8451 if (shift == ASHIFTRT)
8453 const char *code_ashiftrt = "lsr %0";
8455 if (sign_extend || msb_in_carry)
8456 code_ashiftrt = "ror %0";
8458 if (src.sbit && src.ibyte == dest.ibyte)
8459 code_ashiftrt = "asr %0";
8461 for (d0 = dest.regno_msb - sign_bytes;
8462 d0 >= dest.regno + zero_bytes - 1 && d0 >= dest.regno; d0--)
8464 avr_asm_len (code_ashiftrt, &all_regs_rtx[d0], plen, 1);
8465 code_ashiftrt = "ror %0";
8475 /* Output fixed-point rounding. XOP[0] = XOP[1] is the operand to round.
8476 XOP[2] is the rounding point, a CONST_INT. The function prints the
8477 instruction sequence if PLEN = NULL and computes the length in words
8478 of the sequence if PLEN != NULL. Most of this function deals with
8479 preparing operands for calls to `avr_out_plus' and `avr_out_bitop'. */
8482 avr_out_round (rtx_insn *insn ATTRIBUTE_UNUSED, rtx *xop, int *plen)
8484 machine_mode mode = GET_MODE (xop[0]);
8485 machine_mode imode = int_mode_for_mode (mode);
8486 // The smallest fractional bit not cleared by the rounding is 2^(-RP).
8487 int fbit = (int) GET_MODE_FBIT (mode);
8488 double_int i_add = double_int_zero.set_bit (fbit-1 - INTVAL (xop[2]));
8489 wide_int wi_add = wi::set_bit_in_zero (fbit-1 - INTVAL (xop[2]),
8490 GET_MODE_PRECISION (imode));
8491 // Lengths of PLUS and AND parts.
8492 int len_add = 0, *plen_add = plen ? &len_add : NULL;
8493 int len_and = 0, *plen_and = plen ? &len_and : NULL;
8495 // Add-Saturate 1/2 * 2^(-RP). Don't print the label "0:" when printing
8496 // the saturated addition so that we can emit the "rjmp 1f" before the
8499 rtx xadd = const_fixed_from_double_int (i_add, mode);
8500 rtx xpattern, xsrc, op[4];
8502 xsrc = SIGNED_FIXED_POINT_MODE_P (mode)
8503 ? gen_rtx_SS_PLUS (mode, xop[1], xadd)
8504 : gen_rtx_US_PLUS (mode, xop[1], xadd);
8505 xpattern = gen_rtx_SET (xop[0], xsrc);
8510 avr_out_plus (xpattern, op, plen_add, NULL, false /* Don't print "0:" */);
8512 avr_asm_len ("rjmp 1f" CR_TAB
8513 "0:", NULL, plen_add, 1);
8515 // Keep all bits from RP and higher: ... 2^(-RP)
8516 // Clear all bits from RP+1 and lower: 2^(-RP-1) ...
8517 // Rounding point ^^^^^^^
8518 // Added above ^^^^^^^^^
8519 rtx xreg = simplify_gen_subreg (imode, xop[0], mode, 0);
8520 rtx xmask = immed_wide_int_const (-wi_add - wi_add, imode);
8522 xpattern = gen_rtx_SET (xreg, gen_rtx_AND (imode, xreg, xmask));
8527 op[3] = gen_rtx_SCRATCH (QImode);
8528 avr_out_bitop (xpattern, op, plen_and);
8529 avr_asm_len ("1:", NULL, plen, 0);
8532 *plen = len_add + len_and;
8538 /* Create RTL split patterns for byte sized rotate expressions. This
8539 produces a series of move instructions and considers overlap situations.
8540 Overlapping non-HImode operands need a scratch register. */
8543 avr_rotate_bytes (rtx operands[])
8546 machine_mode mode = GET_MODE (operands[0]);
8547 bool overlapped = reg_overlap_mentioned_p (operands[0], operands[1]);
8548 bool same_reg = rtx_equal_p (operands[0], operands[1]);
8549 int num = INTVAL (operands[2]);
8550 rtx scratch = operands[3];
8551 /* Work out if byte or word move is needed. Odd byte rotates need QImode.
8552 Word move if no scratch is needed, otherwise use size of scratch. */
8553 machine_mode move_mode = QImode;
8554 int move_size, offset, size;
8558 else if ((mode == SImode && !same_reg) || !overlapped)
8561 move_mode = GET_MODE (scratch);
8563 /* Force DI rotate to use QI moves since other DI moves are currently split
8564 into QI moves so forward propagation works better. */
8567 /* Make scratch smaller if needed. */
8568 if (SCRATCH != GET_CODE (scratch)
8569 && HImode == GET_MODE (scratch)
8570 && QImode == move_mode)
8571 scratch = simplify_gen_subreg (move_mode, scratch, HImode, 0);
8573 move_size = GET_MODE_SIZE (move_mode);
8574 /* Number of bytes/words to rotate. */
8575 offset = (num >> 3) / move_size;
8576 /* Number of moves needed. */
8577 size = GET_MODE_SIZE (mode) / move_size;
8578 /* Himode byte swap is special case to avoid a scratch register. */
8579 if (mode == HImode && same_reg)
8581 /* HImode byte swap, using xor. This is as quick as using scratch. */
8583 src = simplify_gen_subreg (move_mode, operands[1], mode, 0);
8584 dst = simplify_gen_subreg (move_mode, operands[0], mode, 1);
8585 if (!rtx_equal_p (dst, src))
8587 emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
8588 emit_move_insn (src, gen_rtx_XOR (QImode, src, dst));
8589 emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
8594 #define MAX_SIZE 8 /* GET_MODE_SIZE (DImode) / GET_MODE_SIZE (QImode) */
8595 /* Create linked list of moves to determine move order. */
8599 } move[MAX_SIZE + 8];
8602 gcc_assert (size <= MAX_SIZE);
8603 /* Generate list of subreg moves. */
8604 for (i = 0; i < size; i++)
8607 int to = (from + offset) % size;
8608 move[i].src = simplify_gen_subreg (move_mode, operands[1],
8609 mode, from * move_size);
8610 move[i].dst = simplify_gen_subreg (move_mode, operands[0],
8611 mode, to * move_size);
8614 /* Mark dependence where a dst of one move is the src of another move.
8615 The first move is a conflict as it must wait until second is
8616 performed. We ignore moves to self - we catch this later. */
8618 for (i = 0; i < size; i++)
8619 if (reg_overlap_mentioned_p (move[i].dst, operands[1]))
8620 for (j = 0; j < size; j++)
8621 if (j != i && rtx_equal_p (move[j].src, move[i].dst))
8623 /* The dst of move i is the src of move j. */
8630 /* Go through move list and perform non-conflicting moves. As each
8631 non-overlapping move is made, it may remove other conflicts
8632 so the process is repeated until no conflicts remain. */
8637 /* Emit move where dst is not also a src or we have used that
8639 for (i = 0; i < size; i++)
8640 if (move[i].src != NULL_RTX)
8642 if (move[i].links == -1
8643 || move[move[i].links].src == NULL_RTX)
8646 /* Ignore NOP moves to self. */
8647 if (!rtx_equal_p (move[i].dst, move[i].src))
8648 emit_move_insn (move[i].dst, move[i].src);
8650 /* Remove conflict from list. */
8651 move[i].src = NULL_RTX;
8657 /* Check for deadlock. This is when no moves occurred and we have
8658 at least one blocked move. */
8659 if (moves == 0 && blocked != -1)
8661 /* Need to use scratch register to break deadlock.
8662 Add move to put dst of blocked move into scratch.
8663 When this move occurs, it will break chain deadlock.
8664 The scratch register is substituted for real move. */
8666 gcc_assert (SCRATCH != GET_CODE (scratch));
8668 move[size].src = move[blocked].dst;
8669 move[size].dst = scratch;
8670 /* Scratch move is never blocked. */
8671 move[size].links = -1;
8672 /* Make sure we have valid link. */
8673 gcc_assert (move[blocked].links != -1);
8674 /* Replace src of blocking move with scratch reg. */
8675 move[move[blocked].links].src = scratch;
8676 /* Make dependent on scratch move occurring. */
8677 move[blocked].links = size;
8681 while (blocked != -1);
8687 /* Worker function for `ADJUST_INSN_LENGTH'. */
8688 /* Modifies the length assigned to instruction INSN
8689 LEN is the initially computed length of the insn. */
8692 avr_adjust_insn_length (rtx_insn *insn, int len)
8694 rtx *op = recog_data.operand;
8695 enum attr_adjust_len adjust_len;
8697 /* Some complex insns don't need length adjustment and therefore
8698 the length need not/must not be adjusted for these insns.
8699 It is easier to state this in an insn attribute "adjust_len" than
8700 to clutter up code here... */
8702 if (!NONDEBUG_INSN_P (insn)
8703 || -1 == recog_memoized (insn))
8708 /* Read from insn attribute "adjust_len" if/how length is to be adjusted. */
8710 adjust_len = get_attr_adjust_len (insn);
8712 if (adjust_len == ADJUST_LEN_NO)
8714 /* Nothing to adjust: The length from attribute "length" is fine.
8715 This is the default. */
8720 /* Extract insn's operands. */
8722 extract_constrain_insn_cached (insn);
8724 /* Dispatch to right function. */
8728 case ADJUST_LEN_RELOAD_IN16: output_reload_inhi (op, op[2], &len); break;
8729 case ADJUST_LEN_RELOAD_IN24: avr_out_reload_inpsi (op, op[2], &len); break;
8730 case ADJUST_LEN_RELOAD_IN32: output_reload_insisf (op, op[2], &len); break;
8732 case ADJUST_LEN_OUT_BITOP: avr_out_bitop (insn, op, &len); break;
8734 case ADJUST_LEN_PLUS: avr_out_plus (insn, op, &len); break;
8735 case ADJUST_LEN_ADDTO_SP: avr_out_addto_sp (op, &len); break;
8737 case ADJUST_LEN_MOV8: output_movqi (insn, op, &len); break;
8738 case ADJUST_LEN_MOV16: output_movhi (insn, op, &len); break;
8739 case ADJUST_LEN_MOV24: avr_out_movpsi (insn, op, &len); break;
8740 case ADJUST_LEN_MOV32: output_movsisf (insn, op, &len); break;
8741 case ADJUST_LEN_MOVMEM: avr_out_movmem (insn, op, &len); break;
8742 case ADJUST_LEN_XLOAD: avr_out_xload (insn, op, &len); break;
8743 case ADJUST_LEN_LPM: avr_out_lpm (insn, op, &len); break;
8744 case ADJUST_LEN_SEXT: avr_out_sign_extend (insn, op, &len); break;
8746 case ADJUST_LEN_SFRACT: avr_out_fract (insn, op, true, &len); break;
8747 case ADJUST_LEN_UFRACT: avr_out_fract (insn, op, false, &len); break;
8748 case ADJUST_LEN_ROUND: avr_out_round (insn, op, &len); break;
8750 case ADJUST_LEN_TSTHI: avr_out_tsthi (insn, op, &len); break;
8751 case ADJUST_LEN_TSTPSI: avr_out_tstpsi (insn, op, &len); break;
8752 case ADJUST_LEN_TSTSI: avr_out_tstsi (insn, op, &len); break;
8753 case ADJUST_LEN_COMPARE: avr_out_compare (insn, op, &len); break;
8754 case ADJUST_LEN_COMPARE64: avr_out_compare64 (insn, op, &len); break;
8756 case ADJUST_LEN_LSHRQI: lshrqi3_out (insn, op, &len); break;
8757 case ADJUST_LEN_LSHRHI: lshrhi3_out (insn, op, &len); break;
8758 case ADJUST_LEN_LSHRSI: lshrsi3_out (insn, op, &len); break;
8760 case ADJUST_LEN_ASHRQI: ashrqi3_out (insn, op, &len); break;
8761 case ADJUST_LEN_ASHRHI: ashrhi3_out (insn, op, &len); break;
8762 case ADJUST_LEN_ASHRSI: ashrsi3_out (insn, op, &len); break;
8764 case ADJUST_LEN_ASHLQI: ashlqi3_out (insn, op, &len); break;
8765 case ADJUST_LEN_ASHLHI: ashlhi3_out (insn, op, &len); break;
8766 case ADJUST_LEN_ASHLSI: ashlsi3_out (insn, op, &len); break;
8768 case ADJUST_LEN_ASHLPSI: avr_out_ashlpsi3 (insn, op, &len); break;
8769 case ADJUST_LEN_ASHRPSI: avr_out_ashrpsi3 (insn, op, &len); break;
8770 case ADJUST_LEN_LSHRPSI: avr_out_lshrpsi3 (insn, op, &len); break;
8772 case ADJUST_LEN_CALL: len = AVR_HAVE_JMP_CALL ? 2 : 1; break;
8774 case ADJUST_LEN_INSERT_BITS: avr_out_insert_bits (op, &len); break;
8783 /* Return nonzero if register REG dead after INSN. */
8786 reg_unused_after (rtx_insn *insn, rtx reg)
8788 return (dead_or_set_p (insn, reg)
8789 || (REG_P(reg) && _reg_unused_after (insn, reg)));
8792 /* Return nonzero if REG is not used after INSN.
8793 We assume REG is a reload reg, and therefore does
8794 not live past labels. It may live past calls or jumps though. */
8797 _reg_unused_after (rtx_insn *insn, rtx reg)
8802 /* If the reg is set by this instruction, then it is safe for our
8803 case. Disregard the case where this is a store to memory, since
8804 we are checking a register used in the store address. */
8805 set = single_set (insn);
8806 if (set && GET_CODE (SET_DEST (set)) != MEM
8807 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
8810 while ((insn = NEXT_INSN (insn)))
8813 code = GET_CODE (insn);
8816 /* If this is a label that existed before reload, then the register
8817 if dead here. However, if this is a label added by reorg, then
8818 the register may still be live here. We can't tell the difference,
8819 so we just ignore labels completely. */
8820 if (code == CODE_LABEL)
8828 if (code == JUMP_INSN)
8831 /* If this is a sequence, we must handle them all at once.
8832 We could have for instance a call that sets the target register,
8833 and an insn in a delay slot that uses the register. In this case,
8834 we must return 0. */
8835 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
8837 rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (insn));
8841 for (i = 0; i < seq->len (); i++)
8843 rtx_insn *this_insn = seq->insn (i);
8844 rtx set = single_set (this_insn);
8846 if (CALL_P (this_insn))
8848 else if (JUMP_P (this_insn))
8850 if (INSN_ANNULLED_BRANCH_P (this_insn))
8855 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
8857 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
8859 if (GET_CODE (SET_DEST (set)) != MEM)
8865 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
8870 else if (code == JUMP_INSN)
8874 if (code == CALL_INSN)
8877 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
8878 if (GET_CODE (XEXP (tem, 0)) == USE
8879 && REG_P (XEXP (XEXP (tem, 0), 0))
8880 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
8882 if (call_used_regs[REGNO (reg)])
8886 set = single_set (insn);
8888 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
8890 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
8891 return GET_CODE (SET_DEST (set)) != MEM;
8892 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
8899 /* Implement `TARGET_ASM_INTEGER'. */
8900 /* Target hook for assembling integer objects. The AVR version needs
8901 special handling for references to certain labels. */
8904 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
8906 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
8907 && text_segment_operand (x, VOIDmode))
8909 fputs ("\t.word\tgs(", asm_out_file);
8910 output_addr_const (asm_out_file, x);
8911 fputs (")\n", asm_out_file);
8915 else if (GET_MODE (x) == PSImode)
8917 /* This needs binutils 2.23+, see PR binutils/13503 */
8919 fputs ("\t.byte\tlo8(", asm_out_file);
8920 output_addr_const (asm_out_file, x);
8921 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
8923 fputs ("\t.byte\thi8(", asm_out_file);
8924 output_addr_const (asm_out_file, x);
8925 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
8927 fputs ("\t.byte\thh8(", asm_out_file);
8928 output_addr_const (asm_out_file, x);
8929 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
8933 else if (CONST_FIXED_P (x))
8937 /* varasm fails to handle big fixed modes that don't fit in hwi. */
8939 for (n = 0; n < size; n++)
8941 rtx xn = simplify_gen_subreg (QImode, x, GET_MODE (x), n);
8942 default_assemble_integer (xn, 1, aligned_p);
8948 return default_assemble_integer (x, size, aligned_p);
8952 /* Implement `TARGET_CLASS_LIKELY_SPILLED_P'. */
8953 /* Return value is nonzero if pseudos that have been
8954 assigned to registers of class CLASS would likely be spilled
8955 because registers of CLASS are needed for spill registers. */
8958 avr_class_likely_spilled_p (reg_class_t c)
8960 return (c != ALL_REGS &&
8961 (AVR_TINY ? 1 : c != ADDW_REGS));
8965 /* Valid attributes:
8966 progmem - Put data to program memory.
8967 signal - Make a function to be hardware interrupt.
8968 After function prologue interrupts remain disabled.
8969 interrupt - Make a function to be hardware interrupt. Before function
8970 prologue interrupts are enabled by means of SEI.
8971 naked - Don't generate function prologue/epilogue and RET
8974 /* Handle a "progmem" attribute; arguments as in
8975 struct attribute_spec.handler. */
8978 avr_handle_progmem_attribute (tree *node, tree name,
8979 tree args ATTRIBUTE_UNUSED,
8980 int flags ATTRIBUTE_UNUSED,
8985 if (TREE_CODE (*node) == TYPE_DECL)
8987 /* This is really a decl attribute, not a type attribute,
8988 but try to handle it for GCC 3.0 backwards compatibility. */
8990 tree type = TREE_TYPE (*node);
8991 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
8992 tree newtype = build_type_attribute_variant (type, attr);
8994 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
8995 TREE_TYPE (*node) = newtype;
8996 *no_add_attrs = true;
8998 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
9000 *no_add_attrs = false;
9004 warning (OPT_Wattributes, "%qE attribute ignored",
9006 *no_add_attrs = true;
9013 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
9014 struct attribute_spec.handler. */
9017 avr_handle_fndecl_attribute (tree *node, tree name,
9018 tree args ATTRIBUTE_UNUSED,
9019 int flags ATTRIBUTE_UNUSED,
9022 if (TREE_CODE (*node) != FUNCTION_DECL)
9024 warning (OPT_Wattributes, "%qE attribute only applies to functions",
9026 *no_add_attrs = true;
9033 avr_handle_fntype_attribute (tree *node, tree name,
9034 tree args ATTRIBUTE_UNUSED,
9035 int flags ATTRIBUTE_UNUSED,
9038 if (TREE_CODE (*node) != FUNCTION_TYPE)
9040 warning (OPT_Wattributes, "%qE attribute only applies to functions",
9042 *no_add_attrs = true;
9049 avr_handle_addr_attribute (tree *node, tree name, tree args,
9050 int flags ATTRIBUTE_UNUSED, bool *no_add)
9052 bool io_p = (strncmp (IDENTIFIER_POINTER (name), "io", 2) == 0);
9053 location_t loc = DECL_SOURCE_LOCATION (*node);
9055 if (TREE_CODE (*node) != VAR_DECL)
9057 warning_at (loc, 0, "%qE attribute only applies to variables", name);
9061 if (args != NULL_TREE)
9063 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
9064 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
9065 tree arg = TREE_VALUE (args);
9066 if (TREE_CODE (arg) != INTEGER_CST)
9068 warning (0, "%qE attribute allows only an integer constant argument",
9073 && (!tree_fits_shwi_p (arg)
9074 || !(strcmp (IDENTIFIER_POINTER (name), "io_low") == 0
9075 ? low_io_address_operand : io_address_operand)
9076 (GEN_INT (TREE_INT_CST_LOW (arg)), QImode)))
9078 warning_at (loc, 0, "%qE attribute address out of range", name);
9083 tree attribs = DECL_ATTRIBUTES (*node);
9084 const char *names[] = { "io", "io_low", "address", NULL } ;
9085 for (const char **p = names; *p; p++)
9087 tree other = lookup_attribute (*p, attribs);
9088 if (other && TREE_VALUE (other))
9091 "both %s and %qE attribute provide address",
9100 if (*no_add == false && io_p && !TREE_THIS_VOLATILE (*node))
9101 warning_at (loc, 0, "%qE attribute on non-volatile variable", name);
9107 avr_eval_addr_attrib (rtx x)
9109 if (GET_CODE (x) == SYMBOL_REF
9110 && (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_ADDRESS))
9112 tree decl = SYMBOL_REF_DECL (x);
9113 tree attr = NULL_TREE;
9115 if (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_IO)
9117 attr = lookup_attribute ("io", DECL_ATTRIBUTES (decl));
9118 if (!attr || !TREE_VALUE (attr))
9119 attr = lookup_attribute ("io_low", DECL_ATTRIBUTES (decl));
9122 if (!attr || !TREE_VALUE (attr))
9123 attr = lookup_attribute ("address", DECL_ATTRIBUTES (decl));
9124 gcc_assert (attr && TREE_VALUE (attr) && TREE_VALUE (TREE_VALUE (attr)));
9125 return GEN_INT (TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))));
9131 /* AVR attributes. */
9132 static const struct attribute_spec
9133 avr_attribute_table[] =
9135 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
9136 affects_type_identity } */
9137 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute,
9139 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute,
9141 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute,
9143 { "naked", 0, 0, false, true, true, avr_handle_fntype_attribute,
9145 { "OS_task", 0, 0, false, true, true, avr_handle_fntype_attribute,
9147 { "OS_main", 0, 0, false, true, true, avr_handle_fntype_attribute,
9149 { "io", 0, 1, false, false, false, avr_handle_addr_attribute,
9151 { "io_low", 0, 1, false, false, false, avr_handle_addr_attribute,
9153 { "address", 1, 1, false, false, false, avr_handle_addr_attribute,
9155 { NULL, 0, 0, false, false, false, NULL, false }
9159 /* Look if DECL shall be placed in program memory space by
9160 means of attribute `progmem' or some address-space qualifier.
9161 Return non-zero if DECL is data that must end up in Flash and
9162 zero if the data lives in RAM (.bss, .data, .rodata, ...).
9164 Return 2 if DECL is located in 24-bit flash address-space
9165 Return 1 if DECL is located in 16-bit flash address-space
9166 Return -1 if attribute `progmem' occurs in DECL or ATTRIBUTES
9167 Return 0 otherwise */
9170 avr_progmem_p (tree decl, tree attributes)
9174 if (TREE_CODE (decl) != VAR_DECL)
9177 if (avr_decl_memx_p (decl))
9180 if (avr_decl_flash_p (decl))
9184 != lookup_attribute ("progmem", attributes))
9191 while (TREE_CODE (a) == ARRAY_TYPE);
9193 if (a == error_mark_node)
9196 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
9203 /* Scan type TYP for pointer references to address space ASn.
9204 Return ADDR_SPACE_GENERIC (i.e. 0) if all pointers targeting
9205 the AS are also declared to be CONST.
9206 Otherwise, return the respective address space, i.e. a value != 0. */
9209 avr_nonconst_pointer_addrspace (tree typ)
9211 while (ARRAY_TYPE == TREE_CODE (typ))
9212 typ = TREE_TYPE (typ);
9214 if (POINTER_TYPE_P (typ))
9217 tree target = TREE_TYPE (typ);
9219 /* Pointer to function: Test the function's return type. */
9221 if (FUNCTION_TYPE == TREE_CODE (target))
9222 return avr_nonconst_pointer_addrspace (TREE_TYPE (target));
9224 /* "Ordinary" pointers... */
9226 while (TREE_CODE (target) == ARRAY_TYPE)
9227 target = TREE_TYPE (target);
9229 /* Pointers to non-generic address space must be const.
9230 Refuse address spaces outside the device's flash. */
9232 as = TYPE_ADDR_SPACE (target);
9234 if (!ADDR_SPACE_GENERIC_P (as)
9235 && (!TYPE_READONLY (target)
9236 || avr_addrspace[as].segment >= avr_n_flash
9237 /* Also refuse __memx address space if we can't support it. */
9238 || (!AVR_HAVE_LPM && avr_addrspace[as].pointer_size > 2)))
9243 /* Scan pointer's target type. */
9245 return avr_nonconst_pointer_addrspace (target);
9248 return ADDR_SPACE_GENERIC;
9252 /* Sanity check NODE so that all pointers targeting non-generic address spaces
9253 go along with CONST qualifier. Writing to these address spaces should
9254 be detected and complained about as early as possible. */
9257 avr_pgm_check_var_decl (tree node)
9259 const char *reason = NULL;
9261 addr_space_t as = ADDR_SPACE_GENERIC;
9263 gcc_assert (as == 0);
9265 if (avr_log.progmem)
9266 avr_edump ("%?: %t\n", node);
9268 switch (TREE_CODE (node))
9274 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
9275 reason = "variable";
9279 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
9280 reason = "function parameter";
9284 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
9285 reason = "structure field";
9289 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (TREE_TYPE (node))),
9291 reason = "return type of function";
9295 if (as = avr_nonconst_pointer_addrspace (node), as)
9302 if (avr_addrspace[as].segment >= avr_n_flash)
9305 error ("%qT uses address space %qs beyond flash of %d KiB",
9306 node, avr_addrspace[as].name, 64 * avr_n_flash);
9308 error ("%s %q+D uses address space %qs beyond flash of %d KiB",
9309 reason, node, avr_addrspace[as].name, 64 * avr_n_flash);
9314 error ("pointer targeting address space %qs must be const in %qT",
9315 avr_addrspace[as].name, node);
9317 error ("pointer targeting address space %qs must be const"
9319 avr_addrspace[as].name, reason, node);
9323 return reason == NULL;
9327 /* Add the section attribute if the variable is in progmem. */
9330 avr_insert_attributes (tree node, tree *attributes)
9332 avr_pgm_check_var_decl (node);
9334 if (TREE_CODE (node) == VAR_DECL
9335 && (TREE_STATIC (node) || DECL_EXTERNAL (node))
9336 && avr_progmem_p (node, *attributes))
9341 /* For C++, we have to peel arrays in order to get correct
9342 determination of readonlyness. */
9345 node0 = TREE_TYPE (node0);
9346 while (TREE_CODE (node0) == ARRAY_TYPE);
9348 if (error_mark_node == node0)
9351 as = TYPE_ADDR_SPACE (TREE_TYPE (node));
9353 if (avr_addrspace[as].segment >= avr_n_flash)
9355 error ("variable %q+D located in address space %qs beyond flash "
9356 "of %d KiB", node, avr_addrspace[as].name, 64 * avr_n_flash);
9358 else if (!AVR_HAVE_LPM && avr_addrspace[as].pointer_size > 2)
9360 error ("variable %q+D located in address space %qs"
9361 " which is not supported for architecture %qs",
9362 node, avr_addrspace[as].name, avr_arch->name);
9365 if (!TYPE_READONLY (node0)
9366 && !TREE_READONLY (node))
9368 const char *reason = "__attribute__((progmem))";
9370 if (!ADDR_SPACE_GENERIC_P (as))
9371 reason = avr_addrspace[as].name;
9373 if (avr_log.progmem)
9374 avr_edump ("\n%?: %t\n%t\n", node, node0);
9376 error ("variable %q+D must be const in order to be put into"
9377 " read-only section by means of %qs", node, reason);
9383 /* Implement `ASM_OUTPUT_ALIGNED_DECL_LOCAL'. */
9384 /* Implement `ASM_OUTPUT_ALIGNED_DECL_COMMON'. */
9385 /* Track need of __do_clear_bss. */
9388 avr_asm_output_aligned_decl_common (FILE * stream,
9391 unsigned HOST_WIDE_INT size,
9392 unsigned int align, bool local_p)
9394 rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl);
9397 if (mem != NULL_RTX && MEM_P (mem)
9398 && GET_CODE ((symbol = XEXP (mem, 0))) == SYMBOL_REF
9399 && (SYMBOL_REF_FLAGS (symbol) & (SYMBOL_FLAG_IO | SYMBOL_FLAG_ADDRESS)))
9404 fprintf (stream, "\t.globl\t");
9405 assemble_name (stream, name);
9406 fprintf (stream, "\n");
9408 if (SYMBOL_REF_FLAGS (symbol) & SYMBOL_FLAG_ADDRESS)
9410 assemble_name (stream, name);
9411 fprintf (stream, " = %ld\n",
9412 (long) INTVAL (avr_eval_addr_attrib (symbol)));
9415 error_at (DECL_SOURCE_LOCATION (decl),
9416 "static IO declaration for %q+D needs an address", decl);
9420 /* __gnu_lto_v1 etc. are just markers for the linker injected by toplev.c.
9421 There is no need to trigger __do_clear_bss code for them. */
9423 if (!STR_PREFIX_P (name, "__gnu_lto"))
9424 avr_need_clear_bss_p = true;
9427 ASM_OUTPUT_ALIGNED_LOCAL (stream, name, size, align);
9429 ASM_OUTPUT_ALIGNED_COMMON (stream, name, size, align);
9433 avr_asm_asm_output_aligned_bss (FILE *file, tree decl, const char *name,
9434 unsigned HOST_WIDE_INT size, int align,
9435 void (*default_func)
9436 (FILE *, tree, const char *,
9437 unsigned HOST_WIDE_INT, int))
9439 rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl);
9442 if (mem != NULL_RTX && MEM_P (mem)
9443 && GET_CODE ((symbol = XEXP (mem, 0))) == SYMBOL_REF
9444 && (SYMBOL_REF_FLAGS (symbol) & (SYMBOL_FLAG_IO | SYMBOL_FLAG_ADDRESS)))
9446 if (!(SYMBOL_REF_FLAGS (symbol) & SYMBOL_FLAG_ADDRESS))
9447 error_at (DECL_SOURCE_LOCATION (decl),
9448 "IO definition for %q+D needs an address", decl);
9449 avr_asm_output_aligned_decl_common (file, decl, name, size, align, false);
9452 default_func (file, decl, name, size, align);
9456 /* Unnamed section callback for data_section
9457 to track need of __do_copy_data. */
9460 avr_output_data_section_asm_op (const void *data)
9462 avr_need_copy_data_p = true;
9464 /* Dispatch to default. */
9465 output_section_asm_op (data);
9469 /* Unnamed section callback for bss_section
9470 to track need of __do_clear_bss. */
9473 avr_output_bss_section_asm_op (const void *data)
9475 avr_need_clear_bss_p = true;
9477 /* Dispatch to default. */
9478 output_section_asm_op (data);
9482 /* Unnamed section callback for progmem*.data sections. */
9485 avr_output_progmem_section_asm_op (const void *data)
9487 fprintf (asm_out_file, "\t.section\t%s,\"a\",@progbits\n",
9488 (const char*) data);
9492 /* Implement `TARGET_ASM_INIT_SECTIONS'. */
9495 avr_asm_init_sections (void)
9497 /* Override section callbacks to keep track of `avr_need_clear_bss_p'
9498 resp. `avr_need_copy_data_p'. */
9500 readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
9501 data_section->unnamed.callback = avr_output_data_section_asm_op;
9502 bss_section->unnamed.callback = avr_output_bss_section_asm_op;
9506 /* Implement `TARGET_ASM_NAMED_SECTION'. */
9507 /* Track need of __do_clear_bss, __do_copy_data for named sections. */
9510 avr_asm_named_section (const char *name, unsigned int flags, tree decl)
9512 if (flags & AVR_SECTION_PROGMEM)
9514 addr_space_t as = (flags & AVR_SECTION_PROGMEM) / SECTION_MACH_DEP;
9515 const char *old_prefix = ".rodata";
9516 const char *new_prefix = avr_addrspace[as].section_name;
9518 if (STR_PREFIX_P (name, old_prefix))
9520 const char *sname = ACONCAT ((new_prefix,
9521 name + strlen (old_prefix), NULL));
9522 default_elf_asm_named_section (sname, flags, decl);
9526 default_elf_asm_named_section (new_prefix, flags, decl);
9530 if (!avr_need_copy_data_p)
9531 avr_need_copy_data_p = (STR_PREFIX_P (name, ".data")
9532 || STR_PREFIX_P (name, ".rodata")
9533 || STR_PREFIX_P (name, ".gnu.linkonce.d"));
9535 if (!avr_need_clear_bss_p)
9536 avr_need_clear_bss_p = STR_PREFIX_P (name, ".bss");
9538 default_elf_asm_named_section (name, flags, decl);
9542 /* Implement `TARGET_SECTION_TYPE_FLAGS'. */
9545 avr_section_type_flags (tree decl, const char *name, int reloc)
9547 unsigned int flags = default_section_type_flags (decl, name, reloc);
9549 if (STR_PREFIX_P (name, ".noinit"))
9551 if (decl && TREE_CODE (decl) == VAR_DECL
9552 && DECL_INITIAL (decl) == NULL_TREE)
9553 flags |= SECTION_BSS; /* @nobits */
9555 warning (0, "only uninitialized variables can be placed in the "
9559 if (decl && DECL_P (decl)
9560 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
9562 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
9564 /* Attribute progmem puts data in generic address space.
9565 Set section flags as if it was in __flash to get the right
9566 section prefix in the remainder. */
9568 if (ADDR_SPACE_GENERIC_P (as))
9569 as = ADDR_SPACE_FLASH;
9571 flags |= as * SECTION_MACH_DEP;
9572 flags &= ~SECTION_WRITE;
9573 flags &= ~SECTION_BSS;
9580 /* Implement `TARGET_ENCODE_SECTION_INFO'. */
9583 avr_encode_section_info (tree decl, rtx rtl, int new_decl_p)
9585 /* In avr_handle_progmem_attribute, DECL_INITIAL is not yet
9586 readily available, see PR34734. So we postpone the warning
9587 about uninitialized data in program memory section until here. */
9590 && decl && DECL_P (decl)
9591 && NULL_TREE == DECL_INITIAL (decl)
9592 && !DECL_EXTERNAL (decl)
9593 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
9595 warning (OPT_Wuninitialized,
9596 "uninitialized variable %q+D put into "
9597 "program memory area", decl);
9600 default_encode_section_info (decl, rtl, new_decl_p);
9602 if (decl && DECL_P (decl)
9603 && TREE_CODE (decl) != FUNCTION_DECL
9605 && SYMBOL_REF == GET_CODE (XEXP (rtl, 0)))
9607 rtx sym = XEXP (rtl, 0);
9608 tree type = TREE_TYPE (decl);
9609 tree attr = DECL_ATTRIBUTES (decl);
9610 if (type == error_mark_node)
9613 addr_space_t as = TYPE_ADDR_SPACE (type);
9615 /* PSTR strings are in generic space but located in flash:
9616 patch address space. */
9618 if (-1 == avr_progmem_p (decl, attr))
9619 as = ADDR_SPACE_FLASH;
9621 AVR_SYMBOL_SET_ADDR_SPACE (sym, as);
9623 tree io_low_attr = lookup_attribute ("io_low", attr);
9624 tree io_attr = lookup_attribute ("io", attr);
9627 && TREE_VALUE (io_low_attr) && TREE_VALUE (TREE_VALUE (io_low_attr)))
9628 addr_attr = io_attr;
9630 && TREE_VALUE (io_attr) && TREE_VALUE (TREE_VALUE (io_attr)))
9631 addr_attr = io_attr;
9633 addr_attr = lookup_attribute ("address", attr);
9635 || (io_attr && addr_attr
9636 && low_io_address_operand
9637 (GEN_INT (TREE_INT_CST_LOW
9638 (TREE_VALUE (TREE_VALUE (addr_attr)))), QImode)))
9639 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_IO_LOW;
9640 if (io_attr || io_low_attr)
9641 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_IO;
9642 /* If we have an (io) address attribute specification, but the variable
9643 is external, treat the address as only a tentative definition
9644 to be used to determine if an io port is in the lower range, but
9645 don't use the exact value for constant propagation. */
9646 if (addr_attr && !DECL_EXTERNAL (decl))
9647 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_ADDRESS;
9652 /* Implement `TARGET_ASM_SELECT_SECTION' */
9655 avr_asm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
9657 section * sect = default_elf_select_section (decl, reloc, align);
9659 if (decl && DECL_P (decl)
9660 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
9662 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
9664 /* __progmem__ goes in generic space but shall be allocated to
9667 if (ADDR_SPACE_GENERIC_P (as))
9668 as = ADDR_SPACE_FLASH;
9670 if (sect->common.flags & SECTION_NAMED)
9672 const char * name = sect->named.name;
9673 const char * old_prefix = ".rodata";
9674 const char * new_prefix = avr_addrspace[as].section_name;
9676 if (STR_PREFIX_P (name, old_prefix))
9678 const char *sname = ACONCAT ((new_prefix,
9679 name + strlen (old_prefix), NULL));
9680 return get_section (sname,
9681 sect->common.flags & ~SECTION_DECLARED,
9686 if (!progmem_section[as])
9689 = get_unnamed_section (0, avr_output_progmem_section_asm_op,
9690 avr_addrspace[as].section_name);
9693 return progmem_section[as];
9699 /* Implement `TARGET_ASM_FILE_START'. */
9700 /* Outputs some text at the start of each assembler file. */
9703 avr_file_start (void)
9705 int sfr_offset = avr_arch->sfr_offset;
9707 if (avr_arch->asm_only)
9708 error ("architecture %qs supported for assembler only", avr_mmcu);
9710 default_file_start ();
9712 /* Print I/O addresses of some SFRs used with IN and OUT. */
9715 fprintf (asm_out_file, "__SP_H__ = 0x%02x\n", avr_addr.sp_h - sfr_offset);
9717 fprintf (asm_out_file, "__SP_L__ = 0x%02x\n", avr_addr.sp_l - sfr_offset);
9718 fprintf (asm_out_file, "__SREG__ = 0x%02x\n", avr_addr.sreg - sfr_offset);
9720 fprintf (asm_out_file, "__RAMPZ__ = 0x%02x\n", avr_addr.rampz - sfr_offset);
9722 fprintf (asm_out_file, "__RAMPY__ = 0x%02x\n", avr_addr.rampy - sfr_offset);
9724 fprintf (asm_out_file, "__RAMPX__ = 0x%02x\n", avr_addr.rampx - sfr_offset);
9726 fprintf (asm_out_file, "__RAMPD__ = 0x%02x\n", avr_addr.rampd - sfr_offset);
9727 if (AVR_XMEGA || AVR_TINY)
9728 fprintf (asm_out_file, "__CCP__ = 0x%02x\n", avr_addr.ccp - sfr_offset);
9729 fprintf (asm_out_file, "__tmp_reg__ = %d\n", AVR_TMP_REGNO);
9730 fprintf (asm_out_file, "__zero_reg__ = %d\n", AVR_ZERO_REGNO);
9734 /* Implement `TARGET_ASM_FILE_END'. */
9735 /* Outputs to the stdio stream FILE some
9736 appropriate text to go at the end of an assembler file. */
9741 /* Output these only if there is anything in the
9742 .data* / .rodata* / .gnu.linkonce.* resp. .bss* or COMMON
9743 input section(s) - some code size can be saved by not
9744 linking in the initialization code from libgcc if resp.
9745 sections are empty, see PR18145. */
9747 if (avr_need_copy_data_p)
9748 fputs (".global __do_copy_data\n", asm_out_file);
9750 if (avr_need_clear_bss_p)
9751 fputs (".global __do_clear_bss\n", asm_out_file);
9755 /* Worker function for `ADJUST_REG_ALLOC_ORDER'. */
9756 /* Choose the order in which to allocate hard registers for
9757 pseudo-registers local to a basic block.
9759 Store the desired register order in the array `reg_alloc_order'.
9760 Element 0 should be the register to allocate first; element 1, the
9761 next register; and so on. */
9764 avr_adjust_reg_alloc_order (void)
9767 static const int order_0[] =
9770 18, 19, 20, 21, 22, 23,
9773 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
9777 static const int tiny_order_0[] = {
9787 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
9789 static const int order_1[] =
9791 18, 19, 20, 21, 22, 23, 24, 25,
9794 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
9798 static const int tiny_order_1[] = {
9807 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
9809 static const int order_2[] =
9811 25, 24, 23, 22, 21, 20, 19, 18,
9814 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
9819 /* Select specific register allocation order.
9820 Tiny Core (ATtiny4/5/9/10/20/40) devices have only 16 registers,
9821 so different allocation order should be used. */
9823 const int *order = (TARGET_ORDER_1 ? (AVR_TINY ? tiny_order_1 : order_1)
9824 : TARGET_ORDER_2 ? (AVR_TINY ? tiny_order_0 : order_2)
9825 : (AVR_TINY ? tiny_order_0 : order_0));
9827 for (i = 0; i < ARRAY_SIZE (order_0); ++i)
9828 reg_alloc_order[i] = order[i];
9832 /* Implement `TARGET_REGISTER_MOVE_COST' */
9835 avr_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
9836 reg_class_t from, reg_class_t to)
9838 return (from == STACK_REG ? 6
9839 : to == STACK_REG ? 12
9844 /* Implement `TARGET_MEMORY_MOVE_COST' */
9847 avr_memory_move_cost (machine_mode mode,
9848 reg_class_t rclass ATTRIBUTE_UNUSED,
9849 bool in ATTRIBUTE_UNUSED)
9851 return (mode == QImode ? 2
9852 : mode == HImode ? 4
9853 : mode == SImode ? 8
9854 : mode == SFmode ? 8
9859 /* Mutually recursive subroutine of avr_rtx_cost for calculating the
9860 cost of an RTX operand given its context. X is the rtx of the
9861 operand, MODE is its mode, and OUTER is the rtx_code of this
9862 operand's parent operator. */
9865 avr_operand_rtx_cost (rtx x, machine_mode mode, enum rtx_code outer,
9866 int opno, bool speed)
9868 enum rtx_code code = GET_CODE (x);
9880 return COSTS_N_INSNS (GET_MODE_SIZE (mode));
9887 avr_rtx_costs (x, mode, outer, opno, &total, speed);
9891 /* Worker function for AVR backend's rtx_cost function.
9892 X is rtx expression whose cost is to be calculated.
9893 Return true if the complete cost has been computed.
9894 Return false if subexpressions should be scanned.
9895 In either case, *TOTAL contains the cost result. */
9898 avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code ATTRIBUTE_UNUSED,
9899 int opno ATTRIBUTE_UNUSED, int *total, bool speed)
9901 enum rtx_code code = GET_CODE (x);
9912 /* Immediate constants are as cheap as registers. */
9917 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
9925 *total = COSTS_N_INSNS (1);
9931 *total = COSTS_N_INSNS (2 * GET_MODE_SIZE (mode) - 1);
9937 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9945 *total = COSTS_N_INSNS (1);
9951 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9955 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
9956 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9960 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
9961 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
9962 *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
9967 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
9968 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
9969 *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
9978 && MULT == GET_CODE (XEXP (x, 0))
9979 && register_operand (XEXP (x, 1), QImode))
9982 *total = COSTS_N_INSNS (speed ? 4 : 3);
9983 /* multiply-add with constant: will be split and load constant. */
9984 if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
9985 *total = COSTS_N_INSNS (1) + *total;
9988 *total = COSTS_N_INSNS (1);
9989 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9990 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
9995 && (MULT == GET_CODE (XEXP (x, 0))
9996 || ASHIFT == GET_CODE (XEXP (x, 0)))
9997 && register_operand (XEXP (x, 1), HImode)
9998 && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))
9999 || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))))
10002 *total = COSTS_N_INSNS (speed ? 5 : 4);
10003 /* multiply-add with constant: will be split and load constant. */
10004 if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
10005 *total = COSTS_N_INSNS (1) + *total;
10008 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10010 *total = COSTS_N_INSNS (2);
10011 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10014 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
10015 *total = COSTS_N_INSNS (1);
10017 *total = COSTS_N_INSNS (2);
10021 if (!CONST_INT_P (XEXP (x, 1)))
10023 *total = COSTS_N_INSNS (3);
10024 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10027 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
10028 *total = COSTS_N_INSNS (2);
10030 *total = COSTS_N_INSNS (3);
10034 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10036 *total = COSTS_N_INSNS (4);
10037 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10040 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
10041 *total = COSTS_N_INSNS (1);
10043 *total = COSTS_N_INSNS (4);
10049 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10055 && register_operand (XEXP (x, 0), QImode)
10056 && MULT == GET_CODE (XEXP (x, 1)))
10059 *total = COSTS_N_INSNS (speed ? 4 : 3);
10060 /* multiply-sub with constant: will be split and load constant. */
10061 if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
10062 *total = COSTS_N_INSNS (1) + *total;
10067 && register_operand (XEXP (x, 0), HImode)
10068 && (MULT == GET_CODE (XEXP (x, 1))
10069 || ASHIFT == GET_CODE (XEXP (x, 1)))
10070 && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))
10071 || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))))
10074 *total = COSTS_N_INSNS (speed ? 5 : 4);
10075 /* multiply-sub with constant: will be split and load constant. */
10076 if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
10077 *total = COSTS_N_INSNS (1) + *total;
10083 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
10084 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10085 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10086 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
10090 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
10091 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10092 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
10100 *total = COSTS_N_INSNS (!speed ? 3 : 4);
10102 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
10110 rtx op0 = XEXP (x, 0);
10111 rtx op1 = XEXP (x, 1);
10112 enum rtx_code code0 = GET_CODE (op0);
10113 enum rtx_code code1 = GET_CODE (op1);
10114 bool ex0 = SIGN_EXTEND == code0 || ZERO_EXTEND == code0;
10115 bool ex1 = SIGN_EXTEND == code1 || ZERO_EXTEND == code1;
10118 && (u8_operand (op1, HImode)
10119 || s8_operand (op1, HImode)))
10121 *total = COSTS_N_INSNS (!speed ? 4 : 6);
10125 && register_operand (op1, HImode))
10127 *total = COSTS_N_INSNS (!speed ? 5 : 8);
10130 else if (ex0 || ex1)
10132 *total = COSTS_N_INSNS (!speed ? 3 : 5);
10135 else if (register_operand (op0, HImode)
10136 && (u8_operand (op1, HImode)
10137 || s8_operand (op1, HImode)))
10139 *total = COSTS_N_INSNS (!speed ? 6 : 9);
10143 *total = COSTS_N_INSNS (!speed ? 7 : 10);
10146 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
10153 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
10164 /* Add some additional costs besides CALL like moves etc. */
10166 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
10170 /* Just a rough estimate. Even with -O2 we don't want bulky
10171 code expanded inline. */
10173 *total = COSTS_N_INSNS (25);
10179 *total = COSTS_N_INSNS (300);
10181 /* Add some additional costs besides CALL like moves etc. */
10182 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
10185 if (mode == DImode)
10193 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10194 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
10202 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
10204 *total = COSTS_N_INSNS (15 * GET_MODE_SIZE (mode));
10205 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10206 /* For div/mod with const-int divisor we have at least the cost of
10207 loading the divisor. */
10208 if (CONST_INT_P (XEXP (x, 1)))
10209 *total += COSTS_N_INSNS (GET_MODE_SIZE (mode));
10210 /* Add some overall penaly for clobbering and moving around registers */
10211 *total += COSTS_N_INSNS (2);
10218 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 4)
10219 *total = COSTS_N_INSNS (1);
10224 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 8)
10225 *total = COSTS_N_INSNS (3);
10230 if (CONST_INT_P (XEXP (x, 1)))
10231 switch (INTVAL (XEXP (x, 1)))
10235 *total = COSTS_N_INSNS (5);
10238 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 6);
10246 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10253 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10255 *total = COSTS_N_INSNS (!speed ? 4 : 17);
10256 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10261 val = INTVAL (XEXP (x, 1));
10263 *total = COSTS_N_INSNS (3);
10264 else if (val >= 0 && val <= 7)
10265 *total = COSTS_N_INSNS (val);
10267 *total = COSTS_N_INSNS (1);
10274 if (const_2_to_7_operand (XEXP (x, 1), HImode)
10275 && (SIGN_EXTEND == GET_CODE (XEXP (x, 0))
10276 || ZERO_EXTEND == GET_CODE (XEXP (x, 0))))
10278 *total = COSTS_N_INSNS (!speed ? 4 : 6);
10283 if (const1_rtx == (XEXP (x, 1))
10284 && SIGN_EXTEND == GET_CODE (XEXP (x, 0)))
10286 *total = COSTS_N_INSNS (2);
10290 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10292 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10293 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10297 switch (INTVAL (XEXP (x, 1)))
10304 *total = COSTS_N_INSNS (2);
10307 *total = COSTS_N_INSNS (3);
10313 *total = COSTS_N_INSNS (4);
10318 *total = COSTS_N_INSNS (5);
10321 *total = COSTS_N_INSNS (!speed ? 5 : 8);
10324 *total = COSTS_N_INSNS (!speed ? 5 : 9);
10327 *total = COSTS_N_INSNS (!speed ? 5 : 10);
10330 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10331 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10337 if (!CONST_INT_P (XEXP (x, 1)))
10339 *total = COSTS_N_INSNS (!speed ? 6 : 73);
10342 switch (INTVAL (XEXP (x, 1)))
10350 *total = COSTS_N_INSNS (3);
10353 *total = COSTS_N_INSNS (5);
10356 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
10362 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10364 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10365 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10369 switch (INTVAL (XEXP (x, 1)))
10375 *total = COSTS_N_INSNS (3);
10380 *total = COSTS_N_INSNS (4);
10383 *total = COSTS_N_INSNS (6);
10386 *total = COSTS_N_INSNS (!speed ? 7 : 8);
10389 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10390 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10398 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10405 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10407 *total = COSTS_N_INSNS (!speed ? 4 : 17);
10408 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10413 val = INTVAL (XEXP (x, 1));
10415 *total = COSTS_N_INSNS (4);
10417 *total = COSTS_N_INSNS (2);
10418 else if (val >= 0 && val <= 7)
10419 *total = COSTS_N_INSNS (val);
10421 *total = COSTS_N_INSNS (1);
10426 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10428 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10429 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10433 switch (INTVAL (XEXP (x, 1)))
10439 *total = COSTS_N_INSNS (2);
10442 *total = COSTS_N_INSNS (3);
10448 *total = COSTS_N_INSNS (4);
10452 *total = COSTS_N_INSNS (5);
10455 *total = COSTS_N_INSNS (!speed ? 5 : 6);
10458 *total = COSTS_N_INSNS (!speed ? 5 : 7);
10462 *total = COSTS_N_INSNS (!speed ? 5 : 8);
10465 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10466 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10472 if (!CONST_INT_P (XEXP (x, 1)))
10474 *total = COSTS_N_INSNS (!speed ? 6 : 73);
10477 switch (INTVAL (XEXP (x, 1)))
10483 *total = COSTS_N_INSNS (3);
10487 *total = COSTS_N_INSNS (5);
10490 *total = COSTS_N_INSNS (4);
10493 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
10499 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10501 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10502 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10506 switch (INTVAL (XEXP (x, 1)))
10512 *total = COSTS_N_INSNS (4);
10517 *total = COSTS_N_INSNS (6);
10520 *total = COSTS_N_INSNS (!speed ? 7 : 8);
10523 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 5);
10526 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10527 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10535 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10542 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10544 *total = COSTS_N_INSNS (!speed ? 4 : 17);
10545 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10550 val = INTVAL (XEXP (x, 1));
10552 *total = COSTS_N_INSNS (3);
10553 else if (val >= 0 && val <= 7)
10554 *total = COSTS_N_INSNS (val);
10556 *total = COSTS_N_INSNS (1);
10561 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10563 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10564 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10568 switch (INTVAL (XEXP (x, 1)))
10575 *total = COSTS_N_INSNS (2);
10578 *total = COSTS_N_INSNS (3);
10583 *total = COSTS_N_INSNS (4);
10587 *total = COSTS_N_INSNS (5);
10593 *total = COSTS_N_INSNS (!speed ? 5 : 6);
10596 *total = COSTS_N_INSNS (!speed ? 5 : 7);
10600 *total = COSTS_N_INSNS (!speed ? 5 : 9);
10603 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10604 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10610 if (!CONST_INT_P (XEXP (x, 1)))
10612 *total = COSTS_N_INSNS (!speed ? 6 : 73);
10615 switch (INTVAL (XEXP (x, 1)))
10623 *total = COSTS_N_INSNS (3);
10626 *total = COSTS_N_INSNS (5);
10629 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
10635 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10637 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10638 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10642 switch (INTVAL (XEXP (x, 1)))
10648 *total = COSTS_N_INSNS (4);
10651 *total = COSTS_N_INSNS (!speed ? 7 : 8);
10656 *total = COSTS_N_INSNS (4);
10659 *total = COSTS_N_INSNS (6);
10662 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10663 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10671 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10675 switch (GET_MODE (XEXP (x, 0)))
10678 *total = COSTS_N_INSNS (1);
10679 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10680 *total += avr_operand_rtx_cost (XEXP (x, 1), QImode, code,
10685 *total = COSTS_N_INSNS (2);
10686 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10687 *total += avr_operand_rtx_cost (XEXP (x, 1), HImode, code,
10689 else if (INTVAL (XEXP (x, 1)) != 0)
10690 *total += COSTS_N_INSNS (1);
10694 *total = COSTS_N_INSNS (3);
10695 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) != 0)
10696 *total += COSTS_N_INSNS (2);
10700 *total = COSTS_N_INSNS (4);
10701 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10702 *total += avr_operand_rtx_cost (XEXP (x, 1), SImode, code,
10704 else if (INTVAL (XEXP (x, 1)) != 0)
10705 *total += COSTS_N_INSNS (3);
10711 *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
10717 && LSHIFTRT == GET_CODE (XEXP (x, 0))
10718 && MULT == GET_CODE (XEXP (XEXP (x, 0), 0))
10719 && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
10721 if (QImode == mode || HImode == mode)
10723 *total = COSTS_N_INSNS (2);
10736 /* Implement `TARGET_RTX_COSTS'. */
10739 avr_rtx_costs (rtx x, machine_mode mode, int outer_code,
10740 int opno, int *total, bool speed)
10742 bool done = avr_rtx_costs_1 (x, mode, outer_code,
10743 opno, total, speed);
10745 if (avr_log.rtx_costs)
10747 avr_edump ("\n%?=%b (%s) total=%d, outer=%C:\n%r\n",
10748 done, speed ? "speed" : "size", *total, outer_code, x);
10755 /* Implement `TARGET_ADDRESS_COST'. */
10758 avr_address_cost (rtx x, machine_mode mode ATTRIBUTE_UNUSED,
10759 addr_space_t as ATTRIBUTE_UNUSED,
10760 bool speed ATTRIBUTE_UNUSED)
10764 if (GET_CODE (x) == PLUS
10765 && CONST_INT_P (XEXP (x, 1))
10766 && (REG_P (XEXP (x, 0))
10767 || GET_CODE (XEXP (x, 0)) == SUBREG))
10769 if (INTVAL (XEXP (x, 1)) > MAX_LD_OFFSET(mode))
10772 else if (CONSTANT_ADDRESS_P (x))
10775 && io_address_operand (x, QImode))
10779 if (avr_log.address_cost)
10780 avr_edump ("\n%?: %d = %r\n", cost, x);
10785 /* Test for extra memory constraint 'Q'.
10786 It's a memory address based on Y or Z pointer with valid displacement. */
10789 extra_constraint_Q (rtx x)
10793 if (GET_CODE (XEXP (x,0)) == PLUS
10794 && REG_P (XEXP (XEXP (x,0), 0))
10795 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
10796 && (INTVAL (XEXP (XEXP (x,0), 1))
10797 <= MAX_LD_OFFSET (GET_MODE (x))))
10799 rtx xx = XEXP (XEXP (x,0), 0);
10800 int regno = REGNO (xx);
10802 ok = (/* allocate pseudos */
10803 regno >= FIRST_PSEUDO_REGISTER
10804 /* strictly check */
10805 || regno == REG_Z || regno == REG_Y
10806 /* XXX frame & arg pointer checks */
10807 || xx == frame_pointer_rtx
10808 || xx == arg_pointer_rtx);
10810 if (avr_log.constraints)
10811 avr_edump ("\n%?=%d reload_completed=%d reload_in_progress=%d\n %r\n",
10812 ok, reload_completed, reload_in_progress, x);
10818 /* Convert condition code CONDITION to the valid AVR condition code. */
10821 avr_normalize_condition (RTX_CODE condition)
10834 gcc_unreachable ();
10838 /* Helper function for `avr_reorg'. */
10841 avr_compare_pattern (rtx_insn *insn)
10843 rtx pattern = single_set (insn);
10846 && NONJUMP_INSN_P (insn)
10847 && SET_DEST (pattern) == cc0_rtx
10848 && GET_CODE (SET_SRC (pattern)) == COMPARE)
10850 machine_mode mode0 = GET_MODE (XEXP (SET_SRC (pattern), 0));
10851 machine_mode mode1 = GET_MODE (XEXP (SET_SRC (pattern), 1));
10853 /* The 64-bit comparisons have fixed operands ACC_A and ACC_B.
10854 They must not be swapped, thus skip them. */
10856 if ((mode0 == VOIDmode || GET_MODE_SIZE (mode0) <= 4)
10857 && (mode1 == VOIDmode || GET_MODE_SIZE (mode1) <= 4))
10864 /* Helper function for `avr_reorg'. */
10866 /* Expansion of switch/case decision trees leads to code like
10868 cc0 = compare (Reg, Num)
10872 cc0 = compare (Reg, Num)
10876 The second comparison is superfluous and can be deleted.
10877 The second jump condition can be transformed from a
10878 "difficult" one to a "simple" one because "cc0 > 0" and
10879 "cc0 >= 0" will have the same effect here.
10881 This function relies on the way switch/case is being expaned
10882 as binary decision tree. For example code see PR 49903.
10884 Return TRUE if optimization performed.
10885 Return FALSE if nothing changed.
10887 INSN1 is a comparison, i.e. avr_compare_pattern != 0.
10889 We don't want to do this in text peephole because it is
10890 tedious to work out jump offsets there and the second comparison
10891 might have been transormed by `avr_reorg'.
10893 RTL peephole won't do because peephole2 does not scan across
10897 avr_reorg_remove_redundant_compare (rtx_insn *insn1)
10899 rtx comp1, ifelse1, xcond1;
10901 rtx comp2, ifelse2, xcond2;
10902 rtx_insn *branch2, *insn2;
10903 enum rtx_code code;
10907 /* Look out for: compare1 - branch1 - compare2 - branch2 */
10909 branch1 = next_nonnote_nondebug_insn (insn1);
10910 if (!branch1 || !JUMP_P (branch1))
10913 insn2 = next_nonnote_nondebug_insn (branch1);
10914 if (!insn2 || !avr_compare_pattern (insn2))
10917 branch2 = next_nonnote_nondebug_insn (insn2);
10918 if (!branch2 || !JUMP_P (branch2))
10921 comp1 = avr_compare_pattern (insn1);
10922 comp2 = avr_compare_pattern (insn2);
10923 xcond1 = single_set (branch1);
10924 xcond2 = single_set (branch2);
10926 if (!comp1 || !comp2
10927 || !rtx_equal_p (comp1, comp2)
10928 || !xcond1 || SET_DEST (xcond1) != pc_rtx
10929 || !xcond2 || SET_DEST (xcond2) != pc_rtx
10930 || IF_THEN_ELSE != GET_CODE (SET_SRC (xcond1))
10931 || IF_THEN_ELSE != GET_CODE (SET_SRC (xcond2)))
10936 comp1 = SET_SRC (comp1);
10937 ifelse1 = SET_SRC (xcond1);
10938 ifelse2 = SET_SRC (xcond2);
10940 /* comp<n> is COMPARE now and ifelse<n> is IF_THEN_ELSE. */
10942 if (EQ != GET_CODE (XEXP (ifelse1, 0))
10943 || !REG_P (XEXP (comp1, 0))
10944 || !CONST_INT_P (XEXP (comp1, 1))
10945 || XEXP (ifelse1, 2) != pc_rtx
10946 || XEXP (ifelse2, 2) != pc_rtx
10947 || LABEL_REF != GET_CODE (XEXP (ifelse1, 1))
10948 || LABEL_REF != GET_CODE (XEXP (ifelse2, 1))
10949 || !COMPARISON_P (XEXP (ifelse2, 0))
10950 || cc0_rtx != XEXP (XEXP (ifelse1, 0), 0)
10951 || cc0_rtx != XEXP (XEXP (ifelse2, 0), 0)
10952 || const0_rtx != XEXP (XEXP (ifelse1, 0), 1)
10953 || const0_rtx != XEXP (XEXP (ifelse2, 0), 1))
10958 /* We filtered the insn sequence to look like
10964 (if_then_else (eq (cc0)
10973 (if_then_else (CODE (cc0)
10979 code = GET_CODE (XEXP (ifelse2, 0));
10981 /* Map GT/GTU to GE/GEU which is easier for AVR.
10982 The first two instructions compare/branch on EQ
10983 so we may replace the difficult
10985 if (x == VAL) goto L1;
10986 if (x > VAL) goto L2;
10990 if (x == VAL) goto L1;
10991 if (x >= VAL) goto L2;
10993 Similarly, replace LE/LEU by LT/LTU. */
11004 code = avr_normalize_condition (code);
11011 /* Wrap the branches into UNSPECs so they won't be changed or
11012 optimized in the remainder. */
11014 target = XEXP (XEXP (ifelse1, 1), 0);
11015 cond = XEXP (ifelse1, 0);
11016 jump = emit_jump_insn_after (gen_branch_unspec (target, cond), insn1);
11018 JUMP_LABEL (jump) = JUMP_LABEL (branch1);
11020 target = XEXP (XEXP (ifelse2, 1), 0);
11021 cond = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
11022 jump = emit_jump_insn_after (gen_branch_unspec (target, cond), insn2);
11024 JUMP_LABEL (jump) = JUMP_LABEL (branch2);
11026 /* The comparisons in insn1 and insn2 are exactly the same;
11027 insn2 is superfluous so delete it. */
11029 delete_insn (insn2);
11030 delete_insn (branch1);
11031 delete_insn (branch2);
11037 /* Implement `TARGET_MACHINE_DEPENDENT_REORG'. */
11038 /* Optimize conditional jumps. */
11043 rtx_insn *insn = get_insns();
11045 for (insn = next_real_insn (insn); insn; insn = next_real_insn (insn))
11047 rtx pattern = avr_compare_pattern (insn);
11053 && avr_reorg_remove_redundant_compare (insn))
11058 if (compare_diff_p (insn))
11060 /* Now we work under compare insn with difficult branch. */
11062 rtx_insn *next = next_real_insn (insn);
11063 rtx pat = PATTERN (next);
11065 pattern = SET_SRC (pattern);
11067 if (true_regnum (XEXP (pattern, 0)) >= 0
11068 && true_regnum (XEXP (pattern, 1)) >= 0)
11070 rtx x = XEXP (pattern, 0);
11071 rtx src = SET_SRC (pat);
11072 rtx t = XEXP (src,0);
11073 PUT_CODE (t, swap_condition (GET_CODE (t)));
11074 XEXP (pattern, 0) = XEXP (pattern, 1);
11075 XEXP (pattern, 1) = x;
11076 INSN_CODE (next) = -1;
11078 else if (true_regnum (XEXP (pattern, 0)) >= 0
11079 && XEXP (pattern, 1) == const0_rtx)
11081 /* This is a tst insn, we can reverse it. */
11082 rtx src = SET_SRC (pat);
11083 rtx t = XEXP (src,0);
11085 PUT_CODE (t, swap_condition (GET_CODE (t)));
11086 XEXP (pattern, 1) = XEXP (pattern, 0);
11087 XEXP (pattern, 0) = const0_rtx;
11088 INSN_CODE (next) = -1;
11089 INSN_CODE (insn) = -1;
11091 else if (true_regnum (XEXP (pattern, 0)) >= 0
11092 && CONST_INT_P (XEXP (pattern, 1)))
11094 rtx x = XEXP (pattern, 1);
11095 rtx src = SET_SRC (pat);
11096 rtx t = XEXP (src,0);
11097 machine_mode mode = GET_MODE (XEXP (pattern, 0));
11099 if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
11101 XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
11102 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
11103 INSN_CODE (next) = -1;
11104 INSN_CODE (insn) = -1;
11111 /* Returns register number for function return value.*/
11113 static inline unsigned int
11114 avr_ret_register (void)
11120 /* Implement `TARGET_FUNCTION_VALUE_REGNO_P'. */
11123 avr_function_value_regno_p (const unsigned int regno)
11125 return (regno == avr_ret_register ());
11129 /* Implement `TARGET_LIBCALL_VALUE'. */
11130 /* Create an RTX representing the place where a
11131 library function returns a value of mode MODE. */
11134 avr_libcall_value (machine_mode mode,
11135 const_rtx func ATTRIBUTE_UNUSED)
11137 int offs = GET_MODE_SIZE (mode);
11140 offs = (offs + 1) & ~1;
11142 return gen_rtx_REG (mode, avr_ret_register () + 2 - offs);
11146 /* Implement `TARGET_FUNCTION_VALUE'. */
11147 /* Create an RTX representing the place where a
11148 function returns a value of data type VALTYPE. */
11151 avr_function_value (const_tree type,
11152 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
11153 bool outgoing ATTRIBUTE_UNUSED)
11157 if (TYPE_MODE (type) != BLKmode)
11158 return avr_libcall_value (TYPE_MODE (type), NULL_RTX);
11160 offs = int_size_in_bytes (type);
11163 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
11164 offs = GET_MODE_SIZE (SImode);
11165 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
11166 offs = GET_MODE_SIZE (DImode);
11168 return gen_rtx_REG (BLKmode, avr_ret_register () + 2 - offs);
11172 test_hard_reg_class (enum reg_class rclass, rtx x)
11174 int regno = true_regnum (x);
11178 if (TEST_HARD_REG_CLASS (rclass, regno))
11185 /* Helper for jump_over_one_insn_p: Test if INSN is a 2-word instruction
11186 and thus is suitable to be skipped by CPSE, SBRC, etc. */
11189 avr_2word_insn_p (rtx_insn *insn)
11191 if (TARGET_SKIP_BUG
11193 || 2 != get_attr_length (insn))
11198 switch (INSN_CODE (insn))
11203 case CODE_FOR_movqi_insn:
11204 case CODE_FOR_movuqq_insn:
11205 case CODE_FOR_movqq_insn:
11207 rtx set = single_set (insn);
11208 rtx src = SET_SRC (set);
11209 rtx dest = SET_DEST (set);
11211 /* Factor out LDS and STS from movqi_insn. */
11214 && (REG_P (src) || src == CONST0_RTX (GET_MODE (dest))))
11216 return CONSTANT_ADDRESS_P (XEXP (dest, 0));
11218 else if (REG_P (dest)
11221 return CONSTANT_ADDRESS_P (XEXP (src, 0));
11227 case CODE_FOR_call_insn:
11228 case CODE_FOR_call_value_insn:
11235 jump_over_one_insn_p (rtx_insn *insn, rtx dest)
11237 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
11240 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
11241 int dest_addr = INSN_ADDRESSES (uid);
11242 int jump_offset = dest_addr - jump_addr - get_attr_length (insn);
11244 return (jump_offset == 1
11245 || (jump_offset == 2
11246 && avr_2word_insn_p (next_active_insn (insn))));
11250 /* Worker function for `HARD_REGNO_MODE_OK'. */
11251 /* Returns 1 if a value of mode MODE can be stored starting with hard
11252 register number REGNO. On the enhanced core, anything larger than
11253 1 byte must start in even numbered register for "movw" to work
11254 (this way we don't have to check for odd registers everywhere). */
11257 avr_hard_regno_mode_ok (int regno, machine_mode mode)
11259 /* NOTE: 8-bit values must not be disallowed for R28 or R29.
11260 Disallowing QI et al. in these regs might lead to code like
11261 (set (subreg:QI (reg:HI 28) n) ...)
11262 which will result in wrong code because reload does not
11263 handle SUBREGs of hard regsisters like this.
11264 This could be fixed in reload. However, it appears
11265 that fixing reload is not wanted by reload people. */
11267 /* Any GENERAL_REGS register can hold 8-bit values. */
11269 if (GET_MODE_SIZE (mode) == 1)
11272 /* FIXME: Ideally, the following test is not needed.
11273 However, it turned out that it can reduce the number
11274 of spill fails. AVR and it's poor endowment with
11275 address registers is extreme stress test for reload. */
11277 if (GET_MODE_SIZE (mode) >= 4
11281 /* All modes larger than 8 bits should start in an even register. */
11283 return !(regno & 1);
11287 /* Implement `HARD_REGNO_CALL_PART_CLOBBERED'. */
11290 avr_hard_regno_call_part_clobbered (unsigned regno, machine_mode mode)
11292 /* FIXME: This hook gets called with MODE:REGNO combinations that don't
11293 represent valid hard registers like, e.g. HI:29. Returning TRUE
11294 for such registers can lead to performance degradation as mentioned
11295 in PR53595. Thus, report invalid hard registers as FALSE. */
11297 if (!avr_hard_regno_mode_ok (regno, mode))
11300 /* Return true if any of the following boundaries is crossed:
11301 17/18 or 19/20 (if AVR_TINY), 27/28 and 29/30. */
11303 return ((regno <= LAST_CALLEE_SAVED_REG &&
11304 regno + GET_MODE_SIZE (mode) > (LAST_CALLEE_SAVED_REG + 1))
11305 || (regno < REG_Y && regno + GET_MODE_SIZE (mode) > REG_Y)
11306 || (regno < REG_Z && regno + GET_MODE_SIZE (mode) > REG_Z));
11310 /* Implement `MODE_CODE_BASE_REG_CLASS'. */
11313 avr_mode_code_base_reg_class (machine_mode mode ATTRIBUTE_UNUSED,
11314 addr_space_t as, RTX_CODE outer_code,
11315 RTX_CODE index_code ATTRIBUTE_UNUSED)
11317 if (!ADDR_SPACE_GENERIC_P (as))
11319 return POINTER_Z_REGS;
11323 return reload_completed ? BASE_POINTER_REGS : POINTER_REGS;
11325 return PLUS == outer_code ? BASE_POINTER_REGS : POINTER_REGS;
11329 /* Implement `REGNO_MODE_CODE_OK_FOR_BASE_P'. */
11332 avr_regno_mode_code_ok_for_base_p (int regno,
11333 machine_mode mode ATTRIBUTE_UNUSED,
11334 addr_space_t as ATTRIBUTE_UNUSED,
11335 RTX_CODE outer_code,
11336 RTX_CODE index_code ATTRIBUTE_UNUSED)
11340 if (!ADDR_SPACE_GENERIC_P (as))
11342 if (regno < FIRST_PSEUDO_REGISTER
11350 regno = reg_renumber[regno];
11352 if (regno == REG_Z)
11361 if (regno < FIRST_PSEUDO_REGISTER
11365 || regno == ARG_POINTER_REGNUM))
11369 else if (reg_renumber)
11371 regno = reg_renumber[regno];
11376 || regno == ARG_POINTER_REGNUM)
11383 && PLUS == outer_code
11393 /* A helper for `output_reload_insisf' and `output_reload_inhi'. */
11394 /* Set 32-bit register OP[0] to compile-time constant OP[1].
11395 CLOBBER_REG is a QI clobber register or NULL_RTX.
11396 LEN == NULL: output instructions.
11397 LEN != NULL: set *LEN to the length of the instruction sequence
11398 (in words) printed with LEN = NULL.
11399 If CLEAR_P is true, OP[0] had been cleard to Zero already.
11400 If CLEAR_P is false, nothing is known about OP[0].
11402 The effect on cc0 is as follows:
11404 Load 0 to any register except ZERO_REG : NONE
11405 Load ld register with any value : NONE
11406 Anything else: : CLOBBER */
11409 output_reload_in_const (rtx *op, rtx clobber_reg, int *len, bool clear_p)
11413 rtx xval, xdest[4];
11415 int clobber_val = 1234;
11416 bool cooked_clobber_p = false;
11417 bool set_p = false;
11418 machine_mode mode = GET_MODE (dest);
11419 int n, n_bytes = GET_MODE_SIZE (mode);
11421 gcc_assert (REG_P (dest)
11422 && CONSTANT_P (src));
11427 /* (REG:SI 14) is special: It's neither in LD_REGS nor in NO_LD_REGS
11428 but has some subregs that are in LD_REGS. Use the MSB (REG:QI 17). */
11430 if (REGNO (dest) < 16
11431 && REGNO (dest) + GET_MODE_SIZE (mode) > 16)
11433 clobber_reg = all_regs_rtx[REGNO (dest) + n_bytes - 1];
11436 /* We might need a clobber reg but don't have one. Look at the value to
11437 be loaded more closely. A clobber is only needed if it is a symbol
11438 or contains a byte that is neither 0, -1 or a power of 2. */
11440 if (NULL_RTX == clobber_reg
11441 && !test_hard_reg_class (LD_REGS, dest)
11442 && (! (CONST_INT_P (src) || CONST_FIXED_P (src) || CONST_DOUBLE_P (src))
11443 || !avr_popcount_each_byte (src, n_bytes,
11444 (1 << 0) | (1 << 1) | (1 << 8))))
11446 /* We have no clobber register but need one. Cook one up.
11447 That's cheaper than loading from constant pool. */
11449 cooked_clobber_p = true;
11450 clobber_reg = all_regs_rtx[REG_Z + 1];
11451 avr_asm_len ("mov __tmp_reg__,%0", &clobber_reg, len, 1);
11454 /* Now start filling DEST from LSB to MSB. */
11456 for (n = 0; n < n_bytes; n++)
11459 bool done_byte = false;
11463 /* Crop the n-th destination byte. */
11465 xdest[n] = simplify_gen_subreg (QImode, dest, mode, n);
11466 ldreg_p = test_hard_reg_class (LD_REGS, xdest[n]);
11468 if (!CONST_INT_P (src)
11469 && !CONST_FIXED_P (src)
11470 && !CONST_DOUBLE_P (src))
11472 static const char* const asm_code[][2] =
11474 { "ldi %2,lo8(%1)" CR_TAB "mov %0,%2", "ldi %0,lo8(%1)" },
11475 { "ldi %2,hi8(%1)" CR_TAB "mov %0,%2", "ldi %0,hi8(%1)" },
11476 { "ldi %2,hlo8(%1)" CR_TAB "mov %0,%2", "ldi %0,hlo8(%1)" },
11477 { "ldi %2,hhi8(%1)" CR_TAB "mov %0,%2", "ldi %0,hhi8(%1)" }
11482 xop[2] = clobber_reg;
11484 avr_asm_len (asm_code[n][ldreg_p], xop, len, ldreg_p ? 1 : 2);
11489 /* Crop the n-th source byte. */
11491 xval = simplify_gen_subreg (QImode, src, mode, n);
11492 ival[n] = INTVAL (xval);
11494 /* Look if we can reuse the low word by means of MOVW. */
11500 rtx lo16 = simplify_gen_subreg (HImode, src, mode, 0);
11501 rtx hi16 = simplify_gen_subreg (HImode, src, mode, 2);
11503 if (INTVAL (lo16) == INTVAL (hi16))
11505 if (0 != INTVAL (lo16)
11508 avr_asm_len ("movw %C0,%A0", &op[0], len, 1);
11515 /* Don't use CLR so that cc0 is set as expected. */
11520 avr_asm_len (ldreg_p ? "ldi %0,0"
11521 : AVR_ZERO_REGNO == REGNO (xdest[n]) ? "clr %0"
11522 : "mov %0,__zero_reg__",
11523 &xdest[n], len, 1);
11527 if (clobber_val == ival[n]
11528 && REGNO (clobber_reg) == REGNO (xdest[n]))
11533 /* LD_REGS can use LDI to move a constant value */
11539 avr_asm_len ("ldi %0,lo8(%1)", xop, len, 1);
11543 /* Try to reuse value already loaded in some lower byte. */
11545 for (j = 0; j < n; j++)
11546 if (ival[j] == ival[n])
11551 avr_asm_len ("mov %0,%1", xop, len, 1);
11559 /* Need no clobber reg for -1: Use CLR/DEC */
11564 avr_asm_len ("clr %0", &xdest[n], len, 1);
11566 avr_asm_len ("dec %0", &xdest[n], len, 1);
11569 else if (1 == ival[n])
11572 avr_asm_len ("clr %0", &xdest[n], len, 1);
11574 avr_asm_len ("inc %0", &xdest[n], len, 1);
11578 /* Use T flag or INC to manage powers of 2 if we have
11581 if (NULL_RTX == clobber_reg
11582 && single_one_operand (xval, QImode))
11585 xop[1] = GEN_INT (exact_log2 (ival[n] & GET_MODE_MASK (QImode)));
11587 gcc_assert (constm1_rtx != xop[1]);
11592 avr_asm_len ("set", xop, len, 1);
11596 avr_asm_len ("clr %0", xop, len, 1);
11598 avr_asm_len ("bld %0,%1", xop, len, 1);
11602 /* We actually need the LD_REGS clobber reg. */
11604 gcc_assert (NULL_RTX != clobber_reg);
11608 xop[2] = clobber_reg;
11609 clobber_val = ival[n];
11611 avr_asm_len ("ldi %2,lo8(%1)" CR_TAB
11612 "mov %0,%2", xop, len, 2);
11615 /* If we cooked up a clobber reg above, restore it. */
11617 if (cooked_clobber_p)
11619 avr_asm_len ("mov %0,__tmp_reg__", &clobber_reg, len, 1);
11624 /* Reload the constant OP[1] into the HI register OP[0].
11625 CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
11626 into a NO_LD_REGS register. If CLOBBER_REG is NULL_RTX we either don't
11627 need a clobber reg or have to cook one up.
11629 PLEN == NULL: Output instructions.
11630 PLEN != NULL: Output nothing. Set *PLEN to number of words occupied
11631 by the insns printed.
11636 output_reload_inhi (rtx *op, rtx clobber_reg, int *plen)
11638 output_reload_in_const (op, clobber_reg, plen, false);
11643 /* Reload a SI or SF compile time constant OP[1] into the register OP[0].
11644 CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
11645 into a NO_LD_REGS register. If CLOBBER_REG is NULL_RTX we either don't
11646 need a clobber reg or have to cook one up.
11648 LEN == NULL: Output instructions.
11650 LEN != NULL: Output nothing. Set *LEN to number of words occupied
11651 by the insns printed.
11656 output_reload_insisf (rtx *op, rtx clobber_reg, int *len)
11659 && !test_hard_reg_class (LD_REGS, op[0])
11660 && (CONST_INT_P (op[1])
11661 || CONST_FIXED_P (op[1])
11662 || CONST_DOUBLE_P (op[1])))
11664 int len_clr, len_noclr;
11666 /* In some cases it is better to clear the destination beforehand, e.g.
11668 CLR R2 CLR R3 MOVW R4,R2 INC R2
11672 CLR R2 INC R2 CLR R3 CLR R4 CLR R5
11674 We find it too tedious to work that out in the print function.
11675 Instead, we call the print function twice to get the lengths of
11676 both methods and use the shortest one. */
11678 output_reload_in_const (op, clobber_reg, &len_clr, true);
11679 output_reload_in_const (op, clobber_reg, &len_noclr, false);
11681 if (len_noclr - len_clr == 4)
11683 /* Default needs 4 CLR instructions: clear register beforehand. */
11685 avr_asm_len ("mov %A0,__zero_reg__" CR_TAB
11686 "mov %B0,__zero_reg__" CR_TAB
11687 "movw %C0,%A0", &op[0], len, 3);
11689 output_reload_in_const (op, clobber_reg, len, true);
11698 /* Default: destination not pre-cleared. */
11700 output_reload_in_const (op, clobber_reg, len, false);
11705 avr_out_reload_inpsi (rtx *op, rtx clobber_reg, int *len)
11707 output_reload_in_const (op, clobber_reg, len, false);
11712 /* Worker function for `ASM_OUTPUT_ADDR_VEC_ELT'. */
11715 avr_output_addr_vec_elt (FILE *stream, int value)
11717 if (AVR_HAVE_JMP_CALL)
11718 fprintf (stream, "\t.word gs(.L%d)\n", value);
11720 fprintf (stream, "\trjmp .L%d\n", value);
11724 avr_conditional_register_usage(void)
11730 const int tiny_reg_alloc_order[] = {
11739 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
11742 /* Set R0-R17 as fixed registers. Reset R0-R17 in call used register list
11743 - R0-R15 are not available in Tiny Core devices
11744 - R16 and R17 are fixed registers. */
11746 for (i = 0; i <= 17; i++)
11749 call_used_regs[i] = 1;
11752 /* Set R18 to R21 as callee saved registers
11753 - R18, R19, R20 and R21 are the callee saved registers in
11754 Tiny Core devices */
11756 for (i = 18; i <= LAST_CALLEE_SAVED_REG; i++)
11758 call_used_regs[i] = 0;
11761 /* Update register allocation order for Tiny Core devices */
11763 for (i = 0; i < ARRAY_SIZE (tiny_reg_alloc_order); i++)
11765 reg_alloc_order[i] = tiny_reg_alloc_order[i];
11768 CLEAR_HARD_REG_SET (reg_class_contents[(int) ADDW_REGS]);
11769 CLEAR_HARD_REG_SET (reg_class_contents[(int) NO_LD_REGS]);
11773 /* Implement `TARGET_HARD_REGNO_SCRATCH_OK'. */
11774 /* Returns true if SCRATCH are safe to be allocated as a scratch
11775 registers (for a define_peephole2) in the current function. */
11778 avr_hard_regno_scratch_ok (unsigned int regno)
11780 /* Interrupt functions can only use registers that have already been saved
11781 by the prologue, even if they would normally be call-clobbered. */
11783 if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
11784 && !df_regs_ever_live_p (regno))
11787 /* Don't allow hard registers that might be part of the frame pointer.
11788 Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
11789 and don't care for a frame pointer that spans more than one register. */
11791 if ((!reload_completed || frame_pointer_needed)
11792 && (regno == REG_Y || regno == REG_Y + 1))
11801 /* Worker function for `HARD_REGNO_RENAME_OK'. */
11802 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
11805 avr_hard_regno_rename_ok (unsigned int old_reg,
11806 unsigned int new_reg)
11808 /* Interrupt functions can only use registers that have already been
11809 saved by the prologue, even if they would normally be
11812 if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
11813 && !df_regs_ever_live_p (new_reg))
11816 /* Don't allow hard registers that might be part of the frame pointer.
11817 Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
11818 and don't care for a frame pointer that spans more than one register. */
11820 if ((!reload_completed || frame_pointer_needed)
11821 && (old_reg == REG_Y || old_reg == REG_Y + 1
11822 || new_reg == REG_Y || new_reg == REG_Y + 1))
11830 /* Output a branch that tests a single bit of a register (QI, HI, SI or DImode)
11831 or memory location in the I/O space (QImode only).
11833 Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
11834 Operand 1: register operand to test, or CONST_INT memory address.
11835 Operand 2: bit number.
11836 Operand 3: label to jump to if the test is true. */
11839 avr_out_sbxx_branch (rtx_insn *insn, rtx operands[])
11841 enum rtx_code comp = GET_CODE (operands[0]);
11842 bool long_jump = get_attr_length (insn) >= 4;
11843 bool reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
11847 else if (comp == LT)
11851 comp = reverse_condition (comp);
11853 switch (GET_CODE (operands[1]))
11862 if (low_io_address_operand (operands[1], QImode))
11865 output_asm_insn ("sbis %i1,%2", operands);
11867 output_asm_insn ("sbic %i1,%2", operands);
11871 gcc_assert (io_address_operand (operands[1], QImode));
11872 output_asm_insn ("in __tmp_reg__,%i1", operands);
11874 output_asm_insn ("sbrs __tmp_reg__,%2", operands);
11876 output_asm_insn ("sbrc __tmp_reg__,%2", operands);
11879 break; /* CONST_INT */
11884 output_asm_insn ("sbrs %T1%T2", operands);
11886 output_asm_insn ("sbrc %T1%T2", operands);
11892 return ("rjmp .+4" CR_TAB
11901 /* Worker function for `TARGET_ASM_CONSTRUCTOR'. */
11904 avr_asm_out_ctor (rtx symbol, int priority)
11906 fputs ("\t.global __do_global_ctors\n", asm_out_file);
11907 default_ctor_section_asm_out_constructor (symbol, priority);
11911 /* Worker function for `TARGET_ASM_DESTRUCTOR'. */
11914 avr_asm_out_dtor (rtx symbol, int priority)
11916 fputs ("\t.global __do_global_dtors\n", asm_out_file);
11917 default_dtor_section_asm_out_destructor (symbol, priority);
11921 /* Worker function for `TARGET_RETURN_IN_MEMORY'. */
11924 avr_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
11926 HOST_WIDE_INT size = int_size_in_bytes (type);
11927 HOST_WIDE_INT ret_size_limit = AVR_TINY ? 4 : 8;
11929 /* In avr, there are 8 return registers. But, for Tiny Core
11930 (ATtiny4/5/9/10/20/40) devices, only 4 registers are available.
11931 Return true if size is unknown or greater than the limit. */
11933 if (size == -1 || size > ret_size_limit)
11944 /* Implement `CASE_VALUES_THRESHOLD'. */
11945 /* Supply the default for --param case-values-threshold=0 */
11947 static unsigned int
11948 avr_case_values_threshold (void)
11950 /* The exact break-even point between a jump table and an if-else tree
11951 depends on several factors not available here like, e.g. if 8-bit
11952 comparisons can be used in the if-else tree or not, on the
11953 range of the case values, if the case value can be reused, on the
11954 register allocation, etc. '7' appears to be a good choice. */
11960 /* Implement `TARGET_ADDR_SPACE_ADDRESS_MODE'. */
11962 static machine_mode
11963 avr_addr_space_address_mode (addr_space_t as)
11965 return avr_addrspace[as].pointer_size == 3 ? PSImode : HImode;
11969 /* Implement `TARGET_ADDR_SPACE_POINTER_MODE'. */
11971 static machine_mode
11972 avr_addr_space_pointer_mode (addr_space_t as)
11974 return avr_addr_space_address_mode (as);
11978 /* Helper for following function. */
11981 avr_reg_ok_for_pgm_addr (rtx reg, bool strict)
11983 gcc_assert (REG_P (reg));
11987 return REGNO (reg) == REG_Z;
11990 /* Avoid combine to propagate hard regs. */
11992 if (can_create_pseudo_p()
11993 && REGNO (reg) < REG_Z)
12002 /* Implement `TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P'. */
12005 avr_addr_space_legitimate_address_p (machine_mode mode, rtx x,
12006 bool strict, addr_space_t as)
12015 case ADDR_SPACE_GENERIC:
12016 return avr_legitimate_address_p (mode, x, strict);
12018 case ADDR_SPACE_FLASH:
12019 case ADDR_SPACE_FLASH1:
12020 case ADDR_SPACE_FLASH2:
12021 case ADDR_SPACE_FLASH3:
12022 case ADDR_SPACE_FLASH4:
12023 case ADDR_SPACE_FLASH5:
12025 switch (GET_CODE (x))
12028 ok = avr_reg_ok_for_pgm_addr (x, strict);
12032 ok = avr_reg_ok_for_pgm_addr (XEXP (x, 0), strict);
12041 case ADDR_SPACE_MEMX:
12044 && can_create_pseudo_p());
12046 if (LO_SUM == GET_CODE (x))
12048 rtx hi = XEXP (x, 0);
12049 rtx lo = XEXP (x, 1);
12052 && (!strict || REGNO (hi) < FIRST_PSEUDO_REGISTER)
12054 && REGNO (lo) == REG_Z);
12060 if (avr_log.legitimate_address_p)
12062 avr_edump ("\n%?: ret=%b, mode=%m strict=%d "
12063 "reload_completed=%d reload_in_progress=%d %s:",
12064 ok, mode, strict, reload_completed, reload_in_progress,
12065 reg_renumber ? "(reg_renumber)" : "");
12067 if (GET_CODE (x) == PLUS
12068 && REG_P (XEXP (x, 0))
12069 && CONST_INT_P (XEXP (x, 1))
12070 && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
12073 avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
12074 true_regnum (XEXP (x, 0)));
12077 avr_edump ("\n%r\n", x);
12084 /* Implement `TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS'. */
12087 avr_addr_space_legitimize_address (rtx x, rtx old_x,
12088 machine_mode mode, addr_space_t as)
12090 if (ADDR_SPACE_GENERIC_P (as))
12091 return avr_legitimize_address (x, old_x, mode);
12093 if (avr_log.legitimize_address)
12095 avr_edump ("\n%?: mode=%m\n %r\n", mode, old_x);
12102 /* Implement `TARGET_ADDR_SPACE_CONVERT'. */
12105 avr_addr_space_convert (rtx src, tree type_from, tree type_to)
12107 addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (type_from));
12108 addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type_to));
12110 if (avr_log.progmem)
12111 avr_edump ("\n%!: op = %r\nfrom = %t\nto = %t\n",
12112 src, type_from, type_to);
12114 /* Up-casting from 16-bit to 24-bit pointer. */
12116 if (as_from != ADDR_SPACE_MEMX
12117 && as_to == ADDR_SPACE_MEMX)
12121 rtx reg = gen_reg_rtx (PSImode);
12123 while (CONST == GET_CODE (sym) || PLUS == GET_CODE (sym))
12124 sym = XEXP (sym, 0);
12126 /* Look at symbol flags: avr_encode_section_info set the flags
12127 also if attribute progmem was seen so that we get the right
12128 promotion for, e.g. PSTR-like strings that reside in generic space
12129 but are located in flash. In that case we patch the incoming
12132 if (SYMBOL_REF == GET_CODE (sym)
12133 && ADDR_SPACE_FLASH == AVR_SYMBOL_GET_ADDR_SPACE (sym))
12135 as_from = ADDR_SPACE_FLASH;
12138 /* Linearize memory: RAM has bit 23 set. */
12140 msb = ADDR_SPACE_GENERIC_P (as_from)
12142 : avr_addrspace[as_from].segment;
12144 src = force_reg (Pmode, src);
12146 emit_insn (msb == 0
12147 ? gen_zero_extendhipsi2 (reg, src)
12148 : gen_n_extendhipsi2 (reg, gen_int_mode (msb, QImode), src));
12153 /* Down-casting from 24-bit to 16-bit throws away the high byte. */
12155 if (as_from == ADDR_SPACE_MEMX
12156 && as_to != ADDR_SPACE_MEMX)
12158 rtx new_src = gen_reg_rtx (Pmode);
12160 src = force_reg (PSImode, src);
12162 emit_move_insn (new_src,
12163 simplify_gen_subreg (Pmode, src, PSImode, 0));
12171 /* Implement `TARGET_ADDR_SPACE_SUBSET_P'. */
12174 avr_addr_space_subset_p (addr_space_t subset ATTRIBUTE_UNUSED,
12175 addr_space_t superset ATTRIBUTE_UNUSED)
12177 /* Allow any kind of pointer mess. */
12183 /* Implement `TARGET_CONVERT_TO_TYPE'. */
12186 avr_convert_to_type (tree type, tree expr)
12188 /* Print a diagnose for pointer conversion that changes the address
12189 space of the pointer target to a non-enclosing address space,
12190 provided -Waddr-space-convert is on.
12192 FIXME: Filter out cases where the target object is known to
12193 be located in the right memory, like in
12195 (const __flash*) PSTR ("text")
12197 Also try to distinguish between explicit casts requested by
12198 the user and implicit casts like
12200 void f (const __flash char*);
12202 void g (const char *p)
12204 f ((const __flash*) p);
12207 under the assumption that an explicit casts means that the user
12208 knows what he is doing, e.g. interface with PSTR or old style
12209 code with progmem and pgm_read_xxx.
12212 if (avr_warn_addr_space_convert
12213 && expr != error_mark_node
12214 && POINTER_TYPE_P (type)
12215 && POINTER_TYPE_P (TREE_TYPE (expr)))
12217 addr_space_t as_old = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
12218 addr_space_t as_new = TYPE_ADDR_SPACE (TREE_TYPE (type));
12220 if (avr_log.progmem)
12221 avr_edump ("%?: type = %t\nexpr = %t\n\n", type, expr);
12223 if (as_new != ADDR_SPACE_MEMX
12224 && as_new != as_old)
12226 location_t loc = EXPR_LOCATION (expr);
12227 const char *name_old = avr_addrspace[as_old].name;
12228 const char *name_new = avr_addrspace[as_new].name;
12230 warning (OPT_Waddr_space_convert,
12231 "conversion from address space %qs to address space %qs",
12232 ADDR_SPACE_GENERIC_P (as_old) ? "generic" : name_old,
12233 ADDR_SPACE_GENERIC_P (as_new) ? "generic" : name_new);
12235 return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, expr);
12243 /* PR63633: The middle-end might come up with hard regs as input operands.
12245 RMASK is a bit mask representing a subset of hard registers R0...R31:
12246 Rn is an element of that set iff bit n of RMASK is set.
12247 OPMASK describes a subset of OP[]: If bit n of OPMASK is 1 then
12248 OP[n] has to be fixed; otherwise OP[n] is left alone.
12250 For each element of OPMASK which is a hard register overlapping RMASK,
12251 replace OP[n] with a newly created pseudo register
12253 HREG == 0: Also emit a move insn that copies the contents of that
12254 hard register into the new pseudo.
12256 HREG != 0: Also set HREG[n] to the hard register. */
12259 avr_fix_operands (rtx *op, rtx *hreg, unsigned opmask, unsigned rmask)
12261 for (; opmask; opmask >>= 1, op++)
12270 && REGNO (reg) < FIRST_PSEUDO_REGISTER
12271 // This hard-reg overlaps other prohibited hard regs?
12272 && (rmask & regmask (GET_MODE (reg), REGNO (reg))))
12274 *op = gen_reg_rtx (GET_MODE (reg));
12276 emit_move_insn (*op, reg);
12288 avr_fix_inputs (rtx *op, unsigned opmask, unsigned rmask)
12290 avr_fix_operands (op, NULL, opmask, rmask);
12294 /* Helper for the function below: If bit n of MASK is set and
12295 HREG[n] != NULL, then emit a move insn to copy OP[n] to HREG[n].
12296 Otherwise do nothing for that n. Return TRUE. */
12299 avr_move_fixed_operands (rtx *op, rtx *hreg, unsigned mask)
12301 for (; mask; mask >>= 1, op++, hreg++)
12304 emit_move_insn (*hreg, *op);
12310 /* PR63633: The middle-end might come up with hard regs as output operands.
12312 GEN is a sequence generating function like gen_mulsi3 with 3 operands OP[].
12313 RMASK is a bit mask representing a subset of hard registers R0...R31:
12314 Rn is an element of that set iff bit n of RMASK is set.
12315 OPMASK describes a subset of OP[]: If bit n of OPMASK is 1 then
12316 OP[n] has to be fixed; otherwise OP[n] is left alone.
12318 Emit the insn sequence as generated by GEN() with all elements of OPMASK
12319 which are hard registers overlapping RMASK replaced by newly created
12320 pseudo registers. After the sequence has been emitted, emit insns that
12321 move the contents of respective pseudos to their hard regs. */
12324 avr_emit3_fix_outputs (rtx (*gen)(rtx,rtx,rtx), rtx *op,
12325 unsigned opmask, unsigned rmask)
12330 /* It is letigimate for GEN to call this function, and in order not to
12331 get self-recursive we use the following static kludge. This is the
12332 only way not to duplicate all expanders and to avoid ugly and
12333 hard-to-maintain C-code instead of the much more appreciated RTL
12334 representation as supplied by define_expand. */
12335 static bool lock = false;
12337 gcc_assert (opmask < (1u << n));
12342 avr_fix_operands (op, hreg, opmask, rmask);
12345 emit_insn (gen (op[0], op[1], op[2]));
12348 return avr_move_fixed_operands (op, hreg, opmask);
12352 /* Worker function for movmemhi expander.
12353 XOP[0] Destination as MEM:BLK
12355 XOP[2] # Bytes to copy
12357 Return TRUE if the expansion is accomplished.
12358 Return FALSE if the operand compination is not supported. */
12361 avr_emit_movmemhi (rtx *xop)
12363 HOST_WIDE_INT count;
12364 machine_mode loop_mode;
12365 addr_space_t as = MEM_ADDR_SPACE (xop[1]);
12366 rtx loop_reg, addr1, a_src, a_dest, insn, xas;
12367 rtx a_hi8 = NULL_RTX;
12369 if (avr_mem_flash_p (xop[0]))
12372 if (!CONST_INT_P (xop[2]))
12375 count = INTVAL (xop[2]);
12379 a_src = XEXP (xop[1], 0);
12380 a_dest = XEXP (xop[0], 0);
12382 if (PSImode == GET_MODE (a_src))
12384 gcc_assert (as == ADDR_SPACE_MEMX);
12386 loop_mode = (count < 0x100) ? QImode : HImode;
12387 loop_reg = gen_rtx_REG (loop_mode, 24);
12388 emit_move_insn (loop_reg, gen_int_mode (count, loop_mode));
12390 addr1 = simplify_gen_subreg (HImode, a_src, PSImode, 0);
12391 a_hi8 = simplify_gen_subreg (QImode, a_src, PSImode, 2);
12395 int segment = avr_addrspace[as].segment;
12398 && avr_n_flash > 1)
12400 a_hi8 = GEN_INT (segment);
12401 emit_move_insn (rampz_rtx, a_hi8 = copy_to_mode_reg (QImode, a_hi8));
12403 else if (!ADDR_SPACE_GENERIC_P (as))
12405 as = ADDR_SPACE_FLASH;
12410 loop_mode = (count <= 0x100) ? QImode : HImode;
12411 loop_reg = copy_to_mode_reg (loop_mode, gen_int_mode (count, loop_mode));
12414 xas = GEN_INT (as);
12416 /* FIXME: Register allocator might come up with spill fails if it is left
12417 on its own. Thus, we allocate the pointer registers by hand:
12419 X = destination address */
12421 emit_move_insn (lpm_addr_reg_rtx, addr1);
12422 emit_move_insn (gen_rtx_REG (HImode, REG_X), a_dest);
12424 /* FIXME: Register allocator does a bad job and might spill address
12425 register(s) inside the loop leading to additional move instruction
12426 to/from stack which could clobber tmp_reg. Thus, do *not* emit
12427 load and store as separate insns. Instead, we perform the copy
12428 by means of one monolithic insn. */
12430 gcc_assert (TMP_REGNO == LPM_REGNO);
12432 if (as != ADDR_SPACE_MEMX)
12434 /* Load instruction ([E]LPM or LD) is known at compile time:
12435 Do the copy-loop inline. */
12437 rtx (*fun) (rtx, rtx, rtx)
12438 = QImode == loop_mode ? gen_movmem_qi : gen_movmem_hi;
12440 insn = fun (xas, loop_reg, loop_reg);
12444 rtx (*fun) (rtx, rtx)
12445 = QImode == loop_mode ? gen_movmemx_qi : gen_movmemx_hi;
12447 emit_move_insn (gen_rtx_REG (QImode, 23), a_hi8);
12449 insn = fun (xas, GEN_INT (avr_addr.rampz));
12452 set_mem_addr_space (SET_SRC (XVECEXP (insn, 0, 0)), as);
12459 /* Print assembler for movmem_qi, movmem_hi insns...
12461 $1, $2 : Loop register
12463 X : Destination address
12467 avr_out_movmem (rtx_insn *insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
12469 addr_space_t as = (addr_space_t) INTVAL (op[0]);
12470 machine_mode loop_mode = GET_MODE (op[1]);
12471 bool sbiw_p = test_hard_reg_class (ADDW_REGS, op[1]);
12479 xop[2] = tmp_reg_rtx;
12483 avr_asm_len ("0:", xop, plen, 0);
12485 /* Load with post-increment */
12492 case ADDR_SPACE_GENERIC:
12494 avr_asm_len ("ld %2,Z+", xop, plen, 1);
12497 case ADDR_SPACE_FLASH:
12500 avr_asm_len ("lpm %2,Z+", xop, plen, 1);
12502 avr_asm_len ("lpm" CR_TAB
12503 "adiw r30,1", xop, plen, 2);
12506 case ADDR_SPACE_FLASH1:
12507 case ADDR_SPACE_FLASH2:
12508 case ADDR_SPACE_FLASH3:
12509 case ADDR_SPACE_FLASH4:
12510 case ADDR_SPACE_FLASH5:
12512 if (AVR_HAVE_ELPMX)
12513 avr_asm_len ("elpm %2,Z+", xop, plen, 1);
12515 avr_asm_len ("elpm" CR_TAB
12516 "adiw r30,1", xop, plen, 2);
12520 /* Store with post-increment */
12522 avr_asm_len ("st X+,%2", xop, plen, 1);
12524 /* Decrement loop-counter and set Z-flag */
12526 if (QImode == loop_mode)
12528 avr_asm_len ("dec %1", xop, plen, 1);
12532 avr_asm_len ("sbiw %1,1", xop, plen, 1);
12536 avr_asm_len ("subi %A1,1" CR_TAB
12537 "sbci %B1,0", xop, plen, 2);
12540 /* Loop until zero */
12542 return avr_asm_len ("brne 0b", xop, plen, 1);
12547 /* Helper for __builtin_avr_delay_cycles */
12550 avr_mem_clobber (void)
12552 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12553 MEM_VOLATILE_P (mem) = 1;
12558 avr_expand_delay_cycles (rtx operands0)
12560 unsigned HOST_WIDE_INT cycles = UINTVAL (operands0) & GET_MODE_MASK (SImode);
12561 unsigned HOST_WIDE_INT cycles_used;
12562 unsigned HOST_WIDE_INT loop_count;
12564 if (IN_RANGE (cycles, 83886082, 0xFFFFFFFF))
12566 loop_count = ((cycles - 9) / 6) + 1;
12567 cycles_used = ((loop_count - 1) * 6) + 9;
12568 emit_insn (gen_delay_cycles_4 (gen_int_mode (loop_count, SImode),
12569 avr_mem_clobber()));
12570 cycles -= cycles_used;
12573 if (IN_RANGE (cycles, 262145, 83886081))
12575 loop_count = ((cycles - 7) / 5) + 1;
12576 if (loop_count > 0xFFFFFF)
12577 loop_count = 0xFFFFFF;
12578 cycles_used = ((loop_count - 1) * 5) + 7;
12579 emit_insn (gen_delay_cycles_3 (gen_int_mode (loop_count, SImode),
12580 avr_mem_clobber()));
12581 cycles -= cycles_used;
12584 if (IN_RANGE (cycles, 768, 262144))
12586 loop_count = ((cycles - 5) / 4) + 1;
12587 if (loop_count > 0xFFFF)
12588 loop_count = 0xFFFF;
12589 cycles_used = ((loop_count - 1) * 4) + 5;
12590 emit_insn (gen_delay_cycles_2 (gen_int_mode (loop_count, HImode),
12591 avr_mem_clobber()));
12592 cycles -= cycles_used;
12595 if (IN_RANGE (cycles, 6, 767))
12597 loop_count = cycles / 3;
12598 if (loop_count > 255)
12600 cycles_used = loop_count * 3;
12601 emit_insn (gen_delay_cycles_1 (gen_int_mode (loop_count, QImode),
12602 avr_mem_clobber()));
12603 cycles -= cycles_used;
12606 while (cycles >= 2)
12608 emit_insn (gen_nopv (GEN_INT(2)));
12614 emit_insn (gen_nopv (GEN_INT(1)));
12620 /* Compute the image of x under f, i.e. perform x --> f(x) */
12623 avr_map (unsigned int f, int x)
12625 return x < 8 ? (f >> (4 * x)) & 0xf : 0;
12629 /* Return some metrics of map A. */
12633 /* Number of fixed points in { 0 ... 7 } */
12636 /* Size of preimage of non-fixed points in { 0 ... 7 } */
12639 /* Mask representing the fixed points in { 0 ... 7 } */
12640 MAP_MASK_FIXED_0_7,
12642 /* Size of the preimage of { 0 ... 7 } */
12645 /* Mask that represents the preimage of { f } */
12646 MAP_MASK_PREIMAGE_F
12650 avr_map_metric (unsigned int a, int mode)
12652 unsigned i, metric = 0;
12654 for (i = 0; i < 8; i++)
12656 unsigned ai = avr_map (a, i);
12658 if (mode == MAP_FIXED_0_7)
12660 else if (mode == MAP_NONFIXED_0_7)
12661 metric += ai < 8 && ai != i;
12662 else if (mode == MAP_MASK_FIXED_0_7)
12663 metric |= ((unsigned) (ai == i)) << i;
12664 else if (mode == MAP_PREIMAGE_0_7)
12666 else if (mode == MAP_MASK_PREIMAGE_F)
12667 metric |= ((unsigned) (ai == 0xf)) << i;
12676 /* Return true if IVAL has a 0xf in its hexadecimal representation
12677 and false, otherwise. Only nibbles 0..7 are taken into account.
12678 Used as constraint helper for C0f and Cxf. */
12681 avr_has_nibble_0xf (rtx ival)
12683 unsigned int map = UINTVAL (ival) & GET_MODE_MASK (SImode);
12684 return 0 != avr_map_metric (map, MAP_MASK_PREIMAGE_F);
12688 /* We have a set of bits that are mapped by a function F.
12689 Try to decompose F by means of a second function G so that
12695 cost (F o G^-1) + cost (G) < cost (F)
12697 Example: Suppose builtin insert_bits supplies us with the map
12698 F = 0x3210ffff. Instead of doing 4 bit insertions to get the high
12699 nibble of the result, we can just as well rotate the bits before inserting
12700 them and use the map 0x7654ffff which is cheaper than the original map.
12701 For this example G = G^-1 = 0x32107654 and F o G^-1 = 0x7654ffff. */
12705 /* tree code of binary function G */
12706 enum tree_code code;
12708 /* The constant second argument of G */
12711 /* G^-1, the inverse of G (*, arg) */
12714 /* The cost of appplying G (*, arg) */
12717 /* The composition F o G^-1 (*, arg) for some function F */
12720 /* For debug purpose only */
12724 static const avr_map_op_t avr_map_op[] =
12726 { LROTATE_EXPR, 0, 0x76543210, 0, 0, "id" },
12727 { LROTATE_EXPR, 1, 0x07654321, 2, 0, "<<<" },
12728 { LROTATE_EXPR, 2, 0x10765432, 4, 0, "<<<" },
12729 { LROTATE_EXPR, 3, 0x21076543, 4, 0, "<<<" },
12730 { LROTATE_EXPR, 4, 0x32107654, 1, 0, "<<<" },
12731 { LROTATE_EXPR, 5, 0x43210765, 3, 0, "<<<" },
12732 { LROTATE_EXPR, 6, 0x54321076, 5, 0, "<<<" },
12733 { LROTATE_EXPR, 7, 0x65432107, 3, 0, "<<<" },
12734 { RSHIFT_EXPR, 1, 0x6543210c, 1, 0, ">>" },
12735 { RSHIFT_EXPR, 1, 0x7543210c, 1, 0, ">>" },
12736 { RSHIFT_EXPR, 2, 0x543210cc, 2, 0, ">>" },
12737 { RSHIFT_EXPR, 2, 0x643210cc, 2, 0, ">>" },
12738 { RSHIFT_EXPR, 2, 0x743210cc, 2, 0, ">>" },
12739 { LSHIFT_EXPR, 1, 0xc7654321, 1, 0, "<<" },
12740 { LSHIFT_EXPR, 2, 0xcc765432, 2, 0, "<<" }
12744 /* Try to decompose F as F = (F o G^-1) o G as described above.
12745 The result is a struct representing F o G^-1 and G.
12746 If result.cost < 0 then such a decomposition does not exist. */
12748 static avr_map_op_t
12749 avr_map_decompose (unsigned int f, const avr_map_op_t *g, bool val_const_p)
12752 bool val_used_p = 0 != avr_map_metric (f, MAP_MASK_PREIMAGE_F);
12753 avr_map_op_t f_ginv = *g;
12754 unsigned int ginv = g->ginv;
12758 /* Step 1: Computing F o G^-1 */
12760 for (i = 7; i >= 0; i--)
12762 int x = avr_map (f, i);
12766 x = avr_map (ginv, x);
12768 /* The bit is no element of the image of G: no avail (cost = -1) */
12774 f_ginv.map = (f_ginv.map << 4) + x;
12777 /* Step 2: Compute the cost of the operations.
12778 The overall cost of doing an operation prior to the insertion is
12779 the cost of the insertion plus the cost of the operation. */
12781 /* Step 2a: Compute cost of F o G^-1 */
12783 if (0 == avr_map_metric (f_ginv.map, MAP_NONFIXED_0_7))
12785 /* The mapping consists only of fixed points and can be folded
12786 to AND/OR logic in the remainder. Reasonable cost is 3. */
12788 f_ginv.cost = 2 + (val_used_p && !val_const_p);
12794 /* Get the cost of the insn by calling the output worker with some
12795 fake values. Mimic effect of reloading xop[3]: Unused operands
12796 are mapped to 0 and used operands are reloaded to xop[0]. */
12798 xop[0] = all_regs_rtx[24];
12799 xop[1] = gen_int_mode (f_ginv.map, SImode);
12800 xop[2] = all_regs_rtx[25];
12801 xop[3] = val_used_p ? xop[0] : const0_rtx;
12803 avr_out_insert_bits (xop, &f_ginv.cost);
12805 f_ginv.cost += val_const_p && val_used_p ? 1 : 0;
12808 /* Step 2b: Add cost of G */
12810 f_ginv.cost += g->cost;
12812 if (avr_log.builtin)
12813 avr_edump (" %s%d=%d", g->str, g->arg, f_ginv.cost);
12819 /* Insert bits from XOP[1] into XOP[0] according to MAP.
12820 XOP[0] and XOP[1] don't overlap.
12821 If FIXP_P = true: Move all bits according to MAP using BLD/BST sequences.
12822 If FIXP_P = false: Just move the bit if its position in the destination
12823 is different to its source position. */
12826 avr_move_bits (rtx *xop, unsigned int map, bool fixp_p, int *plen)
12830 /* T-flag contains this bit of the source, i.e. of XOP[1] */
12831 int t_bit_src = -1;
12833 /* We order the operations according to the requested source bit b. */
12835 for (b = 0; b < 8; b++)
12836 for (bit_dest = 0; bit_dest < 8; bit_dest++)
12838 int bit_src = avr_map (map, bit_dest);
12842 /* Same position: No need to copy as requested by FIXP_P. */
12843 || (bit_dest == bit_src && !fixp_p))
12846 if (t_bit_src != bit_src)
12848 /* Source bit is not yet in T: Store it to T. */
12850 t_bit_src = bit_src;
12852 xop[3] = GEN_INT (bit_src);
12853 avr_asm_len ("bst %T1%T3", xop, plen, 1);
12856 /* Load destination bit with T. */
12858 xop[3] = GEN_INT (bit_dest);
12859 avr_asm_len ("bld %T0%T3", xop, plen, 1);
12864 /* PLEN == 0: Print assembler code for `insert_bits'.
12865 PLEN != 0: Compute code length in bytes.
12868 OP[1]: The mapping composed of nibbles. If nibble no. N is
12869 0: Bit N of result is copied from bit OP[2].0
12871 7: Bit N of result is copied from bit OP[2].7
12872 0xf: Bit N of result is copied from bit OP[3].N
12873 OP[2]: Bits to be inserted
12874 OP[3]: Target value */
12877 avr_out_insert_bits (rtx *op, int *plen)
12879 unsigned int map = UINTVAL (op[1]) & GET_MODE_MASK (SImode);
12880 unsigned mask_fixed;
12881 bool fixp_p = true;
12888 gcc_assert (REG_P (xop[2]) || CONST_INT_P (xop[2]));
12892 else if (flag_print_asm_name)
12893 fprintf (asm_out_file, ASM_COMMENT_START "map = 0x%08x\n", map);
12895 /* If MAP has fixed points it might be better to initialize the result
12896 with the bits to be inserted instead of moving all bits by hand. */
12898 mask_fixed = avr_map_metric (map, MAP_MASK_FIXED_0_7);
12900 if (REGNO (xop[0]) == REGNO (xop[1]))
12902 /* Avoid early-clobber conflicts */
12904 avr_asm_len ("mov __tmp_reg__,%1", xop, plen, 1);
12905 xop[1] = tmp_reg_rtx;
12909 if (avr_map_metric (map, MAP_MASK_PREIMAGE_F))
12911 /* XOP[2] is used and reloaded to XOP[0] already */
12913 int n_fix = 0, n_nofix = 0;
12915 gcc_assert (REG_P (xop[2]));
12917 /* Get the code size of the bit insertions; once with all bits
12918 moved and once with fixed points omitted. */
12920 avr_move_bits (xop, map, true, &n_fix);
12921 avr_move_bits (xop, map, false, &n_nofix);
12923 if (fixp_p && n_fix - n_nofix > 3)
12925 xop[3] = gen_int_mode (~mask_fixed, QImode);
12927 avr_asm_len ("eor %0,%1" CR_TAB
12928 "andi %0,%3" CR_TAB
12929 "eor %0,%1", xop, plen, 3);
12935 /* XOP[2] is unused */
12937 if (fixp_p && mask_fixed)
12939 avr_asm_len ("mov %0,%1", xop, plen, 1);
12944 /* Move/insert remaining bits. */
12946 avr_move_bits (xop, map, fixp_p, plen);
12952 /* IDs for all the AVR builtins. */
12954 enum avr_builtin_id
12956 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME) \
12957 AVR_BUILTIN_ ## NAME,
12958 #include "builtins.def"
12964 struct GTY(()) avr_builtin_description
12966 enum insn_code icode;
12972 /* Notice that avr_bdesc[] and avr_builtin_id are initialized in such a way
12973 that a built-in's ID can be used to access the built-in by means of
12976 static GTY(()) struct avr_builtin_description
12977 avr_bdesc[AVR_BUILTIN_COUNT] =
12979 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, LIBNAME) \
12980 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
12981 #include "builtins.def"
12986 /* Implement `TARGET_BUILTIN_DECL'. */
12989 avr_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED)
12991 if (id < AVR_BUILTIN_COUNT)
12992 return avr_bdesc[id].fndecl;
12994 return error_mark_node;
12999 avr_init_builtin_int24 (void)
13001 tree int24_type = make_signed_type (GET_MODE_BITSIZE (PSImode));
13002 tree uint24_type = make_unsigned_type (GET_MODE_BITSIZE (PSImode));
13004 lang_hooks.types.register_builtin_type (int24_type, "__int24");
13005 lang_hooks.types.register_builtin_type (uint24_type, "__uint24");
13009 /* Implement `TARGET_INIT_BUILTINS' */
13010 /* Set up all builtin functions for this target. */
13013 avr_init_builtins (void)
13015 tree void_ftype_void
13016 = build_function_type_list (void_type_node, NULL_TREE);
13017 tree uchar_ftype_uchar
13018 = build_function_type_list (unsigned_char_type_node,
13019 unsigned_char_type_node,
13021 tree uint_ftype_uchar_uchar
13022 = build_function_type_list (unsigned_type_node,
13023 unsigned_char_type_node,
13024 unsigned_char_type_node,
13026 tree int_ftype_char_char
13027 = build_function_type_list (integer_type_node,
13031 tree int_ftype_char_uchar
13032 = build_function_type_list (integer_type_node,
13034 unsigned_char_type_node,
13036 tree void_ftype_ulong
13037 = build_function_type_list (void_type_node,
13038 long_unsigned_type_node,
13041 tree uchar_ftype_ulong_uchar_uchar
13042 = build_function_type_list (unsigned_char_type_node,
13043 long_unsigned_type_node,
13044 unsigned_char_type_node,
13045 unsigned_char_type_node,
13048 tree const_memx_void_node
13049 = build_qualified_type (void_type_node,
13051 | ENCODE_QUAL_ADDR_SPACE (ADDR_SPACE_MEMX));
13053 tree const_memx_ptr_type_node
13054 = build_pointer_type_for_mode (const_memx_void_node, PSImode, false);
13056 tree char_ftype_const_memx_ptr
13057 = build_function_type_list (char_type_node,
13058 const_memx_ptr_type_node,
13062 lang_hooks.types.type_for_size (TYPE_PRECISION (T), TYPE_UNSIGNED (T))
13064 #define FX_FTYPE_FX(fx) \
13065 tree fx##r_ftype_##fx##r \
13066 = build_function_type_list (node_##fx##r, node_##fx##r, NULL); \
13067 tree fx##k_ftype_##fx##k \
13068 = build_function_type_list (node_##fx##k, node_##fx##k, NULL)
13070 #define FX_FTYPE_FX_INT(fx) \
13071 tree fx##r_ftype_##fx##r_int \
13072 = build_function_type_list (node_##fx##r, node_##fx##r, \
13073 integer_type_node, NULL); \
13074 tree fx##k_ftype_##fx##k_int \
13075 = build_function_type_list (node_##fx##k, node_##fx##k, \
13076 integer_type_node, NULL)
13078 #define INT_FTYPE_FX(fx) \
13079 tree int_ftype_##fx##r \
13080 = build_function_type_list (integer_type_node, node_##fx##r, NULL); \
13081 tree int_ftype_##fx##k \
13082 = build_function_type_list (integer_type_node, node_##fx##k, NULL)
13084 #define INTX_FTYPE_FX(fx) \
13085 tree int##fx##r_ftype_##fx##r \
13086 = build_function_type_list (ITYP (node_##fx##r), node_##fx##r, NULL); \
13087 tree int##fx##k_ftype_##fx##k \
13088 = build_function_type_list (ITYP (node_##fx##k), node_##fx##k, NULL)
13090 #define FX_FTYPE_INTX(fx) \
13091 tree fx##r_ftype_int##fx##r \
13092 = build_function_type_list (node_##fx##r, ITYP (node_##fx##r), NULL); \
13093 tree fx##k_ftype_int##fx##k \
13094 = build_function_type_list (node_##fx##k, ITYP (node_##fx##k), NULL)
13096 tree node_hr = short_fract_type_node;
13097 tree node_nr = fract_type_node;
13098 tree node_lr = long_fract_type_node;
13099 tree node_llr = long_long_fract_type_node;
13101 tree node_uhr = unsigned_short_fract_type_node;
13102 tree node_unr = unsigned_fract_type_node;
13103 tree node_ulr = unsigned_long_fract_type_node;
13104 tree node_ullr = unsigned_long_long_fract_type_node;
13106 tree node_hk = short_accum_type_node;
13107 tree node_nk = accum_type_node;
13108 tree node_lk = long_accum_type_node;
13109 tree node_llk = long_long_accum_type_node;
13111 tree node_uhk = unsigned_short_accum_type_node;
13112 tree node_unk = unsigned_accum_type_node;
13113 tree node_ulk = unsigned_long_accum_type_node;
13114 tree node_ullk = unsigned_long_long_accum_type_node;
13117 /* For absfx builtins. */
13124 /* For roundfx builtins. */
13126 FX_FTYPE_FX_INT (h);
13127 FX_FTYPE_FX_INT (n);
13128 FX_FTYPE_FX_INT (l);
13129 FX_FTYPE_FX_INT (ll);
13131 FX_FTYPE_FX_INT (uh);
13132 FX_FTYPE_FX_INT (un);
13133 FX_FTYPE_FX_INT (ul);
13134 FX_FTYPE_FX_INT (ull);
13136 /* For countlsfx builtins. */
13146 INT_FTYPE_FX (ull);
13148 /* For bitsfx builtins. */
13153 INTX_FTYPE_FX (ll);
13155 INTX_FTYPE_FX (uh);
13156 INTX_FTYPE_FX (un);
13157 INTX_FTYPE_FX (ul);
13158 INTX_FTYPE_FX (ull);
13160 /* For fxbits builtins. */
13165 FX_FTYPE_INTX (ll);
13167 FX_FTYPE_INTX (uh);
13168 FX_FTYPE_INTX (un);
13169 FX_FTYPE_INTX (ul);
13170 FX_FTYPE_INTX (ull);
13173 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME) \
13175 int id = AVR_BUILTIN_ ## NAME; \
13176 const char *Name = "__builtin_avr_" #NAME; \
13177 char *name = (char*) alloca (1 + strlen (Name)); \
13179 gcc_assert (id < AVR_BUILTIN_COUNT); \
13180 avr_bdesc[id].fndecl \
13181 = add_builtin_function (avr_tolower (name, Name), TYPE, id, \
13182 BUILT_IN_MD, LIBNAME, NULL_TREE); \
13184 #include "builtins.def"
13187 avr_init_builtin_int24 ();
13191 /* Subroutine of avr_expand_builtin to expand vanilla builtins
13192 with non-void result and 1 ... 3 arguments. */
13195 avr_default_expand_builtin (enum insn_code icode, tree exp, rtx target)
13198 int n, n_args = call_expr_nargs (exp);
13199 machine_mode tmode = insn_data[icode].operand[0].mode;
13201 gcc_assert (n_args >= 1 && n_args <= 3);
13203 if (target == NULL_RTX
13204 || GET_MODE (target) != tmode
13205 || !insn_data[icode].operand[0].predicate (target, tmode))
13207 target = gen_reg_rtx (tmode);
13210 for (n = 0; n < n_args; n++)
13212 tree arg = CALL_EXPR_ARG (exp, n);
13213 rtx op = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
13214 machine_mode opmode = GET_MODE (op);
13215 machine_mode mode = insn_data[icode].operand[n+1].mode;
13217 if ((opmode == SImode || opmode == VOIDmode) && mode == HImode)
13220 op = gen_lowpart (HImode, op);
13223 /* In case the insn wants input operands in modes different from
13224 the result, abort. */
13226 gcc_assert (opmode == mode || opmode == VOIDmode);
13228 if (!insn_data[icode].operand[n+1].predicate (op, mode))
13229 op = copy_to_mode_reg (mode, op);
13236 case 1: pat = GEN_FCN (icode) (target, xop[0]); break;
13237 case 2: pat = GEN_FCN (icode) (target, xop[0], xop[1]); break;
13238 case 3: pat = GEN_FCN (icode) (target, xop[0], xop[1], xop[2]); break;
13244 if (pat == NULL_RTX)
13253 /* Implement `TARGET_EXPAND_BUILTIN'. */
13254 /* Expand an expression EXP that calls a built-in function,
13255 with result going to TARGET if that's convenient
13256 (and in mode MODE if that's convenient).
13257 SUBTARGET may be used as the target for computing one of EXP's operands.
13258 IGNORE is nonzero if the value is to be ignored. */
13261 avr_expand_builtin (tree exp, rtx target,
13262 rtx subtarget ATTRIBUTE_UNUSED,
13263 machine_mode mode ATTRIBUTE_UNUSED,
13266 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
13267 const char *bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
13268 unsigned int id = DECL_FUNCTION_CODE (fndecl);
13269 const struct avr_builtin_description *d = &avr_bdesc[id];
13273 gcc_assert (id < AVR_BUILTIN_COUNT);
13277 case AVR_BUILTIN_NOP:
13278 emit_insn (gen_nopv (GEN_INT(1)));
13281 case AVR_BUILTIN_DELAY_CYCLES:
13283 arg0 = CALL_EXPR_ARG (exp, 0);
13284 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
13286 if (!CONST_INT_P (op0))
13287 error ("%s expects a compile time integer constant", bname);
13289 avr_expand_delay_cycles (op0);
13294 case AVR_BUILTIN_INSERT_BITS:
13296 arg0 = CALL_EXPR_ARG (exp, 0);
13297 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
13299 if (!CONST_INT_P (op0))
13301 error ("%s expects a compile time long integer constant"
13302 " as first argument", bname);
13309 case AVR_BUILTIN_ROUNDHR: case AVR_BUILTIN_ROUNDUHR:
13310 case AVR_BUILTIN_ROUNDR: case AVR_BUILTIN_ROUNDUR:
13311 case AVR_BUILTIN_ROUNDLR: case AVR_BUILTIN_ROUNDULR:
13312 case AVR_BUILTIN_ROUNDLLR: case AVR_BUILTIN_ROUNDULLR:
13314 case AVR_BUILTIN_ROUNDHK: case AVR_BUILTIN_ROUNDUHK:
13315 case AVR_BUILTIN_ROUNDK: case AVR_BUILTIN_ROUNDUK:
13316 case AVR_BUILTIN_ROUNDLK: case AVR_BUILTIN_ROUNDULK:
13317 case AVR_BUILTIN_ROUNDLLK: case AVR_BUILTIN_ROUNDULLK:
13319 /* Warn about odd rounding. Rounding points >= FBIT will have
13322 if (TREE_CODE (CALL_EXPR_ARG (exp, 1)) != INTEGER_CST)
13325 int rbit = (int) TREE_INT_CST_LOW (CALL_EXPR_ARG (exp, 1));
13327 if (rbit >= (int) GET_MODE_FBIT (mode))
13329 warning (OPT_Wextra, "rounding to %d bits has no effect for "
13330 "fixed-point value with %d fractional bits",
13331 rbit, GET_MODE_FBIT (mode));
13333 return expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX, mode,
13336 else if (rbit <= - (int) GET_MODE_IBIT (mode))
13338 warning (0, "rounding result will always be 0");
13339 return CONST0_RTX (mode);
13342 /* The rounding points RP satisfies now: -IBIT < RP < FBIT.
13344 TR 18037 only specifies results for RP > 0. However, the
13345 remaining cases of -IBIT < RP <= 0 can easily be supported
13346 without any additional overhead. */
13351 /* No fold found and no insn: Call support function from libgcc. */
13353 if (d->icode == CODE_FOR_nothing
13354 && DECL_ASSEMBLER_NAME (get_callee_fndecl (exp)) != NULL_TREE)
13356 return expand_call (exp, target, ignore);
13359 /* No special treatment needed: vanilla expand. */
13361 gcc_assert (d->icode != CODE_FOR_nothing);
13362 gcc_assert (d->n_args == call_expr_nargs (exp));
13364 if (d->n_args == 0)
13366 emit_insn ((GEN_FCN (d->icode)) (target));
13370 return avr_default_expand_builtin (d->icode, exp, target);
13374 /* Helper for `avr_fold_builtin' that folds absfx (FIXED_CST). */
13377 avr_fold_absfx (tree tval)
13379 if (FIXED_CST != TREE_CODE (tval))
13382 /* Our fixed-points have no padding: Use double_int payload directly. */
13384 FIXED_VALUE_TYPE fval = TREE_FIXED_CST (tval);
13385 unsigned int bits = GET_MODE_BITSIZE (fval.mode);
13386 double_int ival = fval.data.sext (bits);
13388 if (!ival.is_negative())
13391 /* ISO/IEC TR 18037, 7.18a.6.2: The absfx functions are saturating. */
13393 fval.data = (ival == double_int::min_value (bits, false).sext (bits))
13394 ? double_int::max_value (bits, false)
13397 return build_fixed (TREE_TYPE (tval), fval);
13401 /* Implement `TARGET_FOLD_BUILTIN'. */
13404 avr_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg,
13405 bool ignore ATTRIBUTE_UNUSED)
13407 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
13408 tree val_type = TREE_TYPE (TREE_TYPE (fndecl));
13418 case AVR_BUILTIN_SWAP:
13420 return fold_build2 (LROTATE_EXPR, val_type, arg[0],
13421 build_int_cst (val_type, 4));
13424 case AVR_BUILTIN_ABSHR:
13425 case AVR_BUILTIN_ABSR:
13426 case AVR_BUILTIN_ABSLR:
13427 case AVR_BUILTIN_ABSLLR:
13429 case AVR_BUILTIN_ABSHK:
13430 case AVR_BUILTIN_ABSK:
13431 case AVR_BUILTIN_ABSLK:
13432 case AVR_BUILTIN_ABSLLK:
13433 /* GCC is not good with folding ABS for fixed-point. Do it by hand. */
13435 return avr_fold_absfx (arg[0]);
13437 case AVR_BUILTIN_BITSHR: case AVR_BUILTIN_HRBITS:
13438 case AVR_BUILTIN_BITSHK: case AVR_BUILTIN_HKBITS:
13439 case AVR_BUILTIN_BITSUHR: case AVR_BUILTIN_UHRBITS:
13440 case AVR_BUILTIN_BITSUHK: case AVR_BUILTIN_UHKBITS:
13442 case AVR_BUILTIN_BITSR: case AVR_BUILTIN_RBITS:
13443 case AVR_BUILTIN_BITSK: case AVR_BUILTIN_KBITS:
13444 case AVR_BUILTIN_BITSUR: case AVR_BUILTIN_URBITS:
13445 case AVR_BUILTIN_BITSUK: case AVR_BUILTIN_UKBITS:
13447 case AVR_BUILTIN_BITSLR: case AVR_BUILTIN_LRBITS:
13448 case AVR_BUILTIN_BITSLK: case AVR_BUILTIN_LKBITS:
13449 case AVR_BUILTIN_BITSULR: case AVR_BUILTIN_ULRBITS:
13450 case AVR_BUILTIN_BITSULK: case AVR_BUILTIN_ULKBITS:
13452 case AVR_BUILTIN_BITSLLR: case AVR_BUILTIN_LLRBITS:
13453 case AVR_BUILTIN_BITSLLK: case AVR_BUILTIN_LLKBITS:
13454 case AVR_BUILTIN_BITSULLR: case AVR_BUILTIN_ULLRBITS:
13455 case AVR_BUILTIN_BITSULLK: case AVR_BUILTIN_ULLKBITS:
13457 gcc_assert (TYPE_PRECISION (val_type)
13458 == TYPE_PRECISION (TREE_TYPE (arg[0])));
13460 return build1 (VIEW_CONVERT_EXPR, val_type, arg[0]);
13462 case AVR_BUILTIN_INSERT_BITS:
13464 tree tbits = arg[1];
13465 tree tval = arg[2];
13467 tree map_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
13469 bool changed = false;
13471 avr_map_op_t best_g;
13473 if (TREE_CODE (arg[0]) != INTEGER_CST)
13475 /* No constant as first argument: Don't fold this and run into
13476 error in avr_expand_builtin. */
13481 tmap = wide_int_to_tree (map_type, arg[0]);
13482 map = TREE_INT_CST_LOW (tmap);
13484 if (TREE_CODE (tval) != INTEGER_CST
13485 && 0 == avr_map_metric (map, MAP_MASK_PREIMAGE_F))
13487 /* There are no F in the map, i.e. 3rd operand is unused.
13488 Replace that argument with some constant to render
13489 respective input unused. */
13491 tval = build_int_cst (val_type, 0);
13495 if (TREE_CODE (tbits) != INTEGER_CST
13496 && 0 == avr_map_metric (map, MAP_PREIMAGE_0_7))
13498 /* Similar for the bits to be inserted. If they are unused,
13499 we can just as well pass 0. */
13501 tbits = build_int_cst (val_type, 0);
13504 if (TREE_CODE (tbits) == INTEGER_CST)
13506 /* Inserting bits known at compile time is easy and can be
13507 performed by AND and OR with appropriate masks. */
13509 int bits = TREE_INT_CST_LOW (tbits);
13510 int mask_ior = 0, mask_and = 0xff;
13512 for (i = 0; i < 8; i++)
13514 int mi = avr_map (map, i);
13518 if (bits & (1 << mi)) mask_ior |= (1 << i);
13519 else mask_and &= ~(1 << i);
13523 tval = fold_build2 (BIT_IOR_EXPR, val_type, tval,
13524 build_int_cst (val_type, mask_ior));
13525 return fold_build2 (BIT_AND_EXPR, val_type, tval,
13526 build_int_cst (val_type, mask_and));
13530 return build_call_expr (fndecl, 3, tmap, tbits, tval);
13532 /* If bits don't change their position we can use vanilla logic
13533 to merge the two arguments. */
13535 if (0 == avr_map_metric (map, MAP_NONFIXED_0_7))
13537 int mask_f = avr_map_metric (map, MAP_MASK_PREIMAGE_F);
13538 tree tres, tmask = build_int_cst (val_type, mask_f ^ 0xff);
13540 tres = fold_build2 (BIT_XOR_EXPR, val_type, tbits, tval);
13541 tres = fold_build2 (BIT_AND_EXPR, val_type, tres, tmask);
13542 return fold_build2 (BIT_XOR_EXPR, val_type, tres, tval);
13545 /* Try to decomposing map to reduce overall cost. */
13547 if (avr_log.builtin)
13548 avr_edump ("\n%?: %x\n%?: ROL cost: ", map);
13550 best_g = avr_map_op[0];
13551 best_g.cost = 1000;
13553 for (i = 0; i < sizeof (avr_map_op) / sizeof (*avr_map_op); i++)
13556 = avr_map_decompose (map, avr_map_op + i,
13557 TREE_CODE (tval) == INTEGER_CST);
13559 if (g.cost >= 0 && g.cost < best_g.cost)
13563 if (avr_log.builtin)
13566 if (best_g.arg == 0)
13567 /* No optimization found */
13570 /* Apply operation G to the 2nd argument. */
13572 if (avr_log.builtin)
13573 avr_edump ("%?: using OP(%s%d, %x) cost %d\n",
13574 best_g.str, best_g.arg, best_g.map, best_g.cost);
13576 /* Do right-shifts arithmetically: They copy the MSB instead of
13577 shifting in a non-usable value (0) as with logic right-shift. */
13579 tbits = fold_convert (signed_char_type_node, tbits);
13580 tbits = fold_build2 (best_g.code, signed_char_type_node, tbits,
13581 build_int_cst (val_type, best_g.arg));
13582 tbits = fold_convert (val_type, tbits);
13584 /* Use map o G^-1 instead of original map to undo the effect of G. */
13586 tmap = wide_int_to_tree (map_type, best_g.map);
13588 return build_call_expr (fndecl, 3, tmap, tbits, tval);
13589 } /* AVR_BUILTIN_INSERT_BITS */
13597 /* Initialize the GCC target structure. */
13599 #undef TARGET_ASM_ALIGNED_HI_OP
13600 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
13601 #undef TARGET_ASM_ALIGNED_SI_OP
13602 #define TARGET_ASM_ALIGNED_SI_OP "\t.long\t"
13603 #undef TARGET_ASM_UNALIGNED_HI_OP
13604 #define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
13605 #undef TARGET_ASM_UNALIGNED_SI_OP
13606 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
13607 #undef TARGET_ASM_INTEGER
13608 #define TARGET_ASM_INTEGER avr_assemble_integer
13609 #undef TARGET_ASM_FILE_START
13610 #define TARGET_ASM_FILE_START avr_file_start
13611 #undef TARGET_ASM_FILE_END
13612 #define TARGET_ASM_FILE_END avr_file_end
13614 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
13615 #define TARGET_ASM_FUNCTION_END_PROLOGUE avr_asm_function_end_prologue
13616 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
13617 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE avr_asm_function_begin_epilogue
13619 #undef TARGET_FUNCTION_VALUE
13620 #define TARGET_FUNCTION_VALUE avr_function_value
13621 #undef TARGET_LIBCALL_VALUE
13622 #define TARGET_LIBCALL_VALUE avr_libcall_value
13623 #undef TARGET_FUNCTION_VALUE_REGNO_P
13624 #define TARGET_FUNCTION_VALUE_REGNO_P avr_function_value_regno_p
13626 #undef TARGET_ATTRIBUTE_TABLE
13627 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
13628 #undef TARGET_INSERT_ATTRIBUTES
13629 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
13630 #undef TARGET_SECTION_TYPE_FLAGS
13631 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
13633 #undef TARGET_ASM_NAMED_SECTION
13634 #define TARGET_ASM_NAMED_SECTION avr_asm_named_section
13635 #undef TARGET_ASM_INIT_SECTIONS
13636 #define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections
13637 #undef TARGET_ENCODE_SECTION_INFO
13638 #define TARGET_ENCODE_SECTION_INFO avr_encode_section_info
13639 #undef TARGET_ASM_SELECT_SECTION
13640 #define TARGET_ASM_SELECT_SECTION avr_asm_select_section
13642 #undef TARGET_REGISTER_MOVE_COST
13643 #define TARGET_REGISTER_MOVE_COST avr_register_move_cost
13644 #undef TARGET_MEMORY_MOVE_COST
13645 #define TARGET_MEMORY_MOVE_COST avr_memory_move_cost
13646 #undef TARGET_RTX_COSTS
13647 #define TARGET_RTX_COSTS avr_rtx_costs
13648 #undef TARGET_ADDRESS_COST
13649 #define TARGET_ADDRESS_COST avr_address_cost
13650 #undef TARGET_MACHINE_DEPENDENT_REORG
13651 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
13652 #undef TARGET_FUNCTION_ARG
13653 #define TARGET_FUNCTION_ARG avr_function_arg
13654 #undef TARGET_FUNCTION_ARG_ADVANCE
13655 #define TARGET_FUNCTION_ARG_ADVANCE avr_function_arg_advance
13657 #undef TARGET_SET_CURRENT_FUNCTION
13658 #define TARGET_SET_CURRENT_FUNCTION avr_set_current_function
13660 #undef TARGET_RETURN_IN_MEMORY
13661 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
13663 #undef TARGET_STRICT_ARGUMENT_NAMING
13664 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
13666 #undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
13667 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE avr_builtin_setjmp_frame_value
13669 #undef TARGET_CONDITIONAL_REGISTER_USAGE
13670 #define TARGET_CONDITIONAL_REGISTER_USAGE avr_conditional_register_usage
13672 #undef TARGET_HARD_REGNO_SCRATCH_OK
13673 #define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok
13674 #undef TARGET_CASE_VALUES_THRESHOLD
13675 #define TARGET_CASE_VALUES_THRESHOLD avr_case_values_threshold
13677 #undef TARGET_FRAME_POINTER_REQUIRED
13678 #define TARGET_FRAME_POINTER_REQUIRED avr_frame_pointer_required_p
13679 #undef TARGET_CAN_ELIMINATE
13680 #define TARGET_CAN_ELIMINATE avr_can_eliminate
13682 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
13683 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS avr_allocate_stack_slots_for_args
13685 #undef TARGET_WARN_FUNC_RETURN
13686 #define TARGET_WARN_FUNC_RETURN avr_warn_func_return
13688 #undef TARGET_CLASS_LIKELY_SPILLED_P
13689 #define TARGET_CLASS_LIKELY_SPILLED_P avr_class_likely_spilled_p
13691 #undef TARGET_OPTION_OVERRIDE
13692 #define TARGET_OPTION_OVERRIDE avr_option_override
13694 #undef TARGET_CANNOT_MODIFY_JUMPS_P
13695 #define TARGET_CANNOT_MODIFY_JUMPS_P avr_cannot_modify_jumps_p
13697 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
13698 #define TARGET_FUNCTION_OK_FOR_SIBCALL avr_function_ok_for_sibcall
13700 #undef TARGET_INIT_BUILTINS
13701 #define TARGET_INIT_BUILTINS avr_init_builtins
13703 #undef TARGET_BUILTIN_DECL
13704 #define TARGET_BUILTIN_DECL avr_builtin_decl
13706 #undef TARGET_EXPAND_BUILTIN
13707 #define TARGET_EXPAND_BUILTIN avr_expand_builtin
13709 #undef TARGET_FOLD_BUILTIN
13710 #define TARGET_FOLD_BUILTIN avr_fold_builtin
13712 #undef TARGET_SCALAR_MODE_SUPPORTED_P
13713 #define TARGET_SCALAR_MODE_SUPPORTED_P avr_scalar_mode_supported_p
13715 #undef TARGET_BUILD_BUILTIN_VA_LIST
13716 #define TARGET_BUILD_BUILTIN_VA_LIST avr_build_builtin_va_list
13718 #undef TARGET_FIXED_POINT_SUPPORTED_P
13719 #define TARGET_FIXED_POINT_SUPPORTED_P hook_bool_void_true
13721 #undef TARGET_CONVERT_TO_TYPE
13722 #define TARGET_CONVERT_TO_TYPE avr_convert_to_type
13724 #undef TARGET_ADDR_SPACE_SUBSET_P
13725 #define TARGET_ADDR_SPACE_SUBSET_P avr_addr_space_subset_p
13727 #undef TARGET_ADDR_SPACE_CONVERT
13728 #define TARGET_ADDR_SPACE_CONVERT avr_addr_space_convert
13730 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
13731 #define TARGET_ADDR_SPACE_ADDRESS_MODE avr_addr_space_address_mode
13733 #undef TARGET_ADDR_SPACE_POINTER_MODE
13734 #define TARGET_ADDR_SPACE_POINTER_MODE avr_addr_space_pointer_mode
13736 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
13737 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
13738 avr_addr_space_legitimate_address_p
13740 #undef TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS
13741 #define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS avr_addr_space_legitimize_address
13743 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
13744 #define TARGET_MODE_DEPENDENT_ADDRESS_P avr_mode_dependent_address_p
13746 #undef TARGET_SECONDARY_RELOAD
13747 #define TARGET_SECONDARY_RELOAD avr_secondary_reload
13749 #undef TARGET_PRINT_OPERAND
13750 #define TARGET_PRINT_OPERAND avr_print_operand
13751 #undef TARGET_PRINT_OPERAND_ADDRESS
13752 #define TARGET_PRINT_OPERAND_ADDRESS avr_print_operand_address
13753 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
13754 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P avr_print_operand_punct_valid_p
13756 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
13757 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
13758 avr_use_by_pieces_infrastructure_p
13760 struct gcc_target targetm = TARGET_INITIALIZER;
13763 #include "gt-avr.h"