1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2 Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3 Contributed by Denis Chertykov (denisc@overta.ru)
5 This file is part of GNU CC.
7 GNU CC 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 2, or (at your option)
12 GNU CC 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 GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
24 #include "coretypes.h"
28 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-attr.h"
44 #include "target-def.h"
46 /* Maximal allowed offset for an address in the LD command */
47 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
49 static int avr_naked_function_p PARAMS ((tree));
50 static int interrupt_function_p PARAMS ((tree));
51 static int signal_function_p PARAMS ((tree));
52 static int avr_regs_to_save PARAMS ((HARD_REG_SET *));
53 static int sequent_regs_live PARAMS ((void));
54 static const char * ptrreg_to_str PARAMS ((int));
55 static const char * cond_string PARAMS ((enum rtx_code));
56 static int avr_num_arg_regs PARAMS ((enum machine_mode, tree));
57 static int out_adj_frame_ptr PARAMS ((FILE *, int));
58 static int out_set_stack_ptr PARAMS ((FILE *, int, int));
59 static RTX_CODE compare_condition PARAMS ((rtx insn));
60 static int compare_sign_p PARAMS ((rtx insn));
61 static int reg_was_0 PARAMS ((rtx insn, rtx op));
62 static tree avr_handle_progmem_attribute PARAMS ((tree *, tree, tree, int, bool *));
63 static tree avr_handle_fndecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
64 const struct attribute_spec avr_attribute_table[];
65 static bool avr_assemble_integer PARAMS ((rtx, unsigned int, int));
66 static void avr_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
67 static void avr_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
68 static void avr_unique_section PARAMS ((tree, int));
69 static void avr_insert_attributes PARAMS ((tree, tree *));
70 static unsigned int avr_section_type_flags PARAMS ((tree, const char *, int));
72 static void avr_asm_out_ctor PARAMS ((rtx, int));
73 static void avr_asm_out_dtor PARAMS ((rtx, int));
74 static int default_rtx_costs PARAMS ((rtx, enum rtx_code, enum rtx_code));
75 static bool avr_rtx_costs PARAMS ((rtx, int, int, int *));
76 static int avr_address_cost PARAMS ((rtx));
78 /* Allocate registers from r25 to r8 for parameters for function calls */
79 #define FIRST_CUM_REG 26
81 /* Temporary register RTX (gen_rtx (REG,QImode,TMP_REGNO)) */
84 /* Zeroed register RTX (gen_rtx (REG,QImode,ZERO_REGNO)) */
87 /* RTX for register which will be used for loading immediate values to
91 /* AVR register names {"r0", "r1", ..., "r31"} */
92 static const char *const avr_regnames[] = REGISTER_NAMES;
94 /* This holds the last insn address. */
95 static int last_insn_address = 0;
97 /* Commands count in the compiled file */
98 static int commands_in_file;
100 /* Commands in the functions prologues in the compiled file */
101 static int commands_in_prologues;
103 /* Commands in the functions epilogues in the compiled file */
104 static int commands_in_epilogues;
106 /* Prologue/Epilogue size in words */
107 static int prologue_size;
108 static int epilogue_size;
110 /* Size of all jump tables in the current function, in words. */
111 static int jump_tables_size;
113 /* Initial stack value specified by the `-minit-stack=' option */
114 const char *avr_init_stack = "__stack";
116 /* Default MCU name */
117 const char *avr_mcu_name = "avr2";
119 /* Preprocessor macros to define depending on MCU type. */
120 const char *avr_base_arch_macro;
121 const char *avr_extra_arch_macro;
123 /* More than 8K of program memory: use "call" and "jmp". */
126 /* Enhanced core: use "movw", "mul", ... */
127 int avr_enhanced_p = 0;
129 /* Assembler only. */
130 int avr_asm_only_p = 0;
136 const char *const macro;
139 static const struct base_arch_s avr_arch_types[] = {
140 { 1, 0, 0, NULL }, /* unknown device specified */
141 { 1, 0, 0, "__AVR_ARCH__=1" },
142 { 0, 0, 0, "__AVR_ARCH__=2" },
143 { 0, 0, 1, "__AVR_ARCH__=3" },
144 { 0, 1, 0, "__AVR_ARCH__=4" },
145 { 0, 1, 1, "__AVR_ARCH__=5" }
149 const char *const name;
150 int arch; /* index in avr_arch_types[] */
151 /* Must lie outside user's namespace. NULL == no macro. */
152 const char *const macro;
155 /* List of all known AVR MCU types - if updated, it has to be kept
156 in sync in several places (FIXME: is there a better way?):
158 - avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
159 - t-avr (MULTILIB_MATCHES)
160 - gas/config/tc-avr.c
163 static const struct mcu_type_s avr_mcu_types[] = {
164 /* Classic, <= 8K. */
166 { "at90s2313", 2, "__AVR_AT90S2313__" },
167 { "at90s2323", 2, "__AVR_AT90S2323__" },
168 { "at90s2333", 2, "__AVR_AT90S2333__" },
169 { "at90s2343", 2, "__AVR_AT90S2343__" },
170 { "attiny22", 2, "__AVR_ATtiny22__" },
171 { "attiny26", 2, "__AVR_ATtiny26__" },
172 { "at90s4414", 2, "__AVR_AT90S4414__" },
173 { "at90s4433", 2, "__AVR_AT90S4433__" },
174 { "at90s4434", 2, "__AVR_AT90S4434__" },
175 { "at90s8515", 2, "__AVR_AT90S8515__" },
176 { "at90c8534", 2, "__AVR_AT90C8534__" },
177 { "at90s8535", 2, "__AVR_AT90S8535__" },
178 { "at86rf401", 2, "__AVR_AT86RF401__" },
181 { "atmega103", 3, "__AVR_ATmega103__" },
182 { "atmega603", 3, "__AVR_ATmega603__" },
183 { "at43usb320", 3, "__AVR_AT43USB320__" },
184 { "at43usb355", 3, "__AVR_AT43USB355__" },
185 { "at76c711", 3, "__AVR_AT76C711__" },
186 /* Enhanced, <= 8K. */
188 { "atmega8", 4, "__AVR_ATmega8__" },
189 { "atmega8515", 4, "__AVR_ATmega8515__" },
190 { "atmega8535", 4, "__AVR_ATmega8535__" },
191 /* Enhanced, > 8K. */
193 { "atmega16", 5, "__AVR_ATmega16__" },
194 { "atmega161", 5, "__AVR_ATmega161__" },
195 { "atmega162", 5, "__AVR_ATmega162__" },
196 { "atmega163", 5, "__AVR_ATmega163__" },
197 { "atmega169", 5, "__AVR_ATmega169__" },
198 { "atmega32", 5, "__AVR_ATmega32__" },
199 { "atmega323", 5, "__AVR_ATmega323__" },
200 { "atmega64", 5, "__AVR_ATmega64__" },
201 { "atmega128", 5, "__AVR_ATmega128__" },
202 { "at94k", 5, "__AVR_AT94K__" },
203 /* Assembler only. */
205 { "at90s1200", 1, "__AVR_AT90S1200__" },
206 { "attiny11", 1, "__AVR_ATtiny11__" },
207 { "attiny12", 1, "__AVR_ATtiny12__" },
208 { "attiny15", 1, "__AVR_ATtiny15__" },
209 { "attiny28", 1, "__AVR_ATtiny28__" },
213 int avr_case_values_threshold = 30000;
215 /* Initialize the GCC target structure. */
216 #undef TARGET_ASM_ALIGNED_HI_OP
217 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
218 #undef TARGET_ASM_INTEGER
219 #define TARGET_ASM_INTEGER avr_assemble_integer
221 #undef TARGET_ASM_FUNCTION_PROLOGUE
222 #define TARGET_ASM_FUNCTION_PROLOGUE avr_output_function_prologue
223 #undef TARGET_ASM_FUNCTION_EPILOGUE
224 #define TARGET_ASM_FUNCTION_EPILOGUE avr_output_function_epilogue
225 #undef TARGET_ATTRIBUTE_TABLE
226 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
227 #undef TARGET_ASM_UNIQUE_SECTION
228 #define TARGET_ASM_UNIQUE_SECTION avr_unique_section
229 #undef TARGET_INSERT_ATTRIBUTES
230 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
231 #undef TARGET_SECTION_TYPE_FLAGS
232 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
233 #undef TARGET_RTX_COSTS
234 #define TARGET_RTX_COSTS avr_rtx_costs
235 #undef TARGET_ADDRESS_COST
236 #define TARGET_ADDRESS_COST avr_address_cost
238 struct gcc_target targetm = TARGET_INITIALIZER;
241 avr_override_options ()
243 const struct mcu_type_s *t;
244 const struct base_arch_s *base;
246 for (t = avr_mcu_types; t->name; t++)
247 if (strcmp (t->name, avr_mcu_name) == 0)
252 fprintf (stderr, "unknown MCU `%s' specified\nKnown MCU names:\n",
254 for (t = avr_mcu_types; t->name; t++)
255 fprintf (stderr," %s\n", t->name);
258 base = &avr_arch_types[t->arch];
259 avr_asm_only_p = base->asm_only;
260 avr_enhanced_p = base->enhanced;
261 avr_mega_p = base->mega;
262 avr_base_arch_macro = base->macro;
263 avr_extra_arch_macro = t->macro;
265 if (optimize && !TARGET_NO_TABLEJUMP)
266 avr_case_values_threshold = (!AVR_MEGA || TARGET_CALL_PROLOGUES) ? 8 : 17;
270 /* Initialize TMP_REG_RTX and ZERO_REG_RTX */
274 tmp_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
275 memset (tmp_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
276 PUT_CODE (tmp_reg_rtx, REG);
277 PUT_MODE (tmp_reg_rtx, QImode);
278 XINT (tmp_reg_rtx, 0) = TMP_REGNO;
280 zero_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
281 memset (zero_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
282 PUT_CODE (zero_reg_rtx, REG);
283 PUT_MODE (zero_reg_rtx, QImode);
284 XINT (zero_reg_rtx, 0) = ZERO_REGNO;
286 ldi_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
287 memset (ldi_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
288 PUT_CODE (ldi_reg_rtx, REG);
289 PUT_MODE (ldi_reg_rtx, QImode);
290 XINT (ldi_reg_rtx, 0) = LDI_REG_REGNO;
293 /* return register class from register number */
295 static const int reg_class_tab[]={
296 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
297 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
298 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
299 GENERAL_REGS, /* r0 - r15 */
300 LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
301 LD_REGS, /* r16 - 23 */
302 ADDW_REGS,ADDW_REGS, /* r24,r25 */
303 POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
304 POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
305 POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
306 STACK_REG,STACK_REG /* SPL,SPH */
309 /* Return register class for register R */
312 avr_regno_reg_class (r)
316 return reg_class_tab[r];
321 /* A C expression which defines the machine-dependent operand
322 constraint letters for register classes. If C is such a
323 letter, the value should be the register class corresponding to
324 it. Otherwise, the value should be `NO_REGS'. The register
325 letter `r', corresponding to class `GENERAL_REGS', will not be
326 passed to this macro; you do not need to handle it. */
329 avr_reg_class_from_letter (c)
334 case 't' : return R0_REG;
335 case 'b' : return BASE_POINTER_REGS;
336 case 'e' : return POINTER_REGS;
337 case 'w' : return ADDW_REGS;
338 case 'd' : return LD_REGS;
339 case 'l' : return NO_LD_REGS;
340 case 'a' : return SIMPLE_LD_REGS;
341 case 'x' : return POINTER_X_REGS;
342 case 'y' : return POINTER_Y_REGS;
343 case 'z' : return POINTER_Z_REGS;
344 case 'q' : return STACK_REG;
350 /* Return nonzero if FUNC is a naked function. */
353 avr_naked_function_p (func)
358 if (TREE_CODE (func) != FUNCTION_DECL)
361 a = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
362 return a != NULL_TREE;
365 /* Return nonzero if FUNC is an interrupt function as specified
366 by the "interrupt" attribute. */
369 interrupt_function_p (func)
374 if (TREE_CODE (func) != FUNCTION_DECL)
377 a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
378 return a != NULL_TREE;
381 /* Return nonzero if FUNC is a signal function as specified
382 by the "signal" attribute. */
385 signal_function_p (func)
390 if (TREE_CODE (func) != FUNCTION_DECL)
393 a = lookup_attribute ("signal", DECL_ATTRIBUTES (func));
394 return a != NULL_TREE;
397 /* Return the number of hard registers to push/pop in the prologue/epilogue
398 of the current function, and optionally store these registers in SET. */
401 avr_regs_to_save (set)
405 int int_or_sig_p = (interrupt_function_p (current_function_decl)
406 || signal_function_p (current_function_decl));
407 int leaf_func_p = leaf_function_p ();
410 CLEAR_HARD_REG_SET (*set);
413 /* No need to save any registers if the function never returns. */
414 if (TREE_THIS_VOLATILE (current_function_decl))
417 for (reg = 0; reg < 32; reg++)
419 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
420 any global register variables. */
424 if ((int_or_sig_p && !leaf_func_p && call_used_regs[reg])
425 || (regs_ever_live[reg]
426 && (int_or_sig_p || !call_used_regs[reg])
427 && !(frame_pointer_needed
428 && (reg == REG_Y || reg == (REG_Y+1)))))
431 SET_HARD_REG_BIT (*set, reg);
438 /* Compute offset between arg_pointer and frame_pointer */
441 initial_elimination_offset (from, to)
445 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
449 int offset = frame_pointer_needed ? 2 : 0;
451 offset += avr_regs_to_save (NULL);
452 return get_frame_size () + 2 + 1 + offset;
456 /* Return 1 if the function epilogue is just a single "ret". */
459 avr_simple_epilogue ()
461 return (! frame_pointer_needed
462 && get_frame_size () == 0
463 && avr_regs_to_save (NULL) == 0
464 && ! interrupt_function_p (current_function_decl)
465 && ! signal_function_p (current_function_decl)
466 && ! avr_naked_function_p (current_function_decl)
467 && ! MAIN_NAME_P (DECL_NAME (current_function_decl))
468 && ! TREE_THIS_VOLATILE (current_function_decl));
471 /* This function checks sequence of live registers */
480 for (reg = 0; reg < 18; ++reg)
482 if (!call_used_regs[reg])
484 if (regs_ever_live[reg])
494 if (!frame_pointer_needed)
496 if (regs_ever_live[REG_Y])
504 if (regs_ever_live[REG_Y+1])
517 return (cur_seq == live_seq) ? live_seq : 0;
521 /* Output to FILE the asm instructions to adjust the frame pointer by
522 ADJ (r29:r28 -= ADJ;) which can be positive (prologue) or negative
523 (epilogue). Returns the number of instructions generated. */
526 out_adj_frame_ptr (file, adj)
534 if (TARGET_TINY_STACK)
536 if (adj < -63 || adj > 63)
537 warning ("large frame pointer change (%d) with -mtiny-stack", adj);
539 /* The high byte (r29) doesn't change - prefer "subi" (1 cycle)
540 over "sbiw" (2 cycles, same size). */
542 fprintf (file, (AS2 (subi, r28, %d) CR_TAB), adj);
545 else if (adj < -63 || adj > 63)
547 fprintf (file, (AS2 (subi, r28, lo8(%d)) CR_TAB
548 AS2 (sbci, r29, hi8(%d)) CR_TAB),
554 fprintf (file, (AS2 (adiw, r28, %d) CR_TAB), -adj);
559 fprintf (file, (AS2 (sbiw, r28, %d) CR_TAB), adj);
567 /* Output to FILE the asm instructions to copy r29:r28 to SPH:SPL,
568 handling various cases of interrupt enable flag state BEFORE and AFTER
569 (0=disabled, 1=enabled, -1=unknown/unchanged) and target_flags.
570 Returns the number of instructions generated. */
573 out_set_stack_ptr (file, before, after)
578 int do_sph, do_cli, do_save, do_sei, lock_sph, size;
580 /* The logic here is so that -mno-interrupts actually means
581 "it is safe to write SPH in one instruction, then SPL in the
582 next instruction, without disabling interrupts first".
583 The after != -1 case (interrupt/signal) is not affected. */
585 do_sph = !TARGET_TINY_STACK;
586 lock_sph = do_sph && !TARGET_NO_INTERRUPTS;
587 do_cli = (before != 0 && (after == 0 || lock_sph));
588 do_save = (do_cli && before == -1 && after == -1);
589 do_sei = ((do_cli || before != 1) && after == 1);
594 fprintf (file, AS2 (in, __tmp_reg__, __SREG__) CR_TAB);
600 fprintf (file, "cli" CR_TAB);
604 /* Do SPH first - maybe this will disable interrupts for one instruction
605 someday (a suggestion has been sent to avr@atmel.com for consideration
606 in future devices - that would make -mno-interrupts always safe). */
609 fprintf (file, AS2 (out, __SP_H__, r29) CR_TAB);
613 /* Set/restore the I flag now - interrupts will be really enabled only
614 after the next instruction. This is not clearly documented, but
615 believed to be true for all AVR devices. */
618 fprintf (file, AS2 (out, __SREG__, __tmp_reg__) CR_TAB);
623 fprintf (file, "sei" CR_TAB);
627 fprintf (file, AS2 (out, __SP_L__, r28) "\n");
633 /* Output function prologue */
636 avr_output_function_prologue (file, size)
641 int interrupt_func_p;
647 last_insn_address = 0;
648 jump_tables_size = 0;
650 fprintf (file, "/* prologue: frame size=%d */\n", size);
652 if (avr_naked_function_p (current_function_decl))
654 fputs ("/* prologue: naked */\n", file);
658 interrupt_func_p = interrupt_function_p (current_function_decl);
659 signal_func_p = signal_function_p (current_function_decl);
660 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
661 live_seq = sequent_regs_live ();
662 minimize = (TARGET_CALL_PROLOGUES
663 && !interrupt_func_p && !signal_func_p && live_seq);
665 if (interrupt_func_p)
667 fprintf (file,"\tsei\n");
670 if (interrupt_func_p || signal_func_p)
673 AS1 (push,__zero_reg__) CR_TAB
674 AS1 (push,__tmp_reg__) CR_TAB
675 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
676 AS1 (push,__tmp_reg__) CR_TAB
677 AS1 (clr,__zero_reg__) "\n");
683 AS2 (ldi,r28,lo8(%s - %d)) CR_TAB
684 AS2 (ldi,r29,hi8(%s - %d)) CR_TAB
685 AS2 (out,__SP_H__,r29) CR_TAB
686 AS2 (out,__SP_L__,r28) "\n"),
687 avr_init_stack, size, avr_init_stack, size);
691 else if (minimize && (frame_pointer_needed || live_seq > 6))
694 AS2 (ldi, r26, lo8(%d)) CR_TAB
695 AS2 (ldi, r27, hi8(%d)) CR_TAB), size, size);
697 fprintf (file, (AS2 (ldi, r30, pm_lo8(.L_%s_body)) CR_TAB
698 AS2 (ldi, r31, pm_hi8(.L_%s_body)) CR_TAB)
699 ,current_function_name, current_function_name);
705 fprintf (file, AS1 (jmp,__prologue_saves__+%d) "\n",
706 (18 - live_seq) * 2);
711 fprintf (file, AS1 (rjmp,__prologue_saves__+%d) "\n",
712 (18 - live_seq) * 2);
715 fprintf (file, ".L_%s_body:\n", current_function_name);
721 prologue_size += avr_regs_to_save (&set);
722 for (reg = 0; reg < 32; ++reg)
724 if (TEST_HARD_REG_BIT (set, reg))
726 fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
729 if (frame_pointer_needed)
733 AS1 (push,r28) CR_TAB
734 AS1 (push,r29) CR_TAB
735 AS2 (in,r28,__SP_L__) CR_TAB
736 AS2 (in,r29,__SP_H__) "\n");
741 prologue_size += out_adj_frame_ptr (file, size);
743 if (interrupt_func_p)
745 prologue_size += out_set_stack_ptr (file, 1, 1);
747 else if (signal_func_p)
749 prologue_size += out_set_stack_ptr (file, 0, 0);
753 prologue_size += out_set_stack_ptr (file, -1, -1);
761 fprintf (file, "/* prologue end (size=%d) */\n", prologue_size);
764 /* Output function epilogue */
767 avr_output_function_epilogue (file, size)
772 int interrupt_func_p;
778 rtx last = get_last_nonnote_insn ();
780 function_size = jump_tables_size;
783 rtx first = get_first_nonnote_insn ();
784 function_size += (INSN_ADDRESSES (INSN_UID (last)) -
785 INSN_ADDRESSES (INSN_UID (first)));
786 function_size += get_attr_length (last);
789 fprintf (file, "/* epilogue: frame size=%d */\n", size);
792 if (avr_naked_function_p (current_function_decl))
794 fputs ("/* epilogue: naked */\n", file);
798 if (last && GET_CODE (last) == BARRIER)
800 fputs ("/* epilogue: noreturn */\n", file);
804 interrupt_func_p = interrupt_function_p (current_function_decl);
805 signal_func_p = signal_function_p (current_function_decl);
806 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
807 live_seq = sequent_regs_live ();
808 minimize = (TARGET_CALL_PROLOGUES
809 && !interrupt_func_p && !signal_func_p && live_seq);
813 /* Return value from main() is already in the correct registers
814 (r25:r24) as the exit() argument. */
817 fputs ("\t" AS1 (jmp,exit) "\n", file);
822 fputs ("\t" AS1 (rjmp,exit) "\n", file);
826 else if (minimize && (frame_pointer_needed || live_seq > 4))
828 fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
830 if (frame_pointer_needed)
832 epilogue_size += out_adj_frame_ptr (file, -size);
836 fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
837 AS2 (in , r29, __SP_H__) CR_TAB));
843 fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
844 (18 - live_seq) * 2);
849 fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
850 (18 - live_seq) * 2);
858 if (frame_pointer_needed)
863 epilogue_size += out_adj_frame_ptr (file, -size);
865 if (interrupt_func_p || signal_func_p)
867 epilogue_size += out_set_stack_ptr (file, -1, 0);
871 epilogue_size += out_set_stack_ptr (file, -1, -1);
880 epilogue_size += avr_regs_to_save (&set);
881 for (reg = 31; reg >= 0; --reg)
883 if (TEST_HARD_REG_BIT (set, reg))
885 fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
889 if (interrupt_func_p || signal_func_p)
892 AS1 (pop,__tmp_reg__) CR_TAB
893 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
894 AS1 (pop,__tmp_reg__) CR_TAB
895 AS1 (pop,__zero_reg__) "\n");
897 fprintf (file, "\treti\n");
900 fprintf (file, "\tret\n");
905 fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
906 fprintf (file, "/* function %s size %d (%d) */\n", current_function_name,
907 prologue_size + function_size + epilogue_size, function_size);
908 commands_in_file += prologue_size + function_size + epilogue_size;
909 commands_in_prologues += prologue_size;
910 commands_in_epilogues += epilogue_size;
914 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
915 machine for a memory operand of mode MODE. */
918 legitimate_address_p (mode, x, strict)
919 enum machine_mode mode;
923 enum reg_class r = NO_REGS;
925 if (TARGET_ALL_DEBUG)
927 fprintf (stderr, "mode: (%s) %s %s %s %s:",
929 strict ? "(strict)": "",
930 reload_completed ? "(reload_completed)": "",
931 reload_in_progress ? "(reload_in_progress)": "",
932 reg_renumber ? "(reg_renumber)" : "");
933 if (GET_CODE (x) == PLUS
934 && REG_P (XEXP (x, 0))
935 && GET_CODE (XEXP (x, 1)) == CONST_INT
936 && INTVAL (XEXP (x, 1)) >= 0
937 && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
940 fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
941 true_regnum (XEXP (x, 0)));
944 if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
945 : REG_OK_FOR_BASE_NOSTRICT_P (x)))
947 else if (CONSTANT_ADDRESS_P (x))
949 else if (GET_CODE (x) == PLUS
950 && REG_P (XEXP (x, 0))
951 && GET_CODE (XEXP (x, 1)) == CONST_INT
952 && INTVAL (XEXP (x, 1)) >= 0)
954 int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
958 || REGNO (XEXP (x,0)) == REG_Y
959 || REGNO (XEXP (x,0)) == REG_Z)
960 r = BASE_POINTER_REGS;
961 if (XEXP (x,0) == frame_pointer_rtx
962 || XEXP (x,0) == arg_pointer_rtx)
963 r = BASE_POINTER_REGS;
965 else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
968 else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
969 && REG_P (XEXP (x, 0))
970 && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
971 : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
975 if (TARGET_ALL_DEBUG)
977 fprintf (stderr, " ret = %c\n", r);
979 return r == NO_REGS ? 0 : (int)r;
982 /* Attempts to replace X with a valid
983 memory address for an operand of mode MODE */
986 legitimize_address (x, oldx, mode)
989 enum machine_mode mode;
992 if (TARGET_ALL_DEBUG)
994 fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
998 if (GET_CODE (oldx) == PLUS
999 && REG_P (XEXP (oldx,0)))
1001 if (REG_P (XEXP (oldx,1)))
1002 x = force_reg (GET_MODE (oldx), oldx);
1003 else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
1005 int offs = INTVAL (XEXP (oldx,1));
1006 if (frame_pointer_rtx != XEXP (oldx,0))
1007 if (offs > MAX_LD_OFFSET (mode))
1009 if (TARGET_ALL_DEBUG)
1010 fprintf (stderr, "force_reg (big offset)\n");
1011 x = force_reg (GET_MODE (oldx), oldx);
1019 /* Return a pointer register name as a string */
1022 ptrreg_to_str (regno)
1027 case REG_X: return "X";
1028 case REG_Y: return "Y";
1029 case REG_Z: return "Z";
1036 /* Return the condition name as a string.
1037 Used in conditional jump constructing */
1050 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1055 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1068 /* Output ADDR to FILE as address */
1071 print_operand_address (file, addr)
1075 switch (GET_CODE (addr))
1078 fprintf (file, ptrreg_to_str (REGNO (addr)));
1082 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1086 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1090 if (CONSTANT_ADDRESS_P (addr)
1091 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (addr))
1092 || GET_CODE (addr) == LABEL_REF))
1094 fprintf (file, "pm(");
1095 output_addr_const (file,addr);
1096 fprintf (file ,")");
1099 output_addr_const (file, addr);
1104 /* Output X as assembler operand to file FILE */
1107 print_operand (file, x, code)
1114 if (code >= 'A' && code <= 'D')
1124 if (x == zero_reg_rtx)
1125 fprintf (file, "__zero_reg__");
1127 fprintf (file, reg_names[true_regnum (x) + abcd]);
1129 else if (GET_CODE (x) == CONST_INT)
1130 fprintf (file, "%d", INTVAL (x) + abcd);
1131 else if (GET_CODE (x) == MEM)
1133 rtx addr = XEXP (x,0);
1135 if (CONSTANT_P (addr) && abcd)
1138 output_address (addr);
1139 fprintf (file, ")+%d", abcd);
1141 else if (code == 'o')
1143 if (GET_CODE (addr) != PLUS)
1144 fatal_insn ("bad address, not (reg+disp):", addr);
1146 print_operand (file, XEXP (addr, 1), 0);
1148 else if (GET_CODE (addr) == PLUS)
1150 print_operand_address (file, XEXP (addr,0));
1151 if (REGNO (XEXP (addr, 0)) == REG_X)
1152 fatal_insn ("internal compiler error. Bad address:"
1155 print_operand (file, XEXP (addr,1), code);
1158 print_operand_address (file, addr);
1160 else if (GET_CODE (x) == CONST_DOUBLE)
1164 if (GET_MODE (x) != SFmode)
1165 fatal_insn ("internal compiler error. Unknown mode:", x);
1166 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1167 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1168 fprintf (file, "0x%lx", val);
1170 else if (code == 'j')
1171 fputs (cond_string (GET_CODE (x)), file);
1172 else if (code == 'k')
1173 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
1175 print_operand_address (file, x);
1178 /* Recognize operand OP of mode MODE used in call instructions */
1181 call_insn_operand (op, mode)
1183 enum machine_mode mode ATTRIBUTE_UNUSED;
1185 if (GET_CODE (op) == MEM)
1187 rtx inside = XEXP (op, 0);
1188 if (register_operand (inside, Pmode))
1190 if (CONSTANT_ADDRESS_P (inside))
1196 /* Update the condition code in the INSN. */
1199 notice_update_cc (body, insn)
1200 rtx body ATTRIBUTE_UNUSED;
1205 switch (get_attr_cc (insn))
1208 /* Insn does not affect CC at all. */
1216 set = single_set (insn);
1220 cc_status.flags |= CC_NO_OVERFLOW;
1221 cc_status.value1 = SET_DEST (set);
1226 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1227 The V flag may or may not be known but that's ok because
1228 alter_cond will change tests to use EQ/NE. */
1229 set = single_set (insn);
1233 cc_status.value1 = SET_DEST (set);
1234 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1239 set = single_set (insn);
1242 cc_status.value1 = SET_SRC (set);
1246 /* Insn doesn't leave CC in a usable state. */
1249 /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1250 set = single_set (insn);
1253 rtx src = SET_SRC (set);
1255 if (GET_CODE (src) == ASHIFTRT
1256 && GET_MODE (src) == QImode)
1258 rtx x = XEXP (src, 1);
1260 if (GET_CODE (x) == CONST_INT
1263 cc_status.value1 = SET_DEST (set);
1264 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1272 /* Return maximum number of consecutive registers of
1273 class CLASS needed to hold a value of mode MODE. */
1276 class_max_nregs (class, mode)
1277 enum reg_class class ATTRIBUTE_UNUSED;
1278 enum machine_mode mode;
1280 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1283 /* Choose mode for jump insn:
1284 1 - relative jump in range -63 <= x <= 62 ;
1285 2 - relative jump in range -2046 <= x <= 2045 ;
1286 3 - absolute jump (only for ATmega[16]03). */
1289 avr_jump_mode (x, insn)
1290 rtx x; /* jump operand */
1291 rtx insn; /* jump insn */
1293 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1294 ? XEXP (x, 0) : x));
1295 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1296 int jump_distance = cur_addr - dest_addr;
1298 if (-63 <= jump_distance && jump_distance <= 62)
1300 else if (-2046 <= jump_distance && jump_distance <= 2045)
1308 /* return an AVR condition jump commands.
1309 X is a comparison RTX.
1310 LEN is a number returned by avr_jump_mode function.
1311 if REVERSE nonzero then condition code in X must be reversed. */
1314 ret_cond_branch (x, len, reverse)
1319 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1324 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1325 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1327 len == 2 ? (AS1 (breq,.+4) CR_TAB
1328 AS1 (brmi,.+2) CR_TAB
1330 (AS1 (breq,.+6) CR_TAB
1331 AS1 (brmi,.+4) CR_TAB
1335 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1337 len == 2 ? (AS1 (breq,.+4) CR_TAB
1338 AS1 (brlt,.+2) CR_TAB
1340 (AS1 (breq,.+6) CR_TAB
1341 AS1 (brlt,.+4) CR_TAB
1344 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1346 len == 2 ? (AS1 (breq,.+4) CR_TAB
1347 AS1 (brlo,.+2) CR_TAB
1349 (AS1 (breq,.+6) CR_TAB
1350 AS1 (brlo,.+4) CR_TAB
1353 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1354 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1356 len == 2 ? (AS1 (breq,.+2) CR_TAB
1357 AS1 (brpl,.+2) CR_TAB
1359 (AS1 (breq,.+2) CR_TAB
1360 AS1 (brpl,.+4) CR_TAB
1363 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1365 len == 2 ? (AS1 (breq,.+2) CR_TAB
1366 AS1 (brge,.+2) CR_TAB
1368 (AS1 (breq,.+2) CR_TAB
1369 AS1 (brge,.+4) CR_TAB
1372 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1374 len == 2 ? (AS1 (breq,.+2) CR_TAB
1375 AS1 (brsh,.+2) CR_TAB
1377 (AS1 (breq,.+2) CR_TAB
1378 AS1 (brsh,.+4) CR_TAB
1386 return AS1 (br%k1,%0);
1388 return (AS1 (br%j1,.+2) CR_TAB
1391 return (AS1 (br%j1,.+4) CR_TAB
1400 return AS1 (br%j1,%0);
1402 return (AS1 (br%k1,.+2) CR_TAB
1405 return (AS1 (br%k1,.+4) CR_TAB
1413 /* Predicate function for immediate operand which fits to byte (8bit) */
1416 byte_immediate_operand (op, mode)
1418 enum machine_mode mode ATTRIBUTE_UNUSED;
1420 return (GET_CODE (op) == CONST_INT
1421 && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1424 /* Output all insn addresses and their sizes into the assembly language
1425 output file. This is helpful for debugging whether the length attributes
1426 in the md file are correct.
1427 Output insn cost for next insn. */
1430 final_prescan_insn (insn, operand, num_operands)
1431 rtx insn, *operand ATTRIBUTE_UNUSED;
1432 int num_operands ATTRIBUTE_UNUSED;
1434 int uid = INSN_UID (insn);
1436 if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1438 fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1439 INSN_ADDRESSES (uid),
1440 INSN_ADDRESSES (uid) - last_insn_address,
1441 rtx_cost (PATTERN (insn), INSN));
1443 last_insn_address = INSN_ADDRESSES (uid);
1445 if (TARGET_RTL_DUMP)
1447 fprintf (asm_out_file, "/*****************\n");
1448 print_rtl_single (asm_out_file, insn);
1449 fprintf (asm_out_file, "*****************/\n");
1453 /* Return 0 if undefined, 1 if always true or always false. */
1456 avr_simplify_comparision_p (mode, operator, x)
1457 enum machine_mode mode;
1461 unsigned int max = (mode == QImode ? 0xff :
1462 mode == HImode ? 0xffff :
1463 mode == SImode ? 0xffffffff : 0);
1464 if (max && operator && GET_CODE (x) == CONST_INT)
1466 if (unsigned_condition (operator) != operator)
1469 if (max != (INTVAL (x) & max)
1470 && INTVAL (x) != 0xff)
1477 /* Returns nonzero if REGNO is the number of a hard
1478 register in which function arguments are sometimes passed. */
1481 function_arg_regno_p(r)
1484 return (r >= 8 && r <= 25);
1487 /* Initializing the variable cum for the state at the beginning
1488 of the argument list. */
1491 init_cumulative_args (cum, fntype, libname, fndecl)
1492 CUMULATIVE_ARGS *cum;
1498 cum->regno = FIRST_CUM_REG;
1499 if (!libname && fntype)
1501 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1502 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1503 != void_type_node));
1509 /* Returns the number of registers to allocate for a function argument. */
1512 avr_num_arg_regs (mode, type)
1513 enum machine_mode mode;
1518 if (mode == BLKmode)
1519 size = int_size_in_bytes (type);
1521 size = GET_MODE_SIZE (mode);
1523 /* Align all function arguments to start in even-numbered registers.
1524 Odd-sized arguments leave holes above them. */
1526 return (size + 1) & ~1;
1529 /* Controls whether a function argument is passed
1530 in a register, and which register. */
1533 function_arg (cum, mode, type, named)
1534 CUMULATIVE_ARGS *cum;
1535 enum machine_mode mode;
1537 int named ATTRIBUTE_UNUSED;
1539 int bytes = avr_num_arg_regs (mode, type);
1541 if (cum->nregs && bytes <= cum->nregs)
1542 return gen_rtx (REG, mode, cum->regno - bytes);
1547 /* Update the summarizer variable CUM to advance past an argument
1548 in the argument list. */
1551 function_arg_advance (cum, mode, type, named)
1552 CUMULATIVE_ARGS *cum; /* current arg information */
1553 enum machine_mode mode; /* current arg mode */
1554 tree type; /* type of the argument or 0 if lib support */
1555 int named ATTRIBUTE_UNUSED; /* whether or not the argument was named */
1557 int bytes = avr_num_arg_regs (mode, type);
1559 cum->nregs -= bytes;
1560 cum->regno -= bytes;
1562 if (cum->nregs <= 0)
1565 cum->regno = FIRST_CUM_REG;
1569 /***********************************************************************
1570 Functions for outputting various mov's for a various modes
1571 ************************************************************************/
1573 output_movqi (insn, operands, l)
1579 rtx dest = operands[0];
1580 rtx src = operands[1];
1588 if (register_operand (dest, QImode))
1590 if (register_operand (src, QImode)) /* mov r,r */
1592 if (test_hard_reg_class (STACK_REG, dest))
1593 return AS2 (out,%0,%1);
1594 else if (test_hard_reg_class (STACK_REG, src))
1595 return AS2 (in,%0,%1);
1597 return AS2 (mov,%0,%1);
1599 else if (CONSTANT_P (src))
1601 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1602 return AS2 (ldi,%0,lo8(%1));
1604 if (GET_CODE (src) == CONST_INT)
1606 if (src == const0_rtx) /* mov r,L */
1607 return AS1 (clr,%0);
1608 else if (src == const1_rtx)
1610 if (reg_was_0 (insn, dest))
1611 return AS1 (inc,%0 ; reg_was_0);
1614 return (AS1 (clr,%0) CR_TAB
1617 else if (src == constm1_rtx)
1619 /* Immediate constants -1 to any register */
1620 if (reg_was_0 (insn, dest))
1621 return AS1 (dec,%0 ; reg_was_0);
1624 return (AS1 (clr,%0) CR_TAB
1629 int bit_nr = exact_log2 (INTVAL (src));
1633 if (reg_was_0 (insn, dest))
1637 output_asm_insn ("set ; reg_was_0", operands);
1643 output_asm_insn ((AS1 (clr,%0) CR_TAB
1647 avr_output_bld (operands, bit_nr);
1654 /* Last resort, larger than loading from memory. */
1656 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1657 AS2 (ldi,r31,lo8(%1)) CR_TAB
1658 AS2 (mov,%0,r31) CR_TAB
1659 AS2 (mov,r31,__tmp_reg__));
1661 else if (GET_CODE (src) == MEM)
1662 return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1664 else if (GET_CODE (dest) == MEM)
1666 const char *template;
1668 if (src == const0_rtx)
1669 operands[1] = zero_reg_rtx;
1671 template = out_movqi_mr_r (insn, operands, real_l);
1674 output_asm_insn (template, operands);
1683 output_movhi (insn, operands, l)
1689 rtx dest = operands[0];
1690 rtx src = operands[1];
1696 if (register_operand (dest, HImode))
1698 if (register_operand (src, HImode)) /* mov r,r */
1700 if (test_hard_reg_class (STACK_REG, dest))
1702 if (TARGET_TINY_STACK)
1705 return AS2 (out,__SP_L__,%A1);
1707 else if (TARGET_NO_INTERRUPTS)
1710 return (AS2 (out,__SP_H__,%B1) CR_TAB
1711 AS2 (out,__SP_L__,%A1));
1715 return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB
1717 AS2 (out,__SP_H__,%B1) CR_TAB
1718 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1719 AS2 (out,__SP_L__,%A1));
1721 else if (test_hard_reg_class (STACK_REG, src))
1724 return (AS2 (in,%A0,__SP_L__) CR_TAB
1725 AS2 (in,%B0,__SP_H__));
1731 return (AS2 (movw,%0,%1));
1734 if (true_regnum (dest) > true_regnum (src))
1737 return (AS2 (mov,%B0,%B1) CR_TAB
1743 return (AS2 (mov,%A0,%A1) CR_TAB
1747 else if (CONSTANT_P (src))
1749 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1751 if (byte_immediate_operand (src, HImode)
1752 && reg_was_0 (insn, dest))
1755 return (AS2 (ldi,%A0,lo8(%1) ; reg_was_0));
1759 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1760 AS2 (ldi,%B0,hi8(%1)));
1763 if (GET_CODE (src) == CONST_INT)
1765 if (src == const0_rtx) /* mov r,L */
1768 return (AS1 (clr,%A0) CR_TAB
1771 else if (src == const1_rtx)
1773 if (reg_was_0 (insn, dest))
1776 return AS1 (inc,%0 ; reg_was_0);
1780 return (AS1 (clr,%A0) CR_TAB
1781 AS1 (clr,%B0) CR_TAB
1784 else if (src == constm1_rtx)
1786 /* Immediate constants -1 to any register */
1787 if (reg_was_0 (insn, dest))
1790 return (AS1 (dec,%A0 ; reg_was_0) CR_TAB
1795 return (AS1 (clr,%0) CR_TAB
1796 AS1 (dec,%A0) CR_TAB
1801 int bit_nr = exact_log2 (INTVAL (src));
1805 if (reg_was_0 (insn, dest))
1809 output_asm_insn ("set ; reg_was_0", operands);
1815 output_asm_insn ((AS1 (clr,%A0) CR_TAB
1816 AS1 (clr,%B0) CR_TAB
1820 avr_output_bld (operands, bit_nr);
1826 if ((INTVAL (src) & 0xff) == 0)
1829 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1830 AS1 (clr,%A0) CR_TAB
1831 AS2 (ldi,r31,hi8(%1)) CR_TAB
1832 AS2 (mov,%B0,r31) CR_TAB
1833 AS2 (mov,r31,__tmp_reg__));
1835 else if ((INTVAL (src) & 0xff00) == 0)
1838 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1839 AS2 (ldi,r31,lo8(%1)) CR_TAB
1840 AS2 (mov,%A0,r31) CR_TAB
1841 AS1 (clr,%B0) CR_TAB
1842 AS2 (mov,r31,__tmp_reg__));
1846 /* Last resort, equal to loading from memory. */
1848 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1849 AS2 (ldi,r31,lo8(%1)) CR_TAB
1850 AS2 (mov,%A0,r31) CR_TAB
1851 AS2 (ldi,r31,hi8(%1)) CR_TAB
1852 AS2 (mov,%B0,r31) CR_TAB
1853 AS2 (mov,r31,__tmp_reg__));
1855 else if (GET_CODE (src) == MEM)
1856 return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1858 else if (GET_CODE (dest) == MEM)
1860 const char *template;
1862 if (src == const0_rtx)
1863 operands[1] = zero_reg_rtx;
1865 template = out_movhi_mr_r (insn, operands, real_l);
1868 output_asm_insn (template, operands);
1873 fatal_insn ("invalid insn:", insn);
1878 out_movqi_r_mr (insn, op, l)
1881 int *l; /* instruction length */
1885 rtx x = XEXP (src, 0);
1891 if (CONSTANT_ADDRESS_P (x))
1893 if (avr_io_address_p (x, 1))
1896 return AS2 (in,%0,%1-0x20);
1899 return AS2 (lds,%0,%1);
1901 /* memory access by reg+disp */
1902 else if (GET_CODE (x) == PLUS
1903 && REG_P (XEXP (x,0))
1904 && GET_CODE (XEXP (x,1)) == CONST_INT)
1906 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1908 int disp = INTVAL (XEXP (x,1));
1909 if (REGNO (XEXP (x,0)) != REG_Y)
1910 fatal_insn ("incorrect insn:",insn);
1912 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1913 return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
1914 AS2 (ldd,%0,Y+63) CR_TAB
1915 AS2 (sbiw,r28,%o1-63));
1917 return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1918 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1919 AS2 (ld,%0,Y) CR_TAB
1920 AS2 (subi,r28,lo8(%o1)) CR_TAB
1921 AS2 (sbci,r29,hi8(%o1)));
1923 else if (REGNO (XEXP (x,0)) == REG_X)
1925 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1926 it but I have this situation with extremal optimizing options. */
1927 if (reg_overlap_mentioned_p (dest, XEXP (x,0))
1928 || reg_unused_after (insn, XEXP (x,0)))
1929 return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
1932 return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
1933 AS2 (ld,%0,X) CR_TAB
1934 AS2 (sbiw,r26,%o1));
1937 return AS2 (ldd,%0,%1);
1940 return AS2 (ld,%0,%1);
1944 out_movhi_r_mr (insn, op, l)
1947 int *l; /* instruction length */
1951 rtx base = XEXP (src, 0);
1952 int reg_dest = true_regnum (dest);
1953 int reg_base = true_regnum (base);
1961 if (reg_dest == reg_base) /* R = (R) */
1964 return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1965 AS2 (ld,%B0,%1) CR_TAB
1966 AS2 (mov,%A0,__tmp_reg__));
1968 else if (reg_base == REG_X) /* (R26) */
1970 if (reg_unused_after (insn, base))
1973 return (AS2 (ld,%A0,X+) CR_TAB
1977 return (AS2 (ld,%A0,X+) CR_TAB
1978 AS2 (ld,%B0,X) CR_TAB
1984 return (AS2 (ld,%A0,%1) CR_TAB
1985 AS2 (ldd,%B0,%1+1));
1988 else if (GET_CODE (base) == PLUS) /* (R + i) */
1990 int disp = INTVAL (XEXP (base, 1));
1991 int reg_base = true_regnum (XEXP (base, 0));
1993 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
1995 if (REGNO (XEXP (base, 0)) != REG_Y)
1996 fatal_insn ("incorrect insn:",insn);
1998 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1999 return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
2000 AS2 (ldd,%A0,Y+62) CR_TAB
2001 AS2 (ldd,%B0,Y+63) CR_TAB
2002 AS2 (sbiw,r28,%o1-62));
2004 return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2005 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2006 AS2 (ld,%A0,Y) CR_TAB
2007 AS2 (ldd,%B0,Y+1) CR_TAB
2008 AS2 (subi,r28,lo8(%o1)) CR_TAB
2009 AS2 (sbci,r29,hi8(%o1)));
2011 if (reg_base == REG_X)
2013 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
2014 it but I have this situation with extremal
2015 optimization options. */
2018 if (reg_base == reg_dest)
2019 return (AS2 (adiw,r26,%o1) CR_TAB
2020 AS2 (ld,__tmp_reg__,X+) CR_TAB
2021 AS2 (ld,%B0,X) CR_TAB
2022 AS2 (mov,%A0,__tmp_reg__));
2024 return (AS2 (adiw,r26,%o1) CR_TAB
2025 AS2 (ld,%A0,X+) CR_TAB
2026 AS2 (ld,%B0,X) CR_TAB
2027 AS2 (sbiw,r26,%o1+1));
2030 if (reg_base == reg_dest)
2033 return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
2034 AS2 (ldd,%B0,%B1) CR_TAB
2035 AS2 (mov,%A0,__tmp_reg__));
2039 return (AS2 (ldd,%A0,%A1) CR_TAB
2042 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2044 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
2045 fatal_insn ("incorrect insn:", insn);
2048 return (AS2 (ld,%B0,%1) CR_TAB
2051 else if (GET_CODE (base) == POST_INC) /* (R++) */
2053 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
2054 fatal_insn ("incorrect insn:", insn);
2057 return (AS2 (ld,%A0,%1) CR_TAB
2060 else if (CONSTANT_ADDRESS_P (base))
2062 if (avr_io_address_p (base, 2))
2065 return (AS2 (in,%A0,%A1-0x20) CR_TAB
2066 AS2 (in,%B0,%B1-0x20));
2069 return (AS2 (lds,%A0,%A1) CR_TAB
2073 fatal_insn ("unknown move insn:",insn);
2078 out_movsi_r_mr (insn, op, l)
2081 int *l; /* instruction length */
2085 rtx base = XEXP (src, 0);
2086 int reg_dest = true_regnum (dest);
2087 int reg_base = true_regnum (base);
2095 if (reg_base == REG_X) /* (R26) */
2097 if (reg_dest == REG_X)
2098 /* "ld r26,-X" is undefined */
2099 return *l=7, (AS2 (adiw,r26,3) CR_TAB
2100 AS2 (ld,r29,X) CR_TAB
2101 AS2 (ld,r28,-X) CR_TAB
2102 AS2 (ld,__tmp_reg__,-X) CR_TAB
2103 AS2 (sbiw,r26,1) CR_TAB
2104 AS2 (ld,r26,X) CR_TAB
2105 AS2 (mov,r27,__tmp_reg__));
2106 else if (reg_dest == REG_X - 2)
2107 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2108 AS2 (ld,%B0,X+) CR_TAB
2109 AS2 (ld,__tmp_reg__,X+) CR_TAB
2110 AS2 (ld,%D0,X) CR_TAB
2111 AS2 (mov,%C0,__tmp_reg__));
2112 else if (reg_unused_after (insn, base))
2113 return *l=4, (AS2 (ld,%A0,X+) CR_TAB
2114 AS2 (ld,%B0,X+) CR_TAB
2115 AS2 (ld,%C0,X+) CR_TAB
2118 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2119 AS2 (ld,%B0,X+) CR_TAB
2120 AS2 (ld,%C0,X+) CR_TAB
2121 AS2 (ld,%D0,X) CR_TAB
2126 if (reg_dest == reg_base)
2127 return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
2128 AS2 (ldd,%C0,%1+2) CR_TAB
2129 AS2 (ldd,__tmp_reg__,%1+1) CR_TAB
2130 AS2 (ld,%A0,%1) CR_TAB
2131 AS2 (mov,%B0,__tmp_reg__));
2132 else if (reg_base == reg_dest + 2)
2133 return *l=5, (AS2 (ld ,%A0,%1) CR_TAB
2134 AS2 (ldd,%B0,%1+1) CR_TAB
2135 AS2 (ldd,__tmp_reg__,%1+2) CR_TAB
2136 AS2 (ldd,%D0,%1+3) CR_TAB
2137 AS2 (mov,%C0,__tmp_reg__));
2139 return *l=4, (AS2 (ld ,%A0,%1) CR_TAB
2140 AS2 (ldd,%B0,%1+1) CR_TAB
2141 AS2 (ldd,%C0,%1+2) CR_TAB
2142 AS2 (ldd,%D0,%1+3));
2145 else if (GET_CODE (base) == PLUS) /* (R + i) */
2147 int disp = INTVAL (XEXP (base, 1));
2149 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2151 if (REGNO (XEXP (base, 0)) != REG_Y)
2152 fatal_insn ("incorrect insn:",insn);
2154 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2155 return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2156 AS2 (ldd,%A0,Y+60) CR_TAB
2157 AS2 (ldd,%B0,Y+61) CR_TAB
2158 AS2 (ldd,%C0,Y+62) CR_TAB
2159 AS2 (ldd,%D0,Y+63) CR_TAB
2160 AS2 (sbiw,r28,%o1-60));
2162 return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2163 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2164 AS2 (ld,%A0,Y) CR_TAB
2165 AS2 (ldd,%B0,Y+1) CR_TAB
2166 AS2 (ldd,%C0,Y+2) CR_TAB
2167 AS2 (ldd,%D0,Y+3) CR_TAB
2168 AS2 (subi,r28,lo8(%o1)) CR_TAB
2169 AS2 (sbci,r29,hi8(%o1)));
2172 reg_base = true_regnum (XEXP (base, 0));
2173 if (reg_base == REG_X)
2176 if (reg_dest == REG_X)
2179 /* "ld r26,-X" is undefined */
2180 return (AS2 (adiw,r26,%o1+3) CR_TAB
2181 AS2 (ld,r29,X) CR_TAB
2182 AS2 (ld,r28,-X) CR_TAB
2183 AS2 (ld,__tmp_reg__,-X) CR_TAB
2184 AS2 (sbiw,r26,1) CR_TAB
2185 AS2 (ld,r26,X) CR_TAB
2186 AS2 (mov,r27,__tmp_reg__));
2189 if (reg_dest == REG_X - 2)
2190 return (AS2 (adiw,r26,%o1) CR_TAB
2191 AS2 (ld,r24,X+) CR_TAB
2192 AS2 (ld,r25,X+) CR_TAB
2193 AS2 (ld,__tmp_reg__,X+) CR_TAB
2194 AS2 (ld,r27,X) CR_TAB
2195 AS2 (mov,r26,__tmp_reg__));
2197 return (AS2 (adiw,r26,%o1) CR_TAB
2198 AS2 (ld,%A0,X+) CR_TAB
2199 AS2 (ld,%B0,X+) CR_TAB
2200 AS2 (ld,%C0,X+) CR_TAB
2201 AS2 (ld,%D0,X) CR_TAB
2202 AS2 (sbiw,r26,%o1+3));
2204 if (reg_dest == reg_base)
2205 return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2206 AS2 (ldd,%C0,%C1) CR_TAB
2207 AS2 (ldd,__tmp_reg__,%B1) CR_TAB
2208 AS2 (ldd,%A0,%A1) CR_TAB
2209 AS2 (mov,%B0,__tmp_reg__));
2210 else if (reg_dest == reg_base - 2)
2211 return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2212 AS2 (ldd,%B0,%B1) CR_TAB
2213 AS2 (ldd,__tmp_reg__,%C1) CR_TAB
2214 AS2 (ldd,%D0,%D1) CR_TAB
2215 AS2 (mov,%C0,__tmp_reg__));
2216 return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2217 AS2 (ldd,%B0,%B1) CR_TAB
2218 AS2 (ldd,%C0,%C1) CR_TAB
2221 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2222 return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2223 AS2 (ld,%C0,%1) CR_TAB
2224 AS2 (ld,%B0,%1) CR_TAB
2226 else if (GET_CODE (base) == POST_INC) /* (R++) */
2227 return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2228 AS2 (ld,%B0,%1) CR_TAB
2229 AS2 (ld,%C0,%1) CR_TAB
2231 else if (CONSTANT_ADDRESS_P (base))
2232 return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2233 AS2 (lds,%B0,%B1) CR_TAB
2234 AS2 (lds,%C0,%C1) CR_TAB
2237 fatal_insn ("unknown move insn:",insn);
2242 out_movsi_mr_r (insn, op, l)
2249 rtx base = XEXP (dest, 0);
2250 int reg_base = true_regnum (base);
2251 int reg_src = true_regnum (src);
2257 if (CONSTANT_ADDRESS_P (base))
2258 return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2259 AS2 (sts,%B0,%B1) CR_TAB
2260 AS2 (sts,%C0,%C1) CR_TAB
2262 if (reg_base > 0) /* (r) */
2264 if (reg_base == REG_X) /* (R26) */
2266 if (reg_src == REG_X)
2268 /* "st X+,r26" is undefined */
2269 if (reg_unused_after (insn, base))
2270 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2271 AS2 (st,X,r26) CR_TAB
2272 AS2 (adiw,r26,1) CR_TAB
2273 AS2 (st,X+,__tmp_reg__) CR_TAB
2274 AS2 (st,X+,r28) CR_TAB
2277 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2278 AS2 (st,X,r26) CR_TAB
2279 AS2 (adiw,r26,1) CR_TAB
2280 AS2 (st,X+,__tmp_reg__) CR_TAB
2281 AS2 (st,X+,r28) CR_TAB
2282 AS2 (st,X,r29) CR_TAB
2285 else if (reg_base == reg_src + 2)
2287 if (reg_unused_after (insn, base))
2288 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2289 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2290 AS2 (st,%0+,%A1) CR_TAB
2291 AS2 (st,%0+,%B1) CR_TAB
2292 AS2 (st,%0+,__zero_reg__) CR_TAB
2293 AS2 (st,%0,__tmp_reg__) CR_TAB
2294 AS1 (clr,__zero_reg__));
2296 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2297 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2298 AS2 (st,%0+,%A1) CR_TAB
2299 AS2 (st,%0+,%B1) CR_TAB
2300 AS2 (st,%0+,__zero_reg__) CR_TAB
2301 AS2 (st,%0,__tmp_reg__) CR_TAB
2302 AS1 (clr,__zero_reg__) CR_TAB
2305 return *l=5, (AS2 (st,%0+,%A1) CR_TAB
2306 AS2 (st,%0+,%B1) CR_TAB
2307 AS2 (st,%0+,%C1) CR_TAB
2308 AS2 (st,%0,%D1) CR_TAB
2312 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2313 AS2 (std,%0+1,%B1) CR_TAB
2314 AS2 (std,%0+2,%C1) CR_TAB
2315 AS2 (std,%0+3,%D1));
2317 else if (GET_CODE (base) == PLUS) /* (R + i) */
2319 int disp = INTVAL (XEXP (base, 1));
2320 reg_base = REGNO (XEXP (base, 0));
2321 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2323 if (reg_base != REG_Y)
2324 fatal_insn ("incorrect insn:",insn);
2326 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2327 return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2328 AS2 (std,Y+60,%A1) CR_TAB
2329 AS2 (std,Y+61,%B1) CR_TAB
2330 AS2 (std,Y+62,%C1) CR_TAB
2331 AS2 (std,Y+63,%D1) CR_TAB
2332 AS2 (sbiw,r28,%o0-60));
2334 return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2335 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2336 AS2 (st,Y,%A1) CR_TAB
2337 AS2 (std,Y+1,%B1) CR_TAB
2338 AS2 (std,Y+2,%C1) CR_TAB
2339 AS2 (std,Y+3,%D1) CR_TAB
2340 AS2 (subi,r28,lo8(%o0)) CR_TAB
2341 AS2 (sbci,r29,hi8(%o0)));
2343 if (reg_base == REG_X)
2346 if (reg_src == REG_X)
2349 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2350 AS2 (mov,__zero_reg__,r27) CR_TAB
2351 AS2 (adiw,r26,%o0) CR_TAB
2352 AS2 (st,X+,__tmp_reg__) CR_TAB
2353 AS2 (st,X+,__zero_reg__) CR_TAB
2354 AS2 (st,X+,r28) CR_TAB
2355 AS2 (st,X,r29) CR_TAB
2356 AS1 (clr,__zero_reg__) CR_TAB
2357 AS2 (sbiw,r26,%o0+3));
2359 else if (reg_src == REG_X - 2)
2362 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2363 AS2 (mov,__zero_reg__,r27) CR_TAB
2364 AS2 (adiw,r26,%o0) CR_TAB
2365 AS2 (st,X+,r24) CR_TAB
2366 AS2 (st,X+,r25) CR_TAB
2367 AS2 (st,X+,__tmp_reg__) CR_TAB
2368 AS2 (st,X,__zero_reg__) CR_TAB
2369 AS1 (clr,__zero_reg__) CR_TAB
2370 AS2 (sbiw,r26,%o0+3));
2373 return (AS2 (adiw,r26,%o0) CR_TAB
2374 AS2 (st,X+,%A1) CR_TAB
2375 AS2 (st,X+,%B1) CR_TAB
2376 AS2 (st,X+,%C1) CR_TAB
2377 AS2 (st,X,%D1) CR_TAB
2378 AS2 (sbiw,r26,%o0+3));
2380 return *l=4, (AS2 (std,%A0,%A1) CR_TAB
2381 AS2 (std,%B0,%B1) CR_TAB
2382 AS2 (std,%C0,%C1) CR_TAB
2385 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2386 return *l=4, (AS2 (st,%0,%D1) CR_TAB
2387 AS2 (st,%0,%C1) CR_TAB
2388 AS2 (st,%0,%B1) CR_TAB
2390 else if (GET_CODE (base) == POST_INC) /* (R++) */
2391 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2392 AS2 (st,%0,%B1) CR_TAB
2393 AS2 (st,%0,%C1) CR_TAB
2395 fatal_insn ("unknown move insn:",insn);
2400 output_movsisf(insn, operands, l)
2406 rtx dest = operands[0];
2407 rtx src = operands[1];
2413 if (register_operand (dest, VOIDmode))
2415 if (register_operand (src, VOIDmode)) /* mov r,r */
2417 if (true_regnum (dest) > true_regnum (src))
2422 return (AS2 (movw,%C0,%C1) CR_TAB
2423 AS2 (movw,%A0,%A1));
2426 return (AS2 (mov,%D0,%D1) CR_TAB
2427 AS2 (mov,%C0,%C1) CR_TAB
2428 AS2 (mov,%B0,%B1) CR_TAB
2436 return (AS2 (movw,%A0,%A1) CR_TAB
2437 AS2 (movw,%C0,%C1));
2440 return (AS2 (mov,%A0,%A1) CR_TAB
2441 AS2 (mov,%B0,%B1) CR_TAB
2442 AS2 (mov,%C0,%C1) CR_TAB
2446 else if (CONSTANT_P (src))
2448 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2450 if (byte_immediate_operand (src, SImode)
2451 && reg_was_0 (insn, dest))
2454 return (AS2 (ldi,%A0,lo8(%1) ; reg_was_0));
2458 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
2459 AS2 (ldi,%B0,hi8(%1)) CR_TAB
2460 AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2461 AS2 (ldi,%D0,hhi8(%1)));
2464 if (GET_CODE (src) == CONST_INT)
2466 const char *const clr_op0 =
2467 AVR_ENHANCED ? (AS1 (clr,%A0) CR_TAB
2468 AS1 (clr,%B0) CR_TAB
2470 : (AS1 (clr,%A0) CR_TAB
2471 AS1 (clr,%B0) CR_TAB
2472 AS1 (clr,%C0) CR_TAB
2475 if (src == const0_rtx) /* mov r,L */
2477 *l = AVR_ENHANCED ? 3 : 4;
2480 else if (src == const1_rtx)
2482 if (reg_was_0 (insn, dest))
2485 return AS1 (inc,%A0 ; reg_was_0);
2488 output_asm_insn (clr_op0, operands);
2489 *l = AVR_ENHANCED ? 4 : 5;
2490 return AS1 (inc,%A0);
2492 else if (src == constm1_rtx)
2494 /* Immediate constants -1 to any register */
2495 if (reg_was_0 (insn, dest))
2500 return (AS1 (dec,%A0) CR_TAB
2501 AS1 (dec,%B0) CR_TAB
2502 AS2 (movw,%C0,%A0));
2505 return (AS1 (dec,%D0 ; reg_was_0) CR_TAB
2506 AS1 (dec,%C0) CR_TAB
2507 AS1 (dec,%B0) CR_TAB
2513 return (AS1 (clr,%A0) CR_TAB
2514 AS1 (dec,%A0) CR_TAB
2515 AS2 (mov,%B0,%A0) CR_TAB
2516 AS2 (movw,%C0,%A0));
2519 return (AS1 (clr,%A0) CR_TAB
2520 AS1 (dec,%A0) CR_TAB
2521 AS2 (mov,%B0,%A0) CR_TAB
2522 AS2 (mov,%C0,%A0) CR_TAB
2527 int bit_nr = exact_log2 (INTVAL (src));
2531 if (reg_was_0 (insn, dest))
2535 output_asm_insn ("set ; reg_was_0", operands);
2539 *l = AVR_ENHANCED ? 5 : 6;
2542 output_asm_insn (clr_op0, operands);
2543 output_asm_insn ("set", operands);
2547 avr_output_bld (operands, bit_nr);
2554 /* Last resort, better than loading from memory. */
2556 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2557 AS2 (ldi,r31,lo8(%1)) CR_TAB
2558 AS2 (mov,%A0,r31) CR_TAB
2559 AS2 (ldi,r31,hi8(%1)) CR_TAB
2560 AS2 (mov,%B0,r31) CR_TAB
2561 AS2 (ldi,r31,hlo8(%1)) CR_TAB
2562 AS2 (mov,%C0,r31) CR_TAB
2563 AS2 (ldi,r31,hhi8(%1)) CR_TAB
2564 AS2 (mov,%D0,r31) CR_TAB
2565 AS2 (mov,r31,__tmp_reg__));
2567 else if (GET_CODE (src) == MEM)
2568 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2570 else if (GET_CODE (dest) == MEM)
2572 const char *template;
2574 if (src == const0_rtx)
2575 operands[1] = zero_reg_rtx;
2577 template = out_movsi_mr_r (insn, operands, real_l);
2580 output_asm_insn (template, operands);
2585 fatal_insn ("invalid insn:", insn);
2590 out_movqi_mr_r (insn, op, l)
2593 int *l; /* instruction length */
2597 rtx x = XEXP (dest, 0);
2603 if (CONSTANT_ADDRESS_P (x))
2605 if (avr_io_address_p (x, 1))
2608 return AS2 (out,%0-0x20,%1);
2611 return AS2 (sts,%0,%1);
2613 /* memory access by reg+disp */
2614 else if (GET_CODE (x) == PLUS
2615 && REG_P (XEXP (x,0))
2616 && GET_CODE (XEXP (x,1)) == CONST_INT)
2618 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2620 int disp = INTVAL (XEXP (x,1));
2621 if (REGNO (XEXP (x,0)) != REG_Y)
2622 fatal_insn ("incorrect insn:",insn);
2624 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2625 return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2626 AS2 (std,Y+63,%1) CR_TAB
2627 AS2 (sbiw,r28,%o0-63));
2629 return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2630 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2631 AS2 (st,Y,%1) CR_TAB
2632 AS2 (subi,r28,lo8(%o0)) CR_TAB
2633 AS2 (sbci,r29,hi8(%o0)));
2635 else if (REGNO (XEXP (x,0)) == REG_X)
2637 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2639 if (reg_unused_after (insn, XEXP (x,0)))
2640 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2641 AS2 (adiw,r26,%o0) CR_TAB
2642 AS2 (st,X,__tmp_reg__));
2644 return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2645 AS2 (adiw,r26,%o0) CR_TAB
2646 AS2 (st,X,__tmp_reg__) CR_TAB
2647 AS2 (sbiw,r26,%o0));
2651 if (reg_unused_after (insn, XEXP (x,0)))
2652 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2655 return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2656 AS2 (st,X,%1) CR_TAB
2657 AS2 (sbiw,r26,%o0));
2661 return AS2 (std,%0,%1);
2664 return AS2 (st,%0,%1);
2668 out_movhi_mr_r (insn, op, l)
2675 rtx base = XEXP (dest, 0);
2676 int reg_base = true_regnum (base);
2677 int reg_src = true_regnum (src);
2681 if (CONSTANT_ADDRESS_P (base))
2683 if (avr_io_address_p (base, 2))
2686 return (AS2 (out,%B0-0x20,%B1) CR_TAB
2687 AS2 (out,%A0-0x20,%A1));
2689 return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2694 if (reg_base == REG_X)
2696 if (reg_src == REG_X)
2698 /* "st X+,r26" is undefined */
2699 if (reg_unused_after (insn, src))
2700 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2701 AS2 (st,X,r26) CR_TAB
2702 AS2 (adiw,r26,1) CR_TAB
2703 AS2 (st,X,__tmp_reg__));
2705 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2706 AS2 (st,X,r26) CR_TAB
2707 AS2 (adiw,r26,1) CR_TAB
2708 AS2 (st,X,__tmp_reg__) CR_TAB
2713 if (reg_unused_after (insn, base))
2714 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2717 return *l=3, (AS2 (st ,X+,%A1) CR_TAB
2718 AS2 (st ,X,%B1) CR_TAB
2723 return *l=2, (AS2 (st ,%0,%A1) CR_TAB
2724 AS2 (std,%0+1,%B1));
2726 else if (GET_CODE (base) == PLUS)
2728 int disp = INTVAL (XEXP (base, 1));
2729 reg_base = REGNO (XEXP (base, 0));
2730 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2732 if (reg_base != REG_Y)
2733 fatal_insn ("incorrect insn:",insn);
2735 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2736 return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2737 AS2 (std,Y+62,%A1) CR_TAB
2738 AS2 (std,Y+63,%B1) CR_TAB
2739 AS2 (sbiw,r28,%o0-62));
2741 return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2742 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2743 AS2 (st,Y,%A1) CR_TAB
2744 AS2 (std,Y+1,%B1) CR_TAB
2745 AS2 (subi,r28,lo8(%o0)) CR_TAB
2746 AS2 (sbci,r29,hi8(%o0)));
2748 if (reg_base == REG_X)
2751 if (reg_src == REG_X)
2754 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2755 AS2 (mov,__zero_reg__,r27) CR_TAB
2756 AS2 (adiw,r26,%o0) CR_TAB
2757 AS2 (st,X+,__tmp_reg__) CR_TAB
2758 AS2 (st,X,__zero_reg__) CR_TAB
2759 AS1 (clr,__zero_reg__) CR_TAB
2760 AS2 (sbiw,r26,%o0+1));
2763 return (AS2 (adiw,r26,%o0) CR_TAB
2764 AS2 (st,X+,%A1) CR_TAB
2765 AS2 (st,X,%B1) CR_TAB
2766 AS2 (sbiw,r26,%o0+1));
2768 return *l=2, (AS2 (std,%A0,%A1) CR_TAB
2771 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2772 return *l=2, (AS2 (st,%0,%B1) CR_TAB
2774 else if (GET_CODE (base) == POST_INC) /* (R++) */
2775 return *l=2, (AS2 (st,%0,%A1) CR_TAB
2777 fatal_insn ("unknown move insn:",insn);
2781 /* Return 1 if frame pointer for current function required */
2784 frame_pointer_required_p ()
2786 return (current_function_calls_alloca
2787 || current_function_args_info.nregs == 0
2788 || get_frame_size () > 0);
2791 /* Returns the condition of compare insn INSN, or UNKNOWN. */
2794 compare_condition (insn)
2797 rtx next = next_real_insn (insn);
2798 RTX_CODE cond = UNKNOWN;
2799 if (next && GET_CODE (next) == JUMP_INSN)
2801 rtx pat = PATTERN (next);
2802 rtx src = SET_SRC (pat);
2803 rtx t = XEXP (src, 0);
2804 cond = GET_CODE (t);
2809 /* Returns nonzero if INSN is a tst insn that only tests the sign. */
2812 compare_sign_p (insn)
2815 RTX_CODE cond = compare_condition (insn);
2816 return (cond == GE || cond == LT);
2819 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
2820 that needs to be swapped (GT, GTU, LE, LEU). */
2823 compare_diff_p (insn)
2826 RTX_CODE cond = compare_condition (insn);
2827 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2830 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition. */
2836 RTX_CODE cond = compare_condition (insn);
2837 return (cond == EQ || cond == NE);
2841 /* Output test instruction for HImode */
2848 if (compare_sign_p (insn))
2851 return AS1 (tst,%B0);
2853 if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
2854 && compare_eq_p (insn))
2856 /* faster than sbiw if we can clobber the operand */
2858 return AS2 (or,%A0,%B0);
2860 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2863 return AS2 (sbiw,%0,0);
2866 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2867 AS2 (cpc,%B0,__zero_reg__));
2871 /* Output test instruction for SImode */
2878 if (compare_sign_p (insn))
2881 return AS1 (tst,%D0);
2883 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2886 return (AS2 (sbiw,%A0,0) CR_TAB
2887 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2888 AS2 (cpc,%D0,__zero_reg__));
2891 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2892 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2893 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2894 AS2 (cpc,%D0,__zero_reg__));
2898 /* Generate asm equivalent for various shifts.
2899 Shift count is a CONST_INT, MEM or REG.
2900 This only handles cases that are not already
2901 carefully hand-optimized in ?sh??i3_out. */
2904 out_shift_with_cnt (template, insn, operands, len, t_len)
2905 const char *template;
2909 int t_len; /* Length of template. */
2913 int second_label = 1;
2914 int saved_in_tmp = 0;
2915 int use_zero_reg = 0;
2917 op[0] = operands[0];
2918 op[1] = operands[1];
2919 op[2] = operands[2];
2920 op[3] = operands[3];
2926 if (GET_CODE (operands[2]) == CONST_INT)
2928 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2929 int count = INTVAL (operands[2]);
2930 int max_len = 10; /* If larger than this, always use a loop. */
2932 if (count < 8 && !scratch)
2936 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
2938 if (t_len * count <= max_len)
2940 /* Output shifts inline with no loop - faster. */
2942 *len = t_len * count;
2946 output_asm_insn (template, op);
2955 strcat (str, AS2 (ldi,%3,%2));
2957 else if (use_zero_reg)
2959 /* Hack to save one word: use __zero_reg__ as loop counter.
2960 Set one bit, then shift in a loop until it is 0 again. */
2962 op[3] = zero_reg_rtx;
2966 strcat (str, ("set" CR_TAB
2967 AS2 (bld,%3,%2-1)));
2971 /* No scratch register available, use one from LD_REGS (saved in
2972 __tmp_reg__) that doesn't overlap with registers to shift. */
2974 op[3] = gen_rtx (REG, QImode,
2975 ((true_regnum (operands[0]) - 1) & 15) + 16);
2976 op[4] = tmp_reg_rtx;
2980 *len = 3; /* Includes "mov %3,%4" after the loop. */
2982 strcat (str, (AS2 (mov,%4,%3) CR_TAB
2988 else if (GET_CODE (operands[2]) == MEM)
2992 op[3] = op_mov[0] = tmp_reg_rtx;
2996 out_movqi_r_mr (insn, op_mov, len);
2998 output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
3000 else if (register_operand (operands[2], QImode))
3002 if (reg_unused_after (insn, operands[2]))
3006 op[3] = tmp_reg_rtx;
3008 strcat (str, (AS2 (mov,%3,%2) CR_TAB));
3012 fatal_insn ("bad shift insn:", insn);
3019 strcat (str, AS1 (rjmp,2f));
3023 *len += t_len + 2; /* template + dec + brXX */
3026 strcat (str, "\n1:\t");
3027 strcat (str, template);
3028 strcat (str, second_label ? "\n2:\t" : "\n\t");
3029 strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
3030 strcat (str, CR_TAB);
3031 strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
3033 strcat (str, (CR_TAB AS2 (mov,%3,%4)));
3034 output_asm_insn (str, op);
3039 /* 8bit shift left ((char)x << i) */
3042 ashlqi3_out (insn, operands, len)
3045 int *len; /* insn length (may be NULL) */
3047 if (GET_CODE (operands[2]) == CONST_INT)
3054 switch (INTVAL (operands[2]))
3058 return AS1 (clr,%0);
3062 return AS1 (lsl,%0);
3066 return (AS1 (lsl,%0) CR_TAB
3071 return (AS1 (lsl,%0) CR_TAB
3076 if (test_hard_reg_class (LD_REGS, operands[0]))
3079 return (AS1 (swap,%0) CR_TAB
3080 AS2 (andi,%0,0xf0));
3083 return (AS1 (lsl,%0) CR_TAB
3089 if (test_hard_reg_class (LD_REGS, operands[0]))
3092 return (AS1 (swap,%0) CR_TAB
3094 AS2 (andi,%0,0xe0));
3097 return (AS1 (lsl,%0) CR_TAB
3104 if (test_hard_reg_class (LD_REGS, operands[0]))
3107 return (AS1 (swap,%0) CR_TAB
3110 AS2 (andi,%0,0xc0));
3113 return (AS1 (lsl,%0) CR_TAB
3122 return (AS1 (ror,%0) CR_TAB
3127 else if (CONSTANT_P (operands[2]))
3128 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3130 out_shift_with_cnt (AS1 (lsl,%0),
3131 insn, operands, len, 1);
3136 /* 16bit shift left ((short)x << i) */
3139 ashlhi3_out (insn, operands, len)
3144 if (GET_CODE (operands[2]) == CONST_INT)
3146 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3147 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3154 switch (INTVAL (operands[2]))
3157 if (optimize_size && scratch)
3162 return (AS1 (swap,%A0) CR_TAB
3163 AS1 (swap,%B0) CR_TAB
3164 AS2 (andi,%B0,0xf0) CR_TAB
3165 AS2 (eor,%B0,%A0) CR_TAB
3166 AS2 (andi,%A0,0xf0) CR_TAB
3172 return (AS1 (swap,%A0) CR_TAB
3173 AS1 (swap,%B0) CR_TAB
3174 AS2 (ldi,%3,0xf0) CR_TAB
3175 AS2 (and,%B0,%3) CR_TAB
3176 AS2 (eor,%B0,%A0) CR_TAB
3177 AS2 (and,%A0,%3) CR_TAB
3180 break; /* optimize_size ? 6 : 8 */
3184 break; /* scratch ? 5 : 6 */
3188 return (AS1 (lsl,%A0) CR_TAB
3189 AS1 (rol,%B0) CR_TAB
3190 AS1 (swap,%A0) CR_TAB
3191 AS1 (swap,%B0) CR_TAB
3192 AS2 (andi,%B0,0xf0) CR_TAB
3193 AS2 (eor,%B0,%A0) CR_TAB
3194 AS2 (andi,%A0,0xf0) CR_TAB
3200 return (AS1 (lsl,%A0) CR_TAB
3201 AS1 (rol,%B0) CR_TAB
3202 AS1 (swap,%A0) CR_TAB
3203 AS1 (swap,%B0) CR_TAB
3204 AS2 (ldi,%3,0xf0) CR_TAB
3205 AS2 (and,%B0,%3) CR_TAB
3206 AS2 (eor,%B0,%A0) CR_TAB
3207 AS2 (and,%A0,%3) CR_TAB
3214 break; /* scratch ? 5 : 6 */
3216 return (AS1 (clr,__tmp_reg__) CR_TAB
3217 AS1 (lsr,%B0) CR_TAB
3218 AS1 (ror,%A0) CR_TAB
3219 AS1 (ror,__tmp_reg__) CR_TAB
3220 AS1 (lsr,%B0) CR_TAB
3221 AS1 (ror,%A0) CR_TAB
3222 AS1 (ror,__tmp_reg__) CR_TAB
3223 AS2 (mov,%B0,%A0) CR_TAB
3224 AS2 (mov,%A0,__tmp_reg__));
3228 return (AS1 (lsr,%B0) CR_TAB
3229 AS2 (mov,%B0,%A0) CR_TAB
3230 AS1 (clr,%A0) CR_TAB
3231 AS1 (ror,%B0) CR_TAB
3235 if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
3236 return *len = 1, AS1 (clr,%A0);
3238 return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3243 return (AS2 (mov,%B0,%A0) CR_TAB
3244 AS1 (clr,%A0) CR_TAB
3249 return (AS2 (mov,%B0,%A0) CR_TAB
3250 AS1 (clr,%A0) CR_TAB
3251 AS1 (lsl,%B0) CR_TAB
3256 return (AS2 (mov,%B0,%A0) CR_TAB
3257 AS1 (clr,%A0) CR_TAB
3258 AS1 (lsl,%B0) CR_TAB
3259 AS1 (lsl,%B0) CR_TAB
3266 return (AS2 (mov,%B0,%A0) CR_TAB
3267 AS1 (clr,%A0) CR_TAB
3268 AS1 (swap,%B0) CR_TAB
3269 AS2 (andi,%B0,0xf0));
3274 return (AS2 (mov,%B0,%A0) CR_TAB
3275 AS1 (clr,%A0) CR_TAB
3276 AS1 (swap,%B0) CR_TAB
3277 AS2 (ldi,%3,0xf0) CR_TAB
3281 return (AS2 (mov,%B0,%A0) CR_TAB
3282 AS1 (clr,%A0) CR_TAB
3283 AS1 (lsl,%B0) CR_TAB
3284 AS1 (lsl,%B0) CR_TAB
3285 AS1 (lsl,%B0) CR_TAB
3292 return (AS2 (mov,%B0,%A0) CR_TAB
3293 AS1 (clr,%A0) CR_TAB
3294 AS1 (swap,%B0) CR_TAB
3295 AS1 (lsl,%B0) CR_TAB
3296 AS2 (andi,%B0,0xe0));
3298 if (AVR_ENHANCED && scratch)
3301 return (AS2 (ldi,%3,0x20) CR_TAB
3302 AS2 (mul,%A0,%3) CR_TAB
3303 AS2 (mov,%B0,r0) CR_TAB
3304 AS1 (clr,%A0) CR_TAB
3305 AS1 (clr,__zero_reg__));
3307 if (optimize_size && scratch)
3312 return (AS2 (mov,%B0,%A0) CR_TAB
3313 AS1 (clr,%A0) CR_TAB
3314 AS1 (swap,%B0) CR_TAB
3315 AS1 (lsl,%B0) CR_TAB
3316 AS2 (ldi,%3,0xe0) CR_TAB
3322 return ("set" CR_TAB
3323 AS2 (bld,r1,5) CR_TAB
3324 AS2 (mul,%A0,r1) CR_TAB
3325 AS2 (mov,%B0,r0) CR_TAB
3326 AS1 (clr,%A0) CR_TAB
3327 AS1 (clr,__zero_reg__));
3330 return (AS2 (mov,%B0,%A0) CR_TAB
3331 AS1 (clr,%A0) CR_TAB
3332 AS1 (lsl,%B0) CR_TAB
3333 AS1 (lsl,%B0) CR_TAB
3334 AS1 (lsl,%B0) CR_TAB
3335 AS1 (lsl,%B0) CR_TAB
3339 if (AVR_ENHANCED && ldi_ok)
3342 return (AS2 (ldi,%B0,0x40) CR_TAB
3343 AS2 (mul,%A0,%B0) CR_TAB
3344 AS2 (mov,%B0,r0) CR_TAB
3345 AS1 (clr,%A0) CR_TAB
3346 AS1 (clr,__zero_reg__));
3348 if (AVR_ENHANCED && scratch)
3351 return (AS2 (ldi,%3,0x40) CR_TAB
3352 AS2 (mul,%A0,%3) CR_TAB
3353 AS2 (mov,%B0,r0) CR_TAB
3354 AS1 (clr,%A0) CR_TAB
3355 AS1 (clr,__zero_reg__));
3357 if (optimize_size && ldi_ok)
3360 return (AS2 (mov,%B0,%A0) CR_TAB
3361 AS2 (ldi,%A0,6) "\n1:\t"
3362 AS1 (lsl,%B0) CR_TAB
3363 AS1 (dec,%A0) CR_TAB
3366 if (optimize_size && scratch)
3369 return (AS1 (clr,%B0) CR_TAB
3370 AS1 (lsr,%A0) CR_TAB
3371 AS1 (ror,%B0) CR_TAB
3372 AS1 (lsr,%A0) CR_TAB
3373 AS1 (ror,%B0) CR_TAB
3378 return (AS1 (clr,%B0) CR_TAB
3379 AS1 (lsr,%A0) CR_TAB
3380 AS1 (ror,%B0) CR_TAB
3385 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3387 insn, operands, len, 2);
3392 /* 32bit shift left ((long)x << i) */
3395 ashlsi3_out (insn, operands, len)
3400 if (GET_CODE (operands[2]) == CONST_INT)
3408 switch (INTVAL (operands[2]))
3412 int reg0 = true_regnum (operands[0]);
3413 int reg1 = true_regnum (operands[1]);
3416 return (AS2 (mov,%D0,%C1) CR_TAB
3417 AS2 (mov,%C0,%B1) CR_TAB
3418 AS2 (mov,%B0,%A1) CR_TAB
3420 else if (reg0 + 1 == reg1)
3423 return AS1 (clr,%A0);
3426 return (AS1 (clr,%A0) CR_TAB
3427 AS2 (mov,%B0,%A1) CR_TAB
3428 AS2 (mov,%C0,%B1) CR_TAB
3434 int reg0 = true_regnum (operands[0]);
3435 int reg1 = true_regnum (operands[1]);
3437 if (AVR_ENHANCED && (reg0 + 2 != reg1))
3440 return (AS2 (movw,%C0,%A1) CR_TAB
3441 AS1 (clr,%B0) CR_TAB
3444 if (reg0 + 1 >= reg1)
3445 return (AS2 (mov,%D0,%B1) CR_TAB
3446 AS2 (mov,%C0,%A1) CR_TAB
3447 AS1 (clr,%B0) CR_TAB
3449 if (reg0 + 2 == reg1)
3452 return (AS1 (clr,%B0) CR_TAB
3456 return (AS2 (mov,%C0,%A1) CR_TAB
3457 AS2 (mov,%D0,%B1) CR_TAB
3458 AS1 (clr,%B0) CR_TAB
3464 if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
3465 return (AS2 (mov,%D0,%A1) CR_TAB
3466 AS1 (clr,%C0) CR_TAB
3467 AS1 (clr,%B0) CR_TAB
3472 return (AS1 (clr,%C0) CR_TAB
3473 AS1 (clr,%B0) CR_TAB
3479 return (AS1 (clr,%D0) CR_TAB
3480 AS1 (lsr,%A0) CR_TAB
3481 AS1 (ror,%D0) CR_TAB
3482 AS1 (clr,%C0) CR_TAB
3483 AS1 (clr,%B0) CR_TAB
3488 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3489 AS1 (rol,%B0) CR_TAB
3490 AS1 (rol,%C0) CR_TAB
3492 insn, operands, len, 4);
3496 /* 8bit arithmetic shift right ((signed char)x >> i) */
3499 ashrqi3_out (insn, operands, len)
3502 int *len; /* insn length */
3504 if (GET_CODE (operands[2]) == CONST_INT)
3511 switch (INTVAL (operands[2]))
3515 return AS1 (asr,%0);
3519 return (AS1 (asr,%0) CR_TAB
3524 return (AS1 (asr,%0) CR_TAB
3530 return (AS1 (asr,%0) CR_TAB
3537 return (AS1 (asr,%0) CR_TAB
3545 return (AS2 (bst,%0,6) CR_TAB
3547 AS2 (sbc,%0,%0) CR_TAB
3553 return (AS1 (lsl,%0) CR_TAB
3557 else if (CONSTANT_P (operands[2]))
3558 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3560 out_shift_with_cnt (AS1 (asr,%0),
3561 insn, operands, len, 1);
3566 /* 16bit arithmetic shift right ((signed short)x >> i) */
3569 ashrhi3_out (insn, operands, len)
3574 if (GET_CODE (operands[2]) == CONST_INT)
3576 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3577 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3584 switch (INTVAL (operands[2]))
3588 /* XXX try to optimize this too? */
3593 break; /* scratch ? 5 : 6 */
3595 return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3596 AS2 (mov,%A0,%B0) CR_TAB
3597 AS1 (lsl,__tmp_reg__) CR_TAB
3598 AS1 (rol,%A0) CR_TAB
3599 AS2 (sbc,%B0,%B0) CR_TAB
3600 AS1 (lsl,__tmp_reg__) CR_TAB
3601 AS1 (rol,%A0) CR_TAB
3606 return (AS1 (lsl,%A0) CR_TAB
3607 AS2 (mov,%A0,%B0) CR_TAB
3608 AS1 (rol,%A0) CR_TAB
3613 int reg0 = true_regnum (operands[0]);
3614 int reg1 = true_regnum (operands[1]);
3617 return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3618 AS1 (lsl,%B0) CR_TAB
3620 else if (reg0 == reg1 + 1)
3621 return *len = 3, (AS1 (clr,%B0) CR_TAB
3622 AS2 (sbrc,%A0,7) CR_TAB
3625 return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3626 AS1 (clr,%B0) CR_TAB
3627 AS2 (sbrc,%A0,7) CR_TAB
3633 return (AS2 (mov,%A0,%B0) CR_TAB
3634 AS1 (lsl,%B0) CR_TAB
3635 AS2 (sbc,%B0,%B0) CR_TAB
3640 return (AS2 (mov,%A0,%B0) CR_TAB
3641 AS1 (lsl,%B0) CR_TAB
3642 AS2 (sbc,%B0,%B0) CR_TAB
3643 AS1 (asr,%A0) CR_TAB
3647 if (AVR_ENHANCED && ldi_ok)
3650 return (AS2 (ldi,%A0,0x20) CR_TAB
3651 AS2 (muls,%B0,%A0) CR_TAB
3652 AS2 (mov,%A0,r1) CR_TAB
3653 AS2 (sbc,%B0,%B0) CR_TAB
3654 AS1 (clr,__zero_reg__));
3656 if (optimize_size && scratch)
3659 return (AS2 (mov,%A0,%B0) CR_TAB
3660 AS1 (lsl,%B0) CR_TAB
3661 AS2 (sbc,%B0,%B0) CR_TAB
3662 AS1 (asr,%A0) CR_TAB
3663 AS1 (asr,%A0) CR_TAB
3667 if (AVR_ENHANCED && ldi_ok)
3670 return (AS2 (ldi,%A0,0x10) CR_TAB
3671 AS2 (muls,%B0,%A0) CR_TAB
3672 AS2 (mov,%A0,r1) CR_TAB
3673 AS2 (sbc,%B0,%B0) CR_TAB
3674 AS1 (clr,__zero_reg__));
3676 if (optimize_size && scratch)
3679 return (AS2 (mov,%A0,%B0) CR_TAB
3680 AS1 (lsl,%B0) CR_TAB
3681 AS2 (sbc,%B0,%B0) CR_TAB
3682 AS1 (asr,%A0) CR_TAB
3683 AS1 (asr,%A0) CR_TAB
3684 AS1 (asr,%A0) CR_TAB
3688 if (AVR_ENHANCED && ldi_ok)
3691 return (AS2 (ldi,%A0,0x08) CR_TAB
3692 AS2 (muls,%B0,%A0) CR_TAB
3693 AS2 (mov,%A0,r1) CR_TAB
3694 AS2 (sbc,%B0,%B0) CR_TAB
3695 AS1 (clr,__zero_reg__));
3698 break; /* scratch ? 5 : 7 */
3700 return (AS2 (mov,%A0,%B0) CR_TAB
3701 AS1 (lsl,%B0) CR_TAB
3702 AS2 (sbc,%B0,%B0) CR_TAB
3703 AS1 (asr,%A0) CR_TAB
3704 AS1 (asr,%A0) CR_TAB
3705 AS1 (asr,%A0) CR_TAB
3706 AS1 (asr,%A0) CR_TAB
3711 return (AS1 (lsl,%B0) CR_TAB
3712 AS2 (sbc,%A0,%A0) CR_TAB
3713 AS1 (lsl,%B0) CR_TAB
3714 AS2 (mov,%B0,%A0) CR_TAB
3718 return *len = 3, (AS1 (lsl,%B0) CR_TAB
3719 AS2 (sbc,%A0,%A0) CR_TAB
3724 out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3726 insn, operands, len, 2);
3731 /* 32bit arithmetic shift right ((signed long)x >> i) */
3734 ashrsi3_out (insn, operands, len)
3739 if (GET_CODE (operands[2]) == CONST_INT)
3747 switch (INTVAL (operands[2]))
3751 int reg0 = true_regnum (operands[0]);
3752 int reg1 = true_regnum (operands[1]);
3755 return (AS2 (mov,%A0,%B1) CR_TAB
3756 AS2 (mov,%B0,%C1) CR_TAB
3757 AS2 (mov,%C0,%D1) CR_TAB
3758 AS1 (clr,%D0) CR_TAB
3759 AS2 (sbrc,%C0,7) CR_TAB
3761 else if (reg0 == reg1 + 1)
3764 return (AS1 (clr,%D0) CR_TAB
3765 AS2 (sbrc,%C0,7) CR_TAB
3769 return (AS1 (clr,%D0) CR_TAB
3770 AS2 (sbrc,%D1,7) CR_TAB
3771 AS1 (dec,%D0) CR_TAB
3772 AS2 (mov,%C0,%D1) CR_TAB
3773 AS2 (mov,%B0,%C1) CR_TAB
3779 int reg0 = true_regnum (operands[0]);
3780 int reg1 = true_regnum (operands[1]);
3782 if (AVR_ENHANCED && (reg0 != reg1 + 2))
3785 return (AS2 (movw,%A0,%C1) CR_TAB
3786 AS1 (clr,%D0) CR_TAB
3787 AS2 (sbrc,%B0,7) CR_TAB
3788 AS1 (com,%D0) CR_TAB
3791 if (reg0 <= reg1 + 1)
3792 return (AS2 (mov,%A0,%C1) CR_TAB
3793 AS2 (mov,%B0,%D1) CR_TAB
3794 AS1 (clr,%D0) CR_TAB
3795 AS2 (sbrc,%B0,7) CR_TAB
3796 AS1 (com,%D0) CR_TAB
3798 else if (reg0 == reg1 + 2)
3799 return *len = 4, (AS1 (clr,%D0) CR_TAB
3800 AS2 (sbrc,%B0,7) CR_TAB
3801 AS1 (com,%D0) CR_TAB
3804 return (AS2 (mov,%B0,%D1) CR_TAB
3805 AS2 (mov,%A0,%C1) CR_TAB
3806 AS1 (clr,%D0) CR_TAB
3807 AS2 (sbrc,%B0,7) CR_TAB
3808 AS1 (com,%D0) CR_TAB
3813 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3814 return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3815 AS1 (clr,%D0) CR_TAB
3816 AS2 (sbrc,%A0,7) CR_TAB
3817 AS1 (com,%D0) CR_TAB
3818 AS2 (mov,%B0,%D0) CR_TAB
3821 return *len = 5, (AS1 (clr,%D0) CR_TAB
3822 AS2 (sbrc,%A0,7) CR_TAB
3823 AS1 (com,%D0) CR_TAB
3824 AS2 (mov,%B0,%D0) CR_TAB
3829 return *len = 4, (AS1 (lsl,%D0) CR_TAB
3830 AS2 (sbc,%A0,%A0) CR_TAB
3831 AS2 (mov,%B0,%A0) CR_TAB
3832 AS2 (movw,%C0,%A0));
3834 return *len = 5, (AS1 (lsl,%D0) CR_TAB
3835 AS2 (sbc,%A0,%A0) CR_TAB
3836 AS2 (mov,%B0,%A0) CR_TAB
3837 AS2 (mov,%C0,%A0) CR_TAB
3842 out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
3843 AS1 (ror,%C0) CR_TAB
3844 AS1 (ror,%B0) CR_TAB
3846 insn, operands, len, 4);
3850 /* 8bit logic shift right ((unsigned char)x >> i) */
3853 lshrqi3_out (insn, operands, len)
3858 if (GET_CODE (operands[2]) == CONST_INT)
3865 switch (INTVAL (operands[2]))
3869 return AS1 (clr,%0);
3873 return AS1 (lsr,%0);
3877 return (AS1 (lsr,%0) CR_TAB
3881 return (AS1 (lsr,%0) CR_TAB
3886 if (test_hard_reg_class (LD_REGS, operands[0]))
3889 return (AS1 (swap,%0) CR_TAB
3890 AS2 (andi,%0,0x0f));
3893 return (AS1 (lsr,%0) CR_TAB
3899 if (test_hard_reg_class (LD_REGS, operands[0]))
3902 return (AS1 (swap,%0) CR_TAB
3907 return (AS1 (lsr,%0) CR_TAB
3914 if (test_hard_reg_class (LD_REGS, operands[0]))
3917 return (AS1 (swap,%0) CR_TAB
3923 return (AS1 (lsr,%0) CR_TAB
3932 return (AS1 (rol,%0) CR_TAB
3937 else if (CONSTANT_P (operands[2]))
3938 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3940 out_shift_with_cnt (AS1 (lsr,%0),
3941 insn, operands, len, 1);
3945 /* 16bit logic shift right ((unsigned short)x >> i) */
3948 lshrhi3_out (insn, operands, len)
3953 if (GET_CODE (operands[2]) == CONST_INT)
3955 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3956 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3963 switch (INTVAL (operands[2]))
3966 if (optimize_size && scratch)
3971 return (AS1 (swap,%B0) CR_TAB
3972 AS1 (swap,%A0) CR_TAB
3973 AS2 (andi,%A0,0x0f) CR_TAB
3974 AS2 (eor,%A0,%B0) CR_TAB
3975 AS2 (andi,%B0,0x0f) CR_TAB
3981 return (AS1 (swap,%B0) CR_TAB
3982 AS1 (swap,%A0) CR_TAB
3983 AS2 (ldi,%3,0x0f) CR_TAB
3984 AS2 (and,%A0,%3) CR_TAB
3985 AS2 (eor,%A0,%B0) CR_TAB
3986 AS2 (and,%B0,%3) CR_TAB
3989 break; /* optimize_size ? 6 : 8 */
3993 break; /* scratch ? 5 : 6 */
3997 return (AS1 (lsr,%B0) CR_TAB
3998 AS1 (ror,%A0) CR_TAB
3999 AS1 (swap,%B0) CR_TAB
4000 AS1 (swap,%A0) CR_TAB
4001 AS2 (andi,%A0,0x0f) CR_TAB
4002 AS2 (eor,%A0,%B0) CR_TAB
4003 AS2 (andi,%B0,0x0f) CR_TAB
4009 return (AS1 (lsr,%B0) CR_TAB
4010 AS1 (ror,%A0) CR_TAB
4011 AS1 (swap,%B0) CR_TAB
4012 AS1 (swap,%A0) CR_TAB
4013 AS2 (ldi,%3,0x0f) CR_TAB
4014 AS2 (and,%A0,%3) CR_TAB
4015 AS2 (eor,%A0,%B0) CR_TAB
4016 AS2 (and,%B0,%3) CR_TAB
4023 break; /* scratch ? 5 : 6 */
4025 return (AS1 (clr,__tmp_reg__) CR_TAB
4026 AS1 (lsl,%A0) CR_TAB
4027 AS1 (rol,%B0) CR_TAB
4028 AS1 (rol,__tmp_reg__) CR_TAB
4029 AS1 (lsl,%A0) CR_TAB
4030 AS1 (rol,%B0) CR_TAB
4031 AS1 (rol,__tmp_reg__) CR_TAB
4032 AS2 (mov,%A0,%B0) CR_TAB
4033 AS2 (mov,%B0,__tmp_reg__));
4037 return (AS1 (lsl,%A0) CR_TAB
4038 AS2 (mov,%A0,%B0) CR_TAB
4039 AS1 (rol,%A0) CR_TAB
4040 AS2 (sbc,%B0,%B0) CR_TAB
4044 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
4045 return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
4048 return *len = 1, AS1 (clr,%B0);
4052 return (AS2 (mov,%A0,%B0) CR_TAB
4053 AS1 (clr,%B0) CR_TAB
4058 return (AS2 (mov,%A0,%B0) CR_TAB
4059 AS1 (clr,%B0) CR_TAB
4060 AS1 (lsr,%A0) CR_TAB
4065 return (AS2 (mov,%A0,%B0) CR_TAB
4066 AS1 (clr,%B0) CR_TAB
4067 AS1 (lsr,%A0) CR_TAB
4068 AS1 (lsr,%A0) CR_TAB
4075 return (AS2 (mov,%A0,%B0) CR_TAB
4076 AS1 (clr,%B0) CR_TAB
4077 AS1 (swap,%A0) CR_TAB
4078 AS2 (andi,%A0,0x0f));
4083 return (AS2 (mov,%A0,%B0) CR_TAB
4084 AS1 (clr,%B0) CR_TAB
4085 AS1 (swap,%A0) CR_TAB
4086 AS2 (ldi,%3,0x0f) CR_TAB
4090 return (AS2 (mov,%A0,%B0) CR_TAB
4091 AS1 (clr,%B0) CR_TAB
4092 AS1 (lsr,%A0) CR_TAB
4093 AS1 (lsr,%A0) CR_TAB
4094 AS1 (lsr,%A0) CR_TAB
4101 return (AS2 (mov,%A0,%B0) CR_TAB
4102 AS1 (clr,%B0) CR_TAB
4103 AS1 (swap,%A0) CR_TAB
4104 AS1 (lsr,%A0) CR_TAB
4105 AS2 (andi,%A0,0x07));
4107 if (AVR_ENHANCED && scratch)
4110 return (AS2 (ldi,%3,0x08) CR_TAB
4111 AS2 (mul,%B0,%3) CR_TAB
4112 AS2 (mov,%A0,r1) CR_TAB
4113 AS1 (clr,%B0) CR_TAB
4114 AS1 (clr,__zero_reg__));
4116 if (optimize_size && scratch)
4121 return (AS2 (mov,%A0,%B0) CR_TAB
4122 AS1 (clr,%B0) CR_TAB
4123 AS1 (swap,%A0) CR_TAB
4124 AS1 (lsr,%A0) CR_TAB
4125 AS2 (ldi,%3,0x07) CR_TAB
4131 return ("set" CR_TAB
4132 AS2 (bld,r1,3) CR_TAB
4133 AS2 (mul,%B0,r1) CR_TAB
4134 AS2 (mov,%A0,r1) CR_TAB
4135 AS1 (clr,%B0) CR_TAB
4136 AS1 (clr,__zero_reg__));
4139 return (AS2 (mov,%A0,%B0) CR_TAB
4140 AS1 (clr,%B0) CR_TAB
4141 AS1 (lsr,%A0) CR_TAB
4142 AS1 (lsr,%A0) CR_TAB
4143 AS1 (lsr,%A0) CR_TAB
4144 AS1 (lsr,%A0) CR_TAB
4148 if (AVR_ENHANCED && ldi_ok)
4151 return (AS2 (ldi,%A0,0x04) CR_TAB
4152 AS2 (mul,%B0,%A0) CR_TAB
4153 AS2 (mov,%A0,r1) CR_TAB
4154 AS1 (clr,%B0) CR_TAB
4155 AS1 (clr,__zero_reg__));
4157 if (AVR_ENHANCED && scratch)
4160 return (AS2 (ldi,%3,0x04) CR_TAB
4161 AS2 (mul,%B0,%3) CR_TAB
4162 AS2 (mov,%A0,r1) CR_TAB
4163 AS1 (clr,%B0) CR_TAB
4164 AS1 (clr,__zero_reg__));
4166 if (optimize_size && ldi_ok)
4169 return (AS2 (mov,%A0,%B0) CR_TAB
4170 AS2 (ldi,%B0,6) "\n1:\t"
4171 AS1 (lsr,%A0) CR_TAB
4172 AS1 (dec,%B0) CR_TAB
4175 if (optimize_size && scratch)
4178 return (AS1 (clr,%A0) CR_TAB
4179 AS1 (lsl,%B0) CR_TAB
4180 AS1 (rol,%A0) CR_TAB
4181 AS1 (lsl,%B0) CR_TAB
4182 AS1 (rol,%A0) CR_TAB
4187 return (AS1 (clr,%A0) CR_TAB
4188 AS1 (lsl,%B0) CR_TAB
4189 AS1 (rol,%A0) CR_TAB
4194 out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
4196 insn, operands, len, 2);
4200 /* 32bit logic shift right ((unsigned int)x >> i) */
4203 lshrsi3_out (insn, operands, len)
4208 if (GET_CODE (operands[2]) == CONST_INT)
4216 switch (INTVAL (operands[2]))
4220 int reg0 = true_regnum (operands[0]);
4221 int reg1 = true_regnum (operands[1]);
4224 return (AS2 (mov,%A0,%B1) CR_TAB
4225 AS2 (mov,%B0,%C1) CR_TAB
4226 AS2 (mov,%C0,%D1) CR_TAB
4228 else if (reg0 == reg1 + 1)
4229 return *len = 1, AS1 (clr,%D0);
4231 return (AS1 (clr,%D0) CR_TAB
4232 AS2 (mov,%C0,%D1) CR_TAB
4233 AS2 (mov,%B0,%C1) CR_TAB
4239 int reg0 = true_regnum (operands[0]);
4240 int reg1 = true_regnum (operands[1]);
4242 if (AVR_ENHANCED && (reg0 != reg1 + 2))
4245 return (AS2 (movw,%A0,%C1) CR_TAB
4246 AS1 (clr,%C0) CR_TAB
4249 if (reg0 <= reg1 + 1)
4250 return (AS2 (mov,%A0,%C1) CR_TAB
4251 AS2 (mov,%B0,%D1) CR_TAB
4252 AS1 (clr,%C0) CR_TAB
4254 else if (reg0 == reg1 + 2)
4255 return *len = 2, (AS1 (clr,%C0) CR_TAB
4258 return (AS2 (mov,%B0,%D1) CR_TAB
4259 AS2 (mov,%A0,%C1) CR_TAB
4260 AS1 (clr,%C0) CR_TAB
4265 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
4266 return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4267 AS1 (clr,%B0) CR_TAB
4268 AS1 (clr,%C0) CR_TAB
4271 return *len = 3, (AS1 (clr,%B0) CR_TAB
4272 AS1 (clr,%C0) CR_TAB
4277 return (AS1 (clr,%A0) CR_TAB
4278 AS2 (sbrc,%D0,7) CR_TAB
4279 AS1 (inc,%A0) CR_TAB
4280 AS1 (clr,%B0) CR_TAB
4281 AS1 (clr,%C0) CR_TAB
4286 out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4287 AS1 (ror,%C0) CR_TAB
4288 AS1 (ror,%B0) CR_TAB
4290 insn, operands, len, 4);
4294 /* Modifies the length assigned to instruction INSN
4295 LEN is the initially computed length of the insn. */
4298 adjust_insn_length (insn, len)
4302 rtx patt = PATTERN (insn);
4305 if (GET_CODE (patt) == SET)
4308 op[1] = SET_SRC (patt);
4309 op[0] = SET_DEST (patt);
4310 if (general_operand (op[1], VOIDmode)
4311 && general_operand (op[0], VOIDmode))
4313 switch (GET_MODE (op[0]))
4316 output_movqi (insn, op, &len);
4319 output_movhi (insn, op, &len);
4323 output_movsisf (insn, op, &len);
4329 else if (op[0] == cc0_rtx && REG_P (op[1]))
4331 switch (GET_MODE (op[1]))
4333 case HImode: out_tsthi (insn,&len); break;
4334 case SImode: out_tstsi (insn,&len); break;
4338 else if (GET_CODE (op[1]) == AND)
4340 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4342 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4343 if (GET_MODE (op[1]) == SImode)
4344 len = (((mask & 0xff) != 0xff)
4345 + ((mask & 0xff00) != 0xff00)
4346 + ((mask & 0xff0000L) != 0xff0000L)
4347 + ((mask & 0xff000000L) != 0xff000000L));
4348 else if (GET_MODE (op[1]) == HImode)
4349 len = (((mask & 0xff) != 0xff)
4350 + ((mask & 0xff00) != 0xff00));
4353 else if (GET_CODE (op[1]) == IOR)
4355 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4357 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4358 if (GET_MODE (op[1]) == SImode)
4359 len = (((mask & 0xff) != 0)
4360 + ((mask & 0xff00) != 0)
4361 + ((mask & 0xff0000L) != 0)
4362 + ((mask & 0xff000000L) != 0));
4363 else if (GET_MODE (op[1]) == HImode)
4364 len = (((mask & 0xff) != 0)
4365 + ((mask & 0xff00) != 0));
4369 set = single_set (insn);
4374 op[1] = SET_SRC (set);
4375 op[0] = SET_DEST (set);
4377 if (GET_CODE (patt) == PARALLEL
4378 && general_operand (op[1], VOIDmode)
4379 && general_operand (op[0], VOIDmode))
4381 if (XVECLEN (patt, 0) == 2)
4382 op[2] = XVECEXP (patt, 0, 1);
4384 switch (GET_MODE (op[0]))
4390 output_reload_inhi (insn, op, &len);
4394 output_reload_insisf (insn, op, &len);
4400 else if (GET_CODE (op[1]) == ASHIFT
4401 || GET_CODE (op[1]) == ASHIFTRT
4402 || GET_CODE (op[1]) == LSHIFTRT)
4406 ops[1] = XEXP (op[1],0);
4407 ops[2] = XEXP (op[1],1);
4408 switch (GET_CODE (op[1]))
4411 switch (GET_MODE (op[0]))
4413 case QImode: ashlqi3_out (insn,ops,&len); break;
4414 case HImode: ashlhi3_out (insn,ops,&len); break;
4415 case SImode: ashlsi3_out (insn,ops,&len); break;
4420 switch (GET_MODE (op[0]))
4422 case QImode: ashrqi3_out (insn,ops,&len); break;
4423 case HImode: ashrhi3_out (insn,ops,&len); break;
4424 case SImode: ashrsi3_out (insn,ops,&len); break;
4429 switch (GET_MODE (op[0]))
4431 case QImode: lshrqi3_out (insn,ops,&len); break;
4432 case HImode: lshrhi3_out (insn,ops,&len); break;
4433 case SImode: lshrsi3_out (insn,ops,&len); break;
4445 /* Return nonzero if register REG dead after INSN */
4448 reg_unused_after (insn, reg)
4452 return (dead_or_set_p (insn, reg)
4453 || (REG_P(reg) && _reg_unused_after (insn, reg)));
4456 /* Return nonzero if REG is not used after INSN.
4457 We assume REG is a reload reg, and therefore does
4458 not live past labels. It may live past calls or jumps though. */
4461 _reg_unused_after (insn, reg)
4468 /* If the reg is set by this instruction, then it is safe for our
4469 case. Disregard the case where this is a store to memory, since
4470 we are checking a register used in the store address. */
4471 set = single_set (insn);
4472 if (set && GET_CODE (SET_DEST (set)) != MEM
4473 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4476 while ((insn = NEXT_INSN (insn)))
4478 code = GET_CODE (insn);
4481 /* If this is a label that existed before reload, then the register
4482 if dead here. However, if this is a label added by reorg, then
4483 the register may still be live here. We can't tell the difference,
4484 so we just ignore labels completely. */
4485 if (code == CODE_LABEL)
4490 if (code == JUMP_INSN)
4493 /* If this is a sequence, we must handle them all at once.
4494 We could have for instance a call that sets the target register,
4495 and an insn in a delay slot that uses the register. In this case,
4496 we must return 0. */
4497 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
4502 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
4504 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
4505 rtx set = single_set (this_insn);
4507 if (GET_CODE (this_insn) == CALL_INSN)
4509 else if (GET_CODE (this_insn) == JUMP_INSN)
4511 if (INSN_ANNULLED_BRANCH_P (this_insn))
4516 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4518 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4520 if (GET_CODE (SET_DEST (set)) != MEM)
4526 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
4531 else if (code == JUMP_INSN)
4535 if (code == CALL_INSN)
4538 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4539 if (GET_CODE (XEXP (tem, 0)) == USE
4540 && REG_P (XEXP (XEXP (tem, 0), 0))
4541 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
4543 if (call_used_regs[REGNO (reg)])
4547 if (GET_RTX_CLASS (code) == 'i')
4549 rtx set = single_set (insn);
4551 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4553 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4554 return GET_CODE (SET_DEST (set)) != MEM;
4555 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
4562 /* Target hook for assembling integer objects. The AVR version needs
4563 special handling for references to certain labels. */
4566 avr_assemble_integer (x, size, aligned_p)
4571 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
4572 && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x))
4573 || GET_CODE (x) == LABEL_REF))
4575 fputs ("\t.word\tpm(", asm_out_file);
4576 output_addr_const (asm_out_file, x);
4577 fputs (")\n", asm_out_file);
4580 return default_assemble_integer (x, size, aligned_p);
4583 /* Sets section name for declaration DECL */
4586 avr_unique_section (decl, reloc)
4588 int reloc ATTRIBUTE_UNUSED;
4591 const char *name, *prefix;
4594 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
4595 name = (* targetm.strip_name_encoding) (name);
4597 if (TREE_CODE (decl) == FUNCTION_DECL)
4599 if (flag_function_sections)
4607 if (flag_function_sections)
4609 len = strlen (name) + strlen (prefix);
4610 string = alloca (len + 1);
4611 sprintf (string, "%s%s", prefix, name);
4612 DECL_SECTION_NAME (decl) = build_string (len, string);
4617 /* The routine used to output NUL terminated strings. We use a special
4618 version of this for most svr4 targets because doing so makes the
4619 generated assembly code more compact (and thus faster to assemble)
4620 as well as more readable, especially for targets like the i386
4621 (where the only alternative is to output character sequences as
4622 comma separated lists of numbers). */
4625 gas_output_limited_string(file, str)
4629 const unsigned char *_limited_str = (unsigned char *) str;
4631 fprintf (file, "%s\"", STRING_ASM_OP);
4632 for (; (ch = *_limited_str); _limited_str++)
4635 switch (escape = ESCAPES[ch])
4641 fprintf (file, "\\%03o", ch);
4645 putc (escape, file);
4649 fprintf (file, "\"\n");
4652 /* The routine used to output sequences of byte values. We use a special
4653 version of this for most svr4 targets because doing so makes the
4654 generated assembly code more compact (and thus faster to assemble)
4655 as well as more readable. Note that if we find subparts of the
4656 character sequence which end with NUL (and which are shorter than
4657 STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
4660 gas_output_ascii(file, str, length)
4665 const unsigned char *_ascii_bytes = (const unsigned char *) str;
4666 const unsigned char *limit = _ascii_bytes + length;
4667 unsigned bytes_in_chunk = 0;
4668 for (; _ascii_bytes < limit; _ascii_bytes++)
4670 const unsigned char *p;
4671 if (bytes_in_chunk >= 60)
4673 fprintf (file, "\"\n");
4676 for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
4678 if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
4680 if (bytes_in_chunk > 0)
4682 fprintf (file, "\"\n");
4685 gas_output_limited_string (file, (char*)_ascii_bytes);
4692 if (bytes_in_chunk == 0)
4693 fprintf (file, "\t.ascii\t\"");
4694 switch (escape = ESCAPES[ch = *_ascii_bytes])
4701 fprintf (file, "\\%03o", ch);
4702 bytes_in_chunk += 4;
4706 putc (escape, file);
4707 bytes_in_chunk += 2;
4712 if (bytes_in_chunk > 0)
4713 fprintf (file, "\"\n");
4716 /* Return value is nonzero if pseudos that have been
4717 assigned to registers of class CLASS would likely be spilled
4718 because registers of CLASS are needed for spill registers. */
4721 class_likely_spilled_p (c)
4724 return (c != ALL_REGS && c != ADDW_REGS);
4727 /* Valid attributes:
4728 progmem - put data to program memory;
4729 signal - make a function to be hardware interrupt. After function
4730 prologue interrupts are disabled;
4731 interrupt - make a function to be hardware interrupt. After function
4732 prologue interrupts are enabled;
4733 naked - don't generate function prologue/epilogue and `ret' command.
4735 Only `progmem' attribute valid for type. */
4737 const struct attribute_spec avr_attribute_table[] =
4739 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
4740 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute },
4741 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4742 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4743 { "naked", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4744 { NULL, 0, 0, false, false, false, NULL }
4747 /* Handle a "progmem" attribute; arguments as in
4748 struct attribute_spec.handler. */
4750 avr_handle_progmem_attribute (node, name, args, flags, no_add_attrs)
4753 tree args ATTRIBUTE_UNUSED;
4754 int flags ATTRIBUTE_UNUSED;
4759 if (TREE_CODE (*node) == TYPE_DECL)
4761 /* This is really a decl attribute, not a type attribute,
4762 but try to handle it for GCC 3.0 backwards compatibility. */
4764 tree type = TREE_TYPE (*node);
4765 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
4766 tree newtype = build_type_attribute_variant (type, attr);
4768 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
4769 TREE_TYPE (*node) = newtype;
4770 *no_add_attrs = true;
4772 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
4774 if (DECL_INITIAL (*node) == NULL_TREE && !DECL_EXTERNAL (*node))
4776 warning ("only initialized variables can be placed into "
4777 "program memory area");
4778 *no_add_attrs = true;
4783 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
4784 *no_add_attrs = true;
4791 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
4792 struct attribute_spec.handler. */
4794 avr_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
4797 tree args ATTRIBUTE_UNUSED;
4798 int flags ATTRIBUTE_UNUSED;
4801 if (TREE_CODE (*node) != FUNCTION_DECL)
4803 warning ("`%s' attribute only applies to functions",
4804 IDENTIFIER_POINTER (name));
4805 *no_add_attrs = true;
4811 /* Look for attribute `progmem' in DECL
4812 if found return 1, otherwise 0. */
4815 avr_progmem_p (decl)
4820 if (TREE_CODE (decl) != VAR_DECL)
4824 != lookup_attribute ("progmem", DECL_ATTRIBUTES (decl)))
4830 while (TREE_CODE (a) == ARRAY_TYPE);
4832 if (a == error_mark_node)
4835 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
4841 /* Add the section attribute if the variable is in progmem. */
4844 avr_insert_attributes (node, attributes)
4848 if (TREE_CODE (node) == VAR_DECL
4849 && (TREE_STATIC (node) || DECL_EXTERNAL (node))
4850 && avr_progmem_p (node))
4852 static const char dsec[] = ".progmem.data";
4853 *attributes = tree_cons (get_identifier ("section"),
4854 build_tree_list (NULL, build_string (strlen (dsec), dsec)),
4857 /* ??? This seems sketchy. Why can't the user declare the
4858 thing const in the first place? */
4859 TREE_READONLY (node) = 1;
4864 avr_section_type_flags (decl, name, reloc)
4869 unsigned int flags = default_section_type_flags (decl, name, reloc);
4871 if (strncmp (name, ".noinit", 7) == 0)
4873 if (decl && TREE_CODE (decl) == VAR_DECL
4874 && DECL_INITIAL (decl) == NULL_TREE)
4875 flags |= SECTION_BSS; /* @nobits */
4877 warning ("only uninitialized variables can be placed in the "
4884 /* Outputs to the stdio stream FILE some
4885 appropriate text to go at the start of an assembler file. */
4888 asm_file_start (file)
4892 error ("MCU `%s' supported for assembler only", avr_mcu_name);
4894 output_file_directive (file, main_input_filename);
4895 fprintf (file, "\t.arch %s\n", avr_mcu_name);
4896 fputs ("__SREG__ = 0x3f\n"
4898 "__SP_L__ = 0x3d\n", file);
4900 fputs ("__tmp_reg__ = 0\n"
4901 "__zero_reg__ = 1\n", file);
4903 /* FIXME: output these only if there is anything in the .data / .bss
4904 sections - some code size could be saved by not linking in the
4905 initialization code from libgcc if one or both sections are empty. */
4906 fputs ("\t.global __do_copy_data\n", file);
4907 fputs ("\t.global __do_clear_bss\n", file);
4909 commands_in_file = 0;
4910 commands_in_prologues = 0;
4911 commands_in_epilogues = 0;
4914 /* Outputs to the stdio stream FILE some
4915 appropriate text to go at the end of an assembler file. */
4921 fputs ("/* File ", file);
4922 output_quoted_string (file, main_input_filename);
4924 ": code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
4927 commands_in_file - commands_in_prologues - commands_in_epilogues,
4928 commands_in_prologues, commands_in_epilogues);
4931 /* Choose the order in which to allocate hard registers for
4932 pseudo-registers local to a basic block.
4934 Store the desired register order in the array `reg_alloc_order'.
4935 Element 0 should be the register to allocate first; element 1, the
4936 next register; and so on. */
4939 order_regs_for_local_alloc ()
4942 static const int order_0[] = {
4950 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4954 static const int order_1[] = {
4962 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4966 static const int order_2[] = {
4975 15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4980 const int *order = (TARGET_ORDER_1 ? order_1 :
4981 TARGET_ORDER_2 ? order_2 :
4983 for (i=0; i < ARRAY_SIZE (order_0); ++i)
4984 reg_alloc_order[i] = order[i];
4987 /* Calculate the cost of X code of the expression in which it is contained,
4988 found in OUTER_CODE */
4991 default_rtx_costs (X, code, outer_code)
4994 enum rtx_code outer_code;
5001 cost = 2 * GET_MODE_SIZE (GET_MODE (X));
5004 if (outer_code != SET)
5006 if (GET_CODE (XEXP (X,0)) == SYMBOL_REF)
5007 cost += 2 * GET_MODE_SIZE (GET_MODE (X));
5009 cost += GET_MODE_SIZE (GET_MODE (X));
5015 if (outer_code == SET)
5016 cost = GET_MODE_SIZE (GET_MODE (X));
5018 cost = -GET_MODE_SIZE (GET_MODE (X));
5021 if (outer_code == SET)
5022 cost = GET_MODE_SIZE (GET_MODE (X));
5028 if (outer_code == SET)
5030 if (X == stack_pointer_rtx)
5032 else if (GET_CODE (XEXP (X,1)) == CONST_INT)
5033 cost = (INTVAL (XEXP (X,1)) <= 63 ? 1 :
5034 GET_MODE_SIZE (GET_MODE (X)));
5036 cost = GET_MODE_SIZE (GET_MODE (X));
5040 if (GET_CODE (XEXP (X,1)) == CONST_INT)
5041 cost = GET_MODE_SIZE (GET_MODE (XEXP (X,0)));
5050 avr_rtx_costs (x, code, outer_code, total)
5052 int code, outer_code;
5060 if (outer_code == PLUS
5061 || outer_code == IOR
5062 || outer_code == AND
5063 || outer_code == MINUS
5064 || outer_code == SET
5070 if (outer_code == COMPARE
5072 && INTVAL (x) <= 255)
5087 cst = default_rtx_costs (x, code, outer_code);
5099 /* Calculate the cost of a memory address */
5102 avr_address_cost (x)
5105 if (GET_CODE (x) == PLUS
5106 && GET_CODE (XEXP (x,1)) == CONST_INT
5107 && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
5108 && INTVAL (XEXP (x,1)) >= 61)
5110 if (CONSTANT_ADDRESS_P (x))
5112 if (avr_io_address_p (x, 1))
5119 /* EXTRA_CONSTRAINT helper */
5122 extra_constraint (x, c)
5127 && GET_CODE (x) == MEM
5128 && GET_CODE (XEXP (x,0)) == PLUS)
5130 if (TARGET_ALL_DEBUG)
5132 fprintf (stderr, ("extra_constraint:\n"
5133 "reload_completed: %d\n"
5134 "reload_in_progress: %d\n"),
5135 reload_completed, reload_in_progress);
5138 if (GET_CODE (x) == MEM
5139 && GET_CODE (XEXP (x,0)) == PLUS
5140 && REG_P (XEXP (XEXP (x,0), 0))
5141 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
5142 && (INTVAL (XEXP (XEXP (x,0), 1))
5143 <= MAX_LD_OFFSET (GET_MODE (x))))
5145 rtx xx = XEXP (XEXP (x,0), 0);
5146 int regno = REGNO (xx);
5147 if (TARGET_ALL_DEBUG)
5149 fprintf (stderr, ("extra_constraint:\n"
5150 "reload_completed: %d\n"
5151 "reload_in_progress: %d\n"),
5152 reload_completed, reload_in_progress);
5155 if (regno >= FIRST_PSEUDO_REGISTER)
5156 return 1; /* allocate pseudos */
5157 else if (regno == REG_Z || regno == REG_Y)
5158 return 1; /* strictly check */
5159 else if (xx == frame_pointer_rtx
5160 || xx == arg_pointer_rtx)
5161 return 1; /* XXX frame & arg pointer checks */
5167 /* Convert condition code CONDITION to the valid AVR condition code */
5170 avr_normalize_condition (condition)
5188 /* This fnction optimizes conditional jumps */
5191 machine_dependent_reorg (first_insn)
5196 for (insn = first_insn; insn; insn = NEXT_INSN (insn))
5198 if (! (GET_CODE (insn) == INSN
5199 || GET_CODE (insn) == CALL_INSN
5200 || GET_CODE (insn) == JUMP_INSN)
5201 || !single_set (insn))
5204 pattern = PATTERN (insn);
5206 if (GET_CODE (pattern) == PARALLEL)
5207 pattern = XVECEXP (pattern, 0, 0);
5208 if (GET_CODE (pattern) == SET
5209 && SET_DEST (pattern) == cc0_rtx
5210 && compare_diff_p (insn))
5212 if (GET_CODE (SET_SRC (pattern)) == COMPARE)
5214 /* Now we work under compare insn */
5216 pattern = SET_SRC (pattern);
5217 if (true_regnum (XEXP (pattern,0)) >= 0
5218 && true_regnum (XEXP (pattern,1)) >= 0 )
5220 rtx x = XEXP (pattern,0);
5221 rtx next = next_real_insn (insn);
5222 rtx pat = PATTERN (next);
5223 rtx src = SET_SRC (pat);
5224 rtx t = XEXP (src,0);
5225 PUT_CODE (t, swap_condition (GET_CODE (t)));
5226 XEXP (pattern,0) = XEXP (pattern,1);
5227 XEXP (pattern,1) = x;
5228 INSN_CODE (next) = -1;
5230 else if (true_regnum (XEXP (pattern,0)) >= 0
5231 && GET_CODE (XEXP (pattern,1)) == CONST_INT)
5233 rtx x = XEXP (pattern,1);
5234 rtx next = next_real_insn (insn);
5235 rtx pat = PATTERN (next);
5236 rtx src = SET_SRC (pat);
5237 rtx t = XEXP (src,0);
5238 enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
5240 if (avr_simplify_comparision_p (mode, GET_CODE (t), x))
5242 XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
5243 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
5244 INSN_CODE (next) = -1;
5245 INSN_CODE (insn) = -1;
5249 else if (true_regnum (SET_SRC (pattern)) >= 0)
5251 /* This is a tst insn */
5252 rtx next = next_real_insn (insn);
5253 rtx pat = PATTERN (next);
5254 rtx src = SET_SRC (pat);
5255 rtx t = XEXP (src,0);
5257 PUT_CODE (t, swap_condition (GET_CODE (t)));
5258 SET_SRC (pattern) = gen_rtx (NEG,
5259 GET_MODE (SET_SRC (pattern)),
5261 INSN_CODE (next) = -1;
5262 INSN_CODE (insn) = -1;
5268 /* Returns register number for function return value.*/
5276 /* Ceate an RTX representing the place where a
5277 library function returns a value of mode MODE. */
5280 avr_libcall_value (mode)
5281 enum machine_mode mode;
5283 int offs = GET_MODE_SIZE (mode);
5286 return gen_rtx (REG, mode, RET_REGISTER + 2 - offs);
5289 /* Create an RTX representing the place where a
5290 function returns a value of data type VALTYPE. */
5293 avr_function_value (type, func)
5295 tree func ATTRIBUTE_UNUSED;
5299 if (TYPE_MODE (type) != BLKmode)
5300 return avr_libcall_value (TYPE_MODE (type));
5302 offs = int_size_in_bytes (type);
5305 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
5306 offs = GET_MODE_SIZE (SImode);
5307 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
5308 offs = GET_MODE_SIZE (DImode);
5310 return gen_rtx (REG, BLKmode, RET_REGISTER + 2 - offs);
5313 /* Returns nonzero if the number MASK has only one bit set. */
5316 mask_one_bit_p (mask)
5320 unsigned HOST_WIDE_INT n=mask;
5321 for (i = 0; i < 32; ++i)
5323 if (n & 0x80000000L)
5325 if (n & 0x7fffffffL)
5336 /* Places additional restrictions on the register class to
5337 use when it is necessary to copy value X into a register
5341 preferred_reload_class (x, class)
5342 rtx x ATTRIBUTE_UNUSED;
5343 enum reg_class class;
5349 test_hard_reg_class (class, x)
5350 enum reg_class class;
5353 int regno = true_regnum (x);
5357 if (TEST_HARD_REG_CLASS (class, regno))
5365 jump_over_one_insn_p (insn, dest)
5369 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
5372 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
5373 int dest_addr = INSN_ADDRESSES (uid);
5374 return dest_addr - jump_addr == get_attr_length (insn) + 1;
5377 /* Returns 1 if a value of mode MODE can be stored starting with hard
5378 register number REGNO. On the enhanced core, anything larger than
5379 1 byte must start in even numbered register for "movw" to work
5380 (this way we don't have to check for odd registers everywhere). */
5383 avr_hard_regno_mode_ok (regno, mode)
5385 enum machine_mode mode;
5387 /* Bug workaround: recog.c (peep2_find_free_register) and probably
5388 a few other places assume that the frame pointer is a single hard
5389 register, so r29 may be allocated and overwrite the high byte of
5390 the frame pointer. Do not allow any value to start in r29. */
5391 if (regno == REG_Y + 1)
5396 /* if (regno < 24 && !AVR_ENHANCED)
5398 return !(regno & 1);
5401 /* Returns 1 if we know register operand OP was 0 before INSN. */
5404 reg_was_0 (insn, op)
5409 return (optimize > 0 && insn && op && REG_P (op)
5410 && (link = find_reg_note (insn, REG_WAS_0, 0))
5411 /* Make sure the insn that stored the 0 is still present. */
5412 && ! INSN_DELETED_P (XEXP (link, 0))
5413 && GET_CODE (XEXP (link, 0)) != NOTE
5414 /* Make sure cross jumping didn't happen here. */
5415 && no_labels_between_p (XEXP (link, 0), insn)
5416 /* Make sure the reg hasn't been clobbered. */
5417 && ! reg_set_between_p (op, XEXP (link, 0), insn));
5420 /* Returns 1 if X is a valid address for an I/O register of size SIZE
5421 (1 or 2). Used for lds/sts -> in/out optimization. Add 0x20 to SIZE
5422 to check for the lower half of I/O space (for cbi/sbi/sbic/sbis). */
5425 avr_io_address_p (x, size)
5429 return (optimize > 0 && GET_CODE (x) == CONST_INT
5430 && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size);
5433 /* Returns nonzero (bit number + 1) if X, or -X, is a constant power of 2. */
5436 const_int_pow2_p (x)
5439 if (GET_CODE (x) == CONST_INT)
5441 HOST_WIDE_INT d = INTVAL (x);
5442 HOST_WIDE_INT abs_d = (d >= 0) ? d : -d;
5443 return exact_log2 (abs_d) + 1;
5449 output_reload_inhi (insn, operands, len)
5450 rtx insn ATTRIBUTE_UNUSED;
5458 if (GET_CODE (operands[1]) == CONST_INT)
5460 int val = INTVAL (operands[1]);
5461 if ((val & 0xff) == 0)
5464 return (AS2 (mov,%A0,__zero_reg__) CR_TAB
5465 AS2 (ldi,%2,hi8(%1)) CR_TAB
5468 else if ((val & 0xff00) == 0)
5471 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5472 AS2 (mov,%A0,%2) CR_TAB
5473 AS2 (mov,%B0,__zero_reg__));
5475 else if ((val & 0xff) == ((val & 0xff00) >> 8))
5478 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5479 AS2 (mov,%A0,%2) CR_TAB
5484 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5485 AS2 (mov,%A0,%2) CR_TAB
5486 AS2 (ldi,%2,hi8(%1)) CR_TAB
5492 output_reload_insisf (insn, operands, len)
5493 rtx insn ATTRIBUTE_UNUSED;
5497 rtx src = operands[1];
5498 int cnst = (GET_CODE (src) == CONST_INT);
5503 *len = 4 + ((INTVAL (src) & 0xff) != 0)
5504 + ((INTVAL (src) & 0xff00) != 0)
5505 + ((INTVAL (src) & 0xff0000) != 0)
5506 + ((INTVAL (src) & 0xff000000) != 0);
5513 if (cnst && ((INTVAL (src) & 0xff) == 0))
5514 output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
5517 output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
5518 output_asm_insn (AS2 (mov, %A0, %2), operands);
5520 if (cnst && ((INTVAL (src) & 0xff00) == 0))
5521 output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
5524 output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
5525 output_asm_insn (AS2 (mov, %B0, %2), operands);
5527 if (cnst && ((INTVAL (src) & 0xff0000) == 0))
5528 output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
5531 output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
5532 output_asm_insn (AS2 (mov, %C0, %2), operands);
5534 if (cnst && ((INTVAL (src) & 0xff000000) == 0))
5535 output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
5538 output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
5539 output_asm_insn (AS2 (mov, %D0, %2), operands);
5545 avr_output_bld (operands, bit_nr)
5549 static char s[] = "bld %A0,0";
5551 s[5] = 'A' + (bit_nr >> 3);
5552 s[8] = '0' + (bit_nr & 7);
5553 output_asm_insn (s, operands);
5557 avr_output_addr_vec_elt (stream, value)
5562 fprintf (stream, "\t.word pm(.L%d)\n", value);
5564 fprintf (stream, "\trjmp .L%d\n", value);
5569 /* Returns 1 if SCRATCH are safe to be allocated as a scratch
5570 registers (for a define_peephole2) in the current function. */
5573 avr_peep2_scratch_safe (scratch)
5576 if ((interrupt_function_p (current_function_decl)
5577 || signal_function_p (current_function_decl))
5578 && leaf_function_p ())
5580 int first_reg = true_regnum (scratch);
5581 int last_reg = first_reg + GET_MODE_SIZE (GET_MODE (scratch)) - 1;
5584 for (reg = first_reg; reg <= last_reg; reg++)
5586 if (!regs_ever_live[reg])
5593 /* Output a branch that tests a single bit of a register (QI, HI or SImode)
5594 or memory location in the I/O space (QImode only).
5596 Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
5597 Operand 1: register operand to test, or CONST_INT memory address.
5598 Operand 2: bit number (for QImode operand) or mask (HImode, SImode).
5599 Operand 3: label to jump to if the test is true. */
5602 avr_out_sbxx_branch (insn, operands)
5606 enum rtx_code comp = GET_CODE (operands[0]);
5607 int long_jump = (get_attr_length (insn) >= 4);
5608 int reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
5612 else if (comp == LT)
5616 comp = reverse_condition (comp);
5618 if (GET_CODE (operands[1]) == CONST_INT)
5620 if (INTVAL (operands[1]) < 0x40)
5623 output_asm_insn (AS2 (sbis,%1-0x20,%2), operands);
5625 output_asm_insn (AS2 (sbic,%1-0x20,%2), operands);
5629 output_asm_insn (AS2 (in,__tmp_reg__,%1-0x20), operands);
5631 output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands);
5633 output_asm_insn (AS2 (sbrc,__tmp_reg__,%2), operands);
5636 else /* GET_CODE (operands[1]) == REG */
5638 if (GET_MODE (operands[1]) == QImode)
5641 output_asm_insn (AS2 (sbrs,%1,%2), operands);
5643 output_asm_insn (AS2 (sbrc,%1,%2), operands);
5645 else /* HImode or SImode */
5647 static char buf[] = "sbrc %A1,0";
5648 int bit_nr = exact_log2 (INTVAL (operands[2])
5649 & GET_MODE_MASK (GET_MODE (operands[1])));
5651 buf[3] = (comp == EQ) ? 's' : 'c';
5652 buf[6] = 'A' + (bit_nr >> 3);
5653 buf[9] = '0' + (bit_nr & 7);
5654 output_asm_insn (buf, operands);
5659 return (AS1 (rjmp,.+4) CR_TAB
5662 return AS1 (rjmp,%3);
5667 avr_asm_out_ctor (symbol, priority)
5671 fputs ("\t.global __do_global_ctors\n", asm_out_file);
5672 default_ctor_section_asm_out_constructor (symbol, priority);
5676 avr_asm_out_dtor (symbol, priority)
5680 fputs ("\t.global __do_global_dtors\n", asm_out_file);
5681 default_dtor_section_asm_out_destructor (symbol, priority);