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 tree avr_handle_progmem_attribute PARAMS ((tree *, tree, tree, int, bool *));
62 static tree avr_handle_fndecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
63 const struct attribute_spec avr_attribute_table[];
64 static bool avr_assemble_integer PARAMS ((rtx, unsigned int, int));
65 static void avr_file_start PARAMS ((void));
66 static void avr_file_end PARAMS ((void));
67 static void avr_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
68 static void avr_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
69 static void avr_unique_section PARAMS ((tree, int));
70 static void avr_insert_attributes PARAMS ((tree, tree *));
71 static unsigned int avr_section_type_flags PARAMS ((tree, const char *, int));
73 static void avr_reorg PARAMS ((void));
74 static void avr_asm_out_ctor PARAMS ((rtx, int));
75 static void avr_asm_out_dtor PARAMS ((rtx, int));
76 static int default_rtx_costs PARAMS ((rtx, enum rtx_code, enum rtx_code));
77 static bool avr_rtx_costs PARAMS ((rtx, int, int, int *));
78 static int avr_address_cost PARAMS ((rtx));
80 /* Allocate registers from r25 to r8 for parameters for function calls */
81 #define FIRST_CUM_REG 26
83 /* Temporary register RTX (gen_rtx (REG,QImode,TMP_REGNO)) */
86 /* Zeroed register RTX (gen_rtx (REG,QImode,ZERO_REGNO)) */
89 /* RTX for register which will be used for loading immediate values to
93 /* AVR register names {"r0", "r1", ..., "r31"} */
94 static const char *const avr_regnames[] = REGISTER_NAMES;
96 /* This holds the last insn address. */
97 static int last_insn_address = 0;
99 /* Commands count in the compiled file */
100 static int commands_in_file;
102 /* Commands in the functions prologues in the compiled file */
103 static int commands_in_prologues;
105 /* Commands in the functions epilogues in the compiled file */
106 static int commands_in_epilogues;
108 /* Prologue/Epilogue size in words */
109 static int prologue_size;
110 static int epilogue_size;
112 /* Size of all jump tables in the current function, in words. */
113 static int jump_tables_size;
115 /* Initial stack value specified by the `-minit-stack=' option */
116 const char *avr_init_stack = "__stack";
118 /* Default MCU name */
119 const char *avr_mcu_name = "avr2";
121 /* Preprocessor macros to define depending on MCU type. */
122 const char *avr_base_arch_macro;
123 const char *avr_extra_arch_macro;
125 /* More than 8K of program memory: use "call" and "jmp". */
128 /* Enhanced core: use "movw", "mul", ... */
129 int avr_enhanced_p = 0;
131 /* Assembler only. */
132 int avr_asm_only_p = 0;
138 const char *const macro;
141 static const struct base_arch_s avr_arch_types[] = {
142 { 1, 0, 0, NULL }, /* unknown device specified */
143 { 1, 0, 0, "__AVR_ARCH__=1" },
144 { 0, 0, 0, "__AVR_ARCH__=2" },
145 { 0, 0, 1, "__AVR_ARCH__=3" },
146 { 0, 1, 0, "__AVR_ARCH__=4" },
147 { 0, 1, 1, "__AVR_ARCH__=5" }
151 const char *const name;
152 int arch; /* index in avr_arch_types[] */
153 /* Must lie outside user's namespace. NULL == no macro. */
154 const char *const macro;
157 /* List of all known AVR MCU types - if updated, it has to be kept
158 in sync in several places (FIXME: is there a better way?):
160 - avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
161 - t-avr (MULTILIB_MATCHES)
162 - gas/config/tc-avr.c
165 static const struct mcu_type_s avr_mcu_types[] = {
166 /* Classic, <= 8K. */
168 { "at90s2313", 2, "__AVR_AT90S2313__" },
169 { "at90s2323", 2, "__AVR_AT90S2323__" },
170 { "at90s2333", 2, "__AVR_AT90S2333__" },
171 { "at90s2343", 2, "__AVR_AT90S2343__" },
172 { "attiny22", 2, "__AVR_ATtiny22__" },
173 { "attiny26", 2, "__AVR_ATtiny26__" },
174 { "at90s4414", 2, "__AVR_AT90S4414__" },
175 { "at90s4433", 2, "__AVR_AT90S4433__" },
176 { "at90s4434", 2, "__AVR_AT90S4434__" },
177 { "at90s8515", 2, "__AVR_AT90S8515__" },
178 { "at90c8534", 2, "__AVR_AT90C8534__" },
179 { "at90s8535", 2, "__AVR_AT90S8535__" },
180 { "at86rf401", 2, "__AVR_AT86RF401__" },
183 { "atmega103", 3, "__AVR_ATmega103__" },
184 { "atmega603", 3, "__AVR_ATmega603__" },
185 { "at43usb320", 3, "__AVR_AT43USB320__" },
186 { "at43usb355", 3, "__AVR_AT43USB355__" },
187 { "at76c711", 3, "__AVR_AT76C711__" },
188 /* Enhanced, <= 8K. */
190 { "atmega8", 4, "__AVR_ATmega8__" },
191 { "atmega8515", 4, "__AVR_ATmega8515__" },
192 { "atmega8535", 4, "__AVR_ATmega8535__" },
193 /* Enhanced, > 8K. */
195 { "atmega16", 5, "__AVR_ATmega16__" },
196 { "atmega161", 5, "__AVR_ATmega161__" },
197 { "atmega162", 5, "__AVR_ATmega162__" },
198 { "atmega163", 5, "__AVR_ATmega163__" },
199 { "atmega169", 5, "__AVR_ATmega169__" },
200 { "atmega32", 5, "__AVR_ATmega32__" },
201 { "atmega323", 5, "__AVR_ATmega323__" },
202 { "atmega64", 5, "__AVR_ATmega64__" },
203 { "atmega128", 5, "__AVR_ATmega128__" },
204 { "at94k", 5, "__AVR_AT94K__" },
205 /* Assembler only. */
207 { "at90s1200", 1, "__AVR_AT90S1200__" },
208 { "attiny11", 1, "__AVR_ATtiny11__" },
209 { "attiny12", 1, "__AVR_ATtiny12__" },
210 { "attiny15", 1, "__AVR_ATtiny15__" },
211 { "attiny28", 1, "__AVR_ATtiny28__" },
215 int avr_case_values_threshold = 30000;
217 /* Initialize the GCC target structure. */
218 #undef TARGET_ASM_ALIGNED_HI_OP
219 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
220 #undef TARGET_ASM_INTEGER
221 #define TARGET_ASM_INTEGER avr_assemble_integer
222 #undef TARGET_ASM_FILE_START
223 #define TARGET_ASM_FILE_START avr_file_start
224 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
225 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
226 #undef TARGET_ASM_FILE_END
227 #define TARGET_ASM_FILE_END avr_file_end
229 #undef TARGET_ASM_FUNCTION_PROLOGUE
230 #define TARGET_ASM_FUNCTION_PROLOGUE avr_output_function_prologue
231 #undef TARGET_ASM_FUNCTION_EPILOGUE
232 #define TARGET_ASM_FUNCTION_EPILOGUE avr_output_function_epilogue
233 #undef TARGET_ATTRIBUTE_TABLE
234 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
235 #undef TARGET_ASM_UNIQUE_SECTION
236 #define TARGET_ASM_UNIQUE_SECTION avr_unique_section
237 #undef TARGET_INSERT_ATTRIBUTES
238 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
239 #undef TARGET_SECTION_TYPE_FLAGS
240 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
241 #undef TARGET_RTX_COSTS
242 #define TARGET_RTX_COSTS avr_rtx_costs
243 #undef TARGET_ADDRESS_COST
244 #define TARGET_ADDRESS_COST avr_address_cost
245 #undef TARGET_MACHINE_DEPENDENT_REORG
246 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
248 struct gcc_target targetm = TARGET_INITIALIZER;
251 avr_override_options ()
253 const struct mcu_type_s *t;
254 const struct base_arch_s *base;
256 for (t = avr_mcu_types; t->name; t++)
257 if (strcmp (t->name, avr_mcu_name) == 0)
262 fprintf (stderr, "unknown MCU `%s' specified\nKnown MCU names:\n",
264 for (t = avr_mcu_types; t->name; t++)
265 fprintf (stderr," %s\n", t->name);
268 base = &avr_arch_types[t->arch];
269 avr_asm_only_p = base->asm_only;
270 avr_enhanced_p = base->enhanced;
271 avr_mega_p = base->mega;
272 avr_base_arch_macro = base->macro;
273 avr_extra_arch_macro = t->macro;
275 if (optimize && !TARGET_NO_TABLEJUMP)
276 avr_case_values_threshold = (!AVR_MEGA || TARGET_CALL_PROLOGUES) ? 8 : 17;
280 /* Initialize TMP_REG_RTX and ZERO_REG_RTX */
284 tmp_reg_rtx = xcalloc (1, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
285 PUT_CODE (tmp_reg_rtx, REG);
286 PUT_MODE (tmp_reg_rtx, QImode);
287 XINT (tmp_reg_rtx, 0) = TMP_REGNO;
289 zero_reg_rtx = xcalloc (1, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
290 PUT_CODE (zero_reg_rtx, REG);
291 PUT_MODE (zero_reg_rtx, QImode);
292 XINT (zero_reg_rtx, 0) = ZERO_REGNO;
294 ldi_reg_rtx = xcalloc (1, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
295 PUT_CODE (ldi_reg_rtx, REG);
296 PUT_MODE (ldi_reg_rtx, QImode);
297 XINT (ldi_reg_rtx, 0) = LDI_REG_REGNO;
300 /* return register class from register number */
302 static const int reg_class_tab[]={
303 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
304 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
305 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
306 GENERAL_REGS, /* r0 - r15 */
307 LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
308 LD_REGS, /* r16 - 23 */
309 ADDW_REGS,ADDW_REGS, /* r24,r25 */
310 POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
311 POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
312 POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
313 STACK_REG,STACK_REG /* SPL,SPH */
316 /* Return register class for register R */
319 avr_regno_reg_class (r)
323 return reg_class_tab[r];
328 /* A C expression which defines the machine-dependent operand
329 constraint letters for register classes. If C is such a
330 letter, the value should be the register class corresponding to
331 it. Otherwise, the value should be `NO_REGS'. The register
332 letter `r', corresponding to class `GENERAL_REGS', will not be
333 passed to this macro; you do not need to handle it. */
336 avr_reg_class_from_letter (c)
341 case 't' : return R0_REG;
342 case 'b' : return BASE_POINTER_REGS;
343 case 'e' : return POINTER_REGS;
344 case 'w' : return ADDW_REGS;
345 case 'd' : return LD_REGS;
346 case 'l' : return NO_LD_REGS;
347 case 'a' : return SIMPLE_LD_REGS;
348 case 'x' : return POINTER_X_REGS;
349 case 'y' : return POINTER_Y_REGS;
350 case 'z' : return POINTER_Z_REGS;
351 case 'q' : return STACK_REG;
357 /* Return nonzero if FUNC is a naked function. */
360 avr_naked_function_p (func)
365 if (TREE_CODE (func) != FUNCTION_DECL)
368 a = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
369 return a != NULL_TREE;
372 /* Return nonzero if FUNC is an interrupt function as specified
373 by the "interrupt" attribute. */
376 interrupt_function_p (func)
381 if (TREE_CODE (func) != FUNCTION_DECL)
384 a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
385 return a != NULL_TREE;
388 /* Return nonzero if FUNC is a signal function as specified
389 by the "signal" attribute. */
392 signal_function_p (func)
397 if (TREE_CODE (func) != FUNCTION_DECL)
400 a = lookup_attribute ("signal", DECL_ATTRIBUTES (func));
401 return a != NULL_TREE;
404 /* Return the number of hard registers to push/pop in the prologue/epilogue
405 of the current function, and optionally store these registers in SET. */
408 avr_regs_to_save (set)
412 int int_or_sig_p = (interrupt_function_p (current_function_decl)
413 || signal_function_p (current_function_decl));
414 int leaf_func_p = leaf_function_p ();
417 CLEAR_HARD_REG_SET (*set);
420 /* No need to save any registers if the function never returns. */
421 if (TREE_THIS_VOLATILE (current_function_decl))
424 for (reg = 0; reg < 32; reg++)
426 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
427 any global register variables. */
431 if ((int_or_sig_p && !leaf_func_p && call_used_regs[reg])
432 || (regs_ever_live[reg]
433 && (int_or_sig_p || !call_used_regs[reg])
434 && !(frame_pointer_needed
435 && (reg == REG_Y || reg == (REG_Y+1)))))
438 SET_HARD_REG_BIT (*set, reg);
445 /* Compute offset between arg_pointer and frame_pointer */
448 initial_elimination_offset (from, to)
452 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
456 int offset = frame_pointer_needed ? 2 : 0;
458 offset += avr_regs_to_save (NULL);
459 return get_frame_size () + 2 + 1 + offset;
463 /* Return 1 if the function epilogue is just a single "ret". */
466 avr_simple_epilogue ()
468 return (! frame_pointer_needed
469 && get_frame_size () == 0
470 && avr_regs_to_save (NULL) == 0
471 && ! interrupt_function_p (current_function_decl)
472 && ! signal_function_p (current_function_decl)
473 && ! avr_naked_function_p (current_function_decl)
474 && ! MAIN_NAME_P (DECL_NAME (current_function_decl))
475 && ! TREE_THIS_VOLATILE (current_function_decl));
478 /* This function checks sequence of live registers */
487 for (reg = 0; reg < 18; ++reg)
489 if (!call_used_regs[reg])
491 if (regs_ever_live[reg])
501 if (!frame_pointer_needed)
503 if (regs_ever_live[REG_Y])
511 if (regs_ever_live[REG_Y+1])
524 return (cur_seq == live_seq) ? live_seq : 0;
528 /* Output to FILE the asm instructions to adjust the frame pointer by
529 ADJ (r29:r28 -= ADJ;) which can be positive (prologue) or negative
530 (epilogue). Returns the number of instructions generated. */
533 out_adj_frame_ptr (file, adj)
541 if (TARGET_TINY_STACK)
543 if (adj < -63 || adj > 63)
544 warning ("large frame pointer change (%d) with -mtiny-stack", adj);
546 /* The high byte (r29) doesn't change - prefer "subi" (1 cycle)
547 over "sbiw" (2 cycles, same size). */
549 fprintf (file, (AS2 (subi, r28, %d) CR_TAB), adj);
552 else if (adj < -63 || adj > 63)
554 fprintf (file, (AS2 (subi, r28, lo8(%d)) CR_TAB
555 AS2 (sbci, r29, hi8(%d)) CR_TAB),
561 fprintf (file, (AS2 (adiw, r28, %d) CR_TAB), -adj);
566 fprintf (file, (AS2 (sbiw, r28, %d) CR_TAB), adj);
574 /* Output to FILE the asm instructions to copy r29:r28 to SPH:SPL,
575 handling various cases of interrupt enable flag state BEFORE and AFTER
576 (0=disabled, 1=enabled, -1=unknown/unchanged) and target_flags.
577 Returns the number of instructions generated. */
580 out_set_stack_ptr (file, before, after)
585 int do_sph, do_cli, do_save, do_sei, lock_sph, size;
587 /* The logic here is so that -mno-interrupts actually means
588 "it is safe to write SPH in one instruction, then SPL in the
589 next instruction, without disabling interrupts first".
590 The after != -1 case (interrupt/signal) is not affected. */
592 do_sph = !TARGET_TINY_STACK;
593 lock_sph = do_sph && !TARGET_NO_INTERRUPTS;
594 do_cli = (before != 0 && (after == 0 || lock_sph));
595 do_save = (do_cli && before == -1 && after == -1);
596 do_sei = ((do_cli || before != 1) && after == 1);
601 fprintf (file, AS2 (in, __tmp_reg__, __SREG__) CR_TAB);
607 fprintf (file, "cli" CR_TAB);
611 /* Do SPH first - maybe this will disable interrupts for one instruction
612 someday (a suggestion has been sent to avr@atmel.com for consideration
613 in future devices - that would make -mno-interrupts always safe). */
616 fprintf (file, AS2 (out, __SP_H__, r29) CR_TAB);
620 /* Set/restore the I flag now - interrupts will be really enabled only
621 after the next instruction. This is not clearly documented, but
622 believed to be true for all AVR devices. */
625 fprintf (file, AS2 (out, __SREG__, __tmp_reg__) CR_TAB);
630 fprintf (file, "sei" CR_TAB);
634 fprintf (file, AS2 (out, __SP_L__, r28) "\n");
640 /* Output function prologue */
643 avr_output_function_prologue (file, size)
648 int interrupt_func_p;
654 last_insn_address = 0;
655 jump_tables_size = 0;
657 fprintf (file, "/* prologue: frame size=" HOST_WIDE_INT_PRINT_DEC " */\n",
660 if (avr_naked_function_p (current_function_decl))
662 fputs ("/* prologue: naked */\n", file);
666 interrupt_func_p = interrupt_function_p (current_function_decl);
667 signal_func_p = signal_function_p (current_function_decl);
668 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
669 live_seq = sequent_regs_live ();
670 minimize = (TARGET_CALL_PROLOGUES
671 && !interrupt_func_p && !signal_func_p && live_seq);
673 if (interrupt_func_p)
675 fprintf (file,"\tsei\n");
678 if (interrupt_func_p || signal_func_p)
681 AS1 (push,__zero_reg__) CR_TAB
682 AS1 (push,__tmp_reg__) CR_TAB
683 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
684 AS1 (push,__tmp_reg__) CR_TAB
685 AS1 (clr,__zero_reg__) "\n");
691 AS1 (ldi,r28) ",lo8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
692 AS1 (ldi,r29) ",hi8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
693 AS2 (out,__SP_H__,r29) CR_TAB
694 AS2 (out,__SP_L__,r28) "\n"),
695 avr_init_stack, size, avr_init_stack, size);
699 else if (minimize && (frame_pointer_needed || live_seq > 6))
702 AS1 (ldi, r26) ",lo8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
703 AS1 (ldi, r27) ",hi8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB), size, size);
705 fprintf (file, (AS2 (ldi, r30, pm_lo8(.L_%s_body)) CR_TAB
706 AS2 (ldi, r31, pm_hi8(.L_%s_body)) CR_TAB)
707 ,current_function_name, current_function_name);
713 fprintf (file, AS1 (jmp,__prologue_saves__+%d) "\n",
714 (18 - live_seq) * 2);
719 fprintf (file, AS1 (rjmp,__prologue_saves__+%d) "\n",
720 (18 - live_seq) * 2);
723 fprintf (file, ".L_%s_body:\n", current_function_name);
729 prologue_size += avr_regs_to_save (&set);
730 for (reg = 0; reg < 32; ++reg)
732 if (TEST_HARD_REG_BIT (set, reg))
734 fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
737 if (frame_pointer_needed)
741 AS1 (push,r28) CR_TAB
742 AS1 (push,r29) CR_TAB
743 AS2 (in,r28,__SP_L__) CR_TAB
744 AS2 (in,r29,__SP_H__) "\n");
749 prologue_size += out_adj_frame_ptr (file, size);
751 if (interrupt_func_p)
753 prologue_size += out_set_stack_ptr (file, 1, 1);
755 else if (signal_func_p)
757 prologue_size += out_set_stack_ptr (file, 0, 0);
761 prologue_size += out_set_stack_ptr (file, -1, -1);
769 fprintf (file, "/* prologue end (size=%d) */\n", prologue_size);
772 /* Output function epilogue */
775 avr_output_function_epilogue (file, size)
780 int interrupt_func_p;
786 rtx last = get_last_nonnote_insn ();
788 function_size = jump_tables_size;
791 rtx first = get_first_nonnote_insn ();
792 function_size += (INSN_ADDRESSES (INSN_UID (last)) -
793 INSN_ADDRESSES (INSN_UID (first)));
794 function_size += get_attr_length (last);
797 fprintf (file, "/* epilogue: frame size=" HOST_WIDE_INT_PRINT_DEC " */\n", size);
800 if (avr_naked_function_p (current_function_decl))
802 fputs ("/* epilogue: naked */\n", file);
806 if (last && GET_CODE (last) == BARRIER)
808 fputs ("/* epilogue: noreturn */\n", file);
812 interrupt_func_p = interrupt_function_p (current_function_decl);
813 signal_func_p = signal_function_p (current_function_decl);
814 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
815 live_seq = sequent_regs_live ();
816 minimize = (TARGET_CALL_PROLOGUES
817 && !interrupt_func_p && !signal_func_p && live_seq);
821 /* Return value from main() is already in the correct registers
822 (r25:r24) as the exit() argument. */
825 fputs ("\t" AS1 (jmp,exit) "\n", file);
830 fputs ("\t" AS1 (rjmp,exit) "\n", file);
834 else if (minimize && (frame_pointer_needed || live_seq > 4))
836 fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
838 if (frame_pointer_needed)
840 epilogue_size += out_adj_frame_ptr (file, -size);
844 fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
845 AS2 (in , r29, __SP_H__) CR_TAB));
851 fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
852 (18 - live_seq) * 2);
857 fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
858 (18 - live_seq) * 2);
866 if (frame_pointer_needed)
871 epilogue_size += out_adj_frame_ptr (file, -size);
873 if (interrupt_func_p || signal_func_p)
875 epilogue_size += out_set_stack_ptr (file, -1, 0);
879 epilogue_size += out_set_stack_ptr (file, -1, -1);
888 epilogue_size += avr_regs_to_save (&set);
889 for (reg = 31; reg >= 0; --reg)
891 if (TEST_HARD_REG_BIT (set, reg))
893 fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
897 if (interrupt_func_p || signal_func_p)
900 AS1 (pop,__tmp_reg__) CR_TAB
901 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
902 AS1 (pop,__tmp_reg__) CR_TAB
903 AS1 (pop,__zero_reg__) "\n");
905 fprintf (file, "\treti\n");
908 fprintf (file, "\tret\n");
913 fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
914 fprintf (file, "/* function %s size %d (%d) */\n", current_function_name,
915 prologue_size + function_size + epilogue_size, function_size);
916 commands_in_file += prologue_size + function_size + epilogue_size;
917 commands_in_prologues += prologue_size;
918 commands_in_epilogues += epilogue_size;
922 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
923 machine for a memory operand of mode MODE. */
926 legitimate_address_p (mode, x, strict)
927 enum machine_mode mode;
931 enum reg_class r = NO_REGS;
933 if (TARGET_ALL_DEBUG)
935 fprintf (stderr, "mode: (%s) %s %s %s %s:",
937 strict ? "(strict)": "",
938 reload_completed ? "(reload_completed)": "",
939 reload_in_progress ? "(reload_in_progress)": "",
940 reg_renumber ? "(reg_renumber)" : "");
941 if (GET_CODE (x) == PLUS
942 && REG_P (XEXP (x, 0))
943 && GET_CODE (XEXP (x, 1)) == CONST_INT
944 && INTVAL (XEXP (x, 1)) >= 0
945 && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
948 fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
949 true_regnum (XEXP (x, 0)));
952 if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
953 : REG_OK_FOR_BASE_NOSTRICT_P (x)))
955 else if (CONSTANT_ADDRESS_P (x))
957 else if (GET_CODE (x) == PLUS
958 && REG_P (XEXP (x, 0))
959 && GET_CODE (XEXP (x, 1)) == CONST_INT
960 && INTVAL (XEXP (x, 1)) >= 0)
962 int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
966 || REGNO (XEXP (x,0)) == REG_Y
967 || REGNO (XEXP (x,0)) == REG_Z)
968 r = BASE_POINTER_REGS;
969 if (XEXP (x,0) == frame_pointer_rtx
970 || XEXP (x,0) == arg_pointer_rtx)
971 r = BASE_POINTER_REGS;
973 else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
976 else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
977 && REG_P (XEXP (x, 0))
978 && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
979 : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
983 if (TARGET_ALL_DEBUG)
985 fprintf (stderr, " ret = %c\n", r);
987 return r == NO_REGS ? 0 : (int)r;
990 /* Attempts to replace X with a valid
991 memory address for an operand of mode MODE */
994 legitimize_address (x, oldx, mode)
997 enum machine_mode mode;
1000 if (TARGET_ALL_DEBUG)
1002 fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
1006 if (GET_CODE (oldx) == PLUS
1007 && REG_P (XEXP (oldx,0)))
1009 if (REG_P (XEXP (oldx,1)))
1010 x = force_reg (GET_MODE (oldx), oldx);
1011 else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
1013 int offs = INTVAL (XEXP (oldx,1));
1014 if (frame_pointer_rtx != XEXP (oldx,0))
1015 if (offs > MAX_LD_OFFSET (mode))
1017 if (TARGET_ALL_DEBUG)
1018 fprintf (stderr, "force_reg (big offset)\n");
1019 x = force_reg (GET_MODE (oldx), oldx);
1027 /* Return a pointer register name as a string */
1030 ptrreg_to_str (regno)
1035 case REG_X: return "X";
1036 case REG_Y: return "Y";
1037 case REG_Z: return "Z";
1044 /* Return the condition name as a string.
1045 Used in conditional jump constructing */
1058 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1063 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1076 /* Output ADDR to FILE as address */
1079 print_operand_address (file, addr)
1083 switch (GET_CODE (addr))
1086 fprintf (file, ptrreg_to_str (REGNO (addr)));
1090 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1094 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1098 if (CONSTANT_ADDRESS_P (addr)
1099 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (addr))
1100 || GET_CODE (addr) == LABEL_REF))
1102 fprintf (file, "pm(");
1103 output_addr_const (file,addr);
1104 fprintf (file ,")");
1107 output_addr_const (file, addr);
1112 /* Output X as assembler operand to file FILE */
1115 print_operand (file, x, code)
1122 if (code >= 'A' && code <= 'D')
1132 if (x == zero_reg_rtx)
1133 fprintf (file, "__zero_reg__");
1135 fprintf (file, reg_names[true_regnum (x) + abcd]);
1137 else if (GET_CODE (x) == CONST_INT)
1138 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd);
1139 else if (GET_CODE (x) == MEM)
1141 rtx addr = XEXP (x,0);
1143 if (CONSTANT_P (addr) && abcd)
1146 output_address (addr);
1147 fprintf (file, ")+%d", abcd);
1149 else if (code == 'o')
1151 if (GET_CODE (addr) != PLUS)
1152 fatal_insn ("bad address, not (reg+disp):", addr);
1154 print_operand (file, XEXP (addr, 1), 0);
1156 else if (GET_CODE (addr) == PLUS)
1158 print_operand_address (file, XEXP (addr,0));
1159 if (REGNO (XEXP (addr, 0)) == REG_X)
1160 fatal_insn ("internal compiler error. Bad address:"
1163 print_operand (file, XEXP (addr,1), code);
1166 print_operand_address (file, addr);
1168 else if (GET_CODE (x) == CONST_DOUBLE)
1172 if (GET_MODE (x) != SFmode)
1173 fatal_insn ("internal compiler error. Unknown mode:", x);
1174 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1175 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1176 fprintf (file, "0x%lx", val);
1178 else if (code == 'j')
1179 fputs (cond_string (GET_CODE (x)), file);
1180 else if (code == 'k')
1181 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
1183 print_operand_address (file, x);
1186 /* Recognize operand OP of mode MODE used in call instructions */
1189 call_insn_operand (op, mode)
1191 enum machine_mode mode ATTRIBUTE_UNUSED;
1193 if (GET_CODE (op) == MEM)
1195 rtx inside = XEXP (op, 0);
1196 if (register_operand (inside, Pmode))
1198 if (CONSTANT_ADDRESS_P (inside))
1204 /* Update the condition code in the INSN. */
1207 notice_update_cc (body, insn)
1208 rtx body ATTRIBUTE_UNUSED;
1213 switch (get_attr_cc (insn))
1216 /* Insn does not affect CC at all. */
1224 set = single_set (insn);
1228 cc_status.flags |= CC_NO_OVERFLOW;
1229 cc_status.value1 = SET_DEST (set);
1234 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1235 The V flag may or may not be known but that's ok because
1236 alter_cond will change tests to use EQ/NE. */
1237 set = single_set (insn);
1241 cc_status.value1 = SET_DEST (set);
1242 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1247 set = single_set (insn);
1250 cc_status.value1 = SET_SRC (set);
1254 /* Insn doesn't leave CC in a usable state. */
1257 /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1258 set = single_set (insn);
1261 rtx src = SET_SRC (set);
1263 if (GET_CODE (src) == ASHIFTRT
1264 && GET_MODE (src) == QImode)
1266 rtx x = XEXP (src, 1);
1268 if (GET_CODE (x) == CONST_INT
1271 cc_status.value1 = SET_DEST (set);
1272 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1280 /* Return maximum number of consecutive registers of
1281 class CLASS needed to hold a value of mode MODE. */
1284 class_max_nregs (class, mode)
1285 enum reg_class class ATTRIBUTE_UNUSED;
1286 enum machine_mode mode;
1288 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1291 /* Choose mode for jump insn:
1292 1 - relative jump in range -63 <= x <= 62 ;
1293 2 - relative jump in range -2046 <= x <= 2045 ;
1294 3 - absolute jump (only for ATmega[16]03). */
1297 avr_jump_mode (x, insn)
1298 rtx x; /* jump operand */
1299 rtx insn; /* jump insn */
1301 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1302 ? XEXP (x, 0) : x));
1303 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1304 int jump_distance = cur_addr - dest_addr;
1306 if (-63 <= jump_distance && jump_distance <= 62)
1308 else if (-2046 <= jump_distance && jump_distance <= 2045)
1316 /* return an AVR condition jump commands.
1317 X is a comparison RTX.
1318 LEN is a number returned by avr_jump_mode function.
1319 if REVERSE nonzero then condition code in X must be reversed. */
1322 ret_cond_branch (x, len, reverse)
1327 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1332 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1333 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1335 len == 2 ? (AS1 (breq,.+4) CR_TAB
1336 AS1 (brmi,.+2) CR_TAB
1338 (AS1 (breq,.+6) CR_TAB
1339 AS1 (brmi,.+4) CR_TAB
1343 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1345 len == 2 ? (AS1 (breq,.+4) CR_TAB
1346 AS1 (brlt,.+2) CR_TAB
1348 (AS1 (breq,.+6) CR_TAB
1349 AS1 (brlt,.+4) CR_TAB
1352 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1354 len == 2 ? (AS1 (breq,.+4) CR_TAB
1355 AS1 (brlo,.+2) CR_TAB
1357 (AS1 (breq,.+6) CR_TAB
1358 AS1 (brlo,.+4) CR_TAB
1361 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1362 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1364 len == 2 ? (AS1 (breq,.+2) CR_TAB
1365 AS1 (brpl,.+2) CR_TAB
1367 (AS1 (breq,.+2) CR_TAB
1368 AS1 (brpl,.+4) CR_TAB
1371 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1373 len == 2 ? (AS1 (breq,.+2) CR_TAB
1374 AS1 (brge,.+2) CR_TAB
1376 (AS1 (breq,.+2) CR_TAB
1377 AS1 (brge,.+4) CR_TAB
1380 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1382 len == 2 ? (AS1 (breq,.+2) CR_TAB
1383 AS1 (brsh,.+2) CR_TAB
1385 (AS1 (breq,.+2) CR_TAB
1386 AS1 (brsh,.+4) CR_TAB
1394 return AS1 (br%k1,%0);
1396 return (AS1 (br%j1,.+2) CR_TAB
1399 return (AS1 (br%j1,.+4) CR_TAB
1408 return AS1 (br%j1,%0);
1410 return (AS1 (br%k1,.+2) CR_TAB
1413 return (AS1 (br%k1,.+4) CR_TAB
1421 /* Predicate function for immediate operand which fits to byte (8bit) */
1424 byte_immediate_operand (op, mode)
1426 enum machine_mode mode ATTRIBUTE_UNUSED;
1428 return (GET_CODE (op) == CONST_INT
1429 && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1432 /* Output all insn addresses and their sizes into the assembly language
1433 output file. This is helpful for debugging whether the length attributes
1434 in the md file are correct.
1435 Output insn cost for next insn. */
1438 final_prescan_insn (insn, operand, num_operands)
1439 rtx insn, *operand ATTRIBUTE_UNUSED;
1440 int num_operands ATTRIBUTE_UNUSED;
1442 int uid = INSN_UID (insn);
1444 if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1446 fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1447 INSN_ADDRESSES (uid),
1448 INSN_ADDRESSES (uid) - last_insn_address,
1449 rtx_cost (PATTERN (insn), INSN));
1451 last_insn_address = INSN_ADDRESSES (uid);
1454 /* Return 0 if undefined, 1 if always true or always false. */
1457 avr_simplify_comparison_p (mode, operator, x)
1458 enum machine_mode mode;
1462 unsigned int max = (mode == QImode ? 0xff :
1463 mode == HImode ? 0xffff :
1464 mode == SImode ? 0xffffffff : 0);
1465 if (max && operator && GET_CODE (x) == CONST_INT)
1467 if (unsigned_condition (operator) != operator)
1470 if (max != (INTVAL (x) & max)
1471 && INTVAL (x) != 0xff)
1478 /* Returns nonzero if REGNO is the number of a hard
1479 register in which function arguments are sometimes passed. */
1482 function_arg_regno_p(r)
1485 return (r >= 8 && r <= 25);
1488 /* Initializing the variable cum for the state at the beginning
1489 of the argument list. */
1492 init_cumulative_args (cum, fntype, libname, fndecl)
1493 CUMULATIVE_ARGS *cum;
1496 tree fndecl ATTRIBUTE_UNUSED;
1499 cum->regno = FIRST_CUM_REG;
1500 if (!libname && fntype)
1502 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1503 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1504 != void_type_node));
1510 /* Returns the number of registers to allocate for a function argument. */
1513 avr_num_arg_regs (mode, type)
1514 enum machine_mode mode;
1519 if (mode == BLKmode)
1520 size = int_size_in_bytes (type);
1522 size = GET_MODE_SIZE (mode);
1524 /* Align all function arguments to start in even-numbered registers.
1525 Odd-sized arguments leave holes above them. */
1527 return (size + 1) & ~1;
1530 /* Controls whether a function argument is passed
1531 in a register, and which register. */
1534 function_arg (cum, mode, type, named)
1535 CUMULATIVE_ARGS *cum;
1536 enum machine_mode mode;
1538 int named ATTRIBUTE_UNUSED;
1540 int bytes = avr_num_arg_regs (mode, type);
1542 if (cum->nregs && bytes <= cum->nregs)
1543 return gen_rtx (REG, mode, cum->regno - bytes);
1548 /* Update the summarizer variable CUM to advance past an argument
1549 in the argument list. */
1552 function_arg_advance (cum, mode, type, named)
1553 CUMULATIVE_ARGS *cum; /* current arg information */
1554 enum machine_mode mode; /* current arg mode */
1555 tree type; /* type of the argument or 0 if lib support */
1556 int named ATTRIBUTE_UNUSED; /* whether or not the argument was named */
1558 int bytes = avr_num_arg_regs (mode, type);
1560 cum->nregs -= bytes;
1561 cum->regno -= bytes;
1563 if (cum->nregs <= 0)
1566 cum->regno = FIRST_CUM_REG;
1570 /***********************************************************************
1571 Functions for outputting various mov's for a various modes
1572 ************************************************************************/
1574 output_movqi (insn, operands, l)
1580 rtx dest = operands[0];
1581 rtx src = operands[1];
1589 if (register_operand (dest, QImode))
1591 if (register_operand (src, QImode)) /* mov r,r */
1593 if (test_hard_reg_class (STACK_REG, dest))
1594 return AS2 (out,%0,%1);
1595 else if (test_hard_reg_class (STACK_REG, src))
1596 return AS2 (in,%0,%1);
1598 return AS2 (mov,%0,%1);
1600 else if (CONSTANT_P (src))
1602 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1603 return AS2 (ldi,%0,lo8(%1));
1605 if (GET_CODE (src) == CONST_INT)
1607 if (src == const0_rtx) /* mov r,L */
1608 return AS1 (clr,%0);
1609 else if (src == const1_rtx)
1612 return (AS1 (clr,%0) CR_TAB
1615 else if (src == constm1_rtx)
1617 /* Immediate constants -1 to any register */
1619 return (AS1 (clr,%0) CR_TAB
1624 int bit_nr = exact_log2 (INTVAL (src));
1630 output_asm_insn ((AS1 (clr,%0) CR_TAB
1633 avr_output_bld (operands, bit_nr);
1640 /* Last resort, larger than loading from memory. */
1642 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1643 AS2 (ldi,r31,lo8(%1)) CR_TAB
1644 AS2 (mov,%0,r31) CR_TAB
1645 AS2 (mov,r31,__tmp_reg__));
1647 else if (GET_CODE (src) == MEM)
1648 return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1650 else if (GET_CODE (dest) == MEM)
1652 const char *template;
1654 if (src == const0_rtx)
1655 operands[1] = zero_reg_rtx;
1657 template = out_movqi_mr_r (insn, operands, real_l);
1660 output_asm_insn (template, operands);
1669 output_movhi (insn, operands, l)
1675 rtx dest = operands[0];
1676 rtx src = operands[1];
1682 if (register_operand (dest, HImode))
1684 if (register_operand (src, HImode)) /* mov r,r */
1686 if (test_hard_reg_class (STACK_REG, dest))
1688 if (TARGET_TINY_STACK)
1691 return AS2 (out,__SP_L__,%A1);
1693 else if (TARGET_NO_INTERRUPTS)
1696 return (AS2 (out,__SP_H__,%B1) CR_TAB
1697 AS2 (out,__SP_L__,%A1));
1701 return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB
1703 AS2 (out,__SP_H__,%B1) CR_TAB
1704 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1705 AS2 (out,__SP_L__,%A1));
1707 else if (test_hard_reg_class (STACK_REG, src))
1710 return (AS2 (in,%A0,__SP_L__) CR_TAB
1711 AS2 (in,%B0,__SP_H__));
1717 return (AS2 (movw,%0,%1));
1720 if (true_regnum (dest) > true_regnum (src))
1723 return (AS2 (mov,%B0,%B1) CR_TAB
1729 return (AS2 (mov,%A0,%A1) CR_TAB
1733 else if (CONSTANT_P (src))
1735 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1738 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1739 AS2 (ldi,%B0,hi8(%1)));
1742 if (GET_CODE (src) == CONST_INT)
1744 if (src == const0_rtx) /* mov r,L */
1747 return (AS1 (clr,%A0) CR_TAB
1750 else if (src == const1_rtx)
1753 return (AS1 (clr,%A0) CR_TAB
1754 AS1 (clr,%B0) CR_TAB
1757 else if (src == constm1_rtx)
1759 /* Immediate constants -1 to any register */
1761 return (AS1 (clr,%0) CR_TAB
1762 AS1 (dec,%A0) CR_TAB
1767 int bit_nr = exact_log2 (INTVAL (src));
1773 output_asm_insn ((AS1 (clr,%A0) CR_TAB
1774 AS1 (clr,%B0) CR_TAB
1777 avr_output_bld (operands, bit_nr);
1783 if ((INTVAL (src) & 0xff) == 0)
1786 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1787 AS1 (clr,%A0) CR_TAB
1788 AS2 (ldi,r31,hi8(%1)) CR_TAB
1789 AS2 (mov,%B0,r31) CR_TAB
1790 AS2 (mov,r31,__tmp_reg__));
1792 else if ((INTVAL (src) & 0xff00) == 0)
1795 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1796 AS2 (ldi,r31,lo8(%1)) CR_TAB
1797 AS2 (mov,%A0,r31) CR_TAB
1798 AS1 (clr,%B0) CR_TAB
1799 AS2 (mov,r31,__tmp_reg__));
1803 /* Last resort, equal to loading from memory. */
1805 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1806 AS2 (ldi,r31,lo8(%1)) CR_TAB
1807 AS2 (mov,%A0,r31) CR_TAB
1808 AS2 (ldi,r31,hi8(%1)) CR_TAB
1809 AS2 (mov,%B0,r31) CR_TAB
1810 AS2 (mov,r31,__tmp_reg__));
1812 else if (GET_CODE (src) == MEM)
1813 return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1815 else if (GET_CODE (dest) == MEM)
1817 const char *template;
1819 if (src == const0_rtx)
1820 operands[1] = zero_reg_rtx;
1822 template = out_movhi_mr_r (insn, operands, real_l);
1825 output_asm_insn (template, operands);
1830 fatal_insn ("invalid insn:", insn);
1835 out_movqi_r_mr (insn, op, l)
1838 int *l; /* instruction length */
1842 rtx x = XEXP (src, 0);
1848 if (CONSTANT_ADDRESS_P (x))
1850 if (avr_io_address_p (x, 1))
1853 return AS2 (in,%0,%1-0x20);
1856 return AS2 (lds,%0,%1);
1858 /* memory access by reg+disp */
1859 else if (GET_CODE (x) == PLUS
1860 && REG_P (XEXP (x,0))
1861 && GET_CODE (XEXP (x,1)) == CONST_INT)
1863 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1865 int disp = INTVAL (XEXP (x,1));
1866 if (REGNO (XEXP (x,0)) != REG_Y)
1867 fatal_insn ("incorrect insn:",insn);
1869 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1870 return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
1871 AS2 (ldd,%0,Y+63) CR_TAB
1872 AS2 (sbiw,r28,%o1-63));
1874 return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1875 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1876 AS2 (ld,%0,Y) CR_TAB
1877 AS2 (subi,r28,lo8(%o1)) CR_TAB
1878 AS2 (sbci,r29,hi8(%o1)));
1880 else if (REGNO (XEXP (x,0)) == REG_X)
1882 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1883 it but I have this situation with extremal optimizing options. */
1884 if (reg_overlap_mentioned_p (dest, XEXP (x,0))
1885 || reg_unused_after (insn, XEXP (x,0)))
1886 return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
1889 return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
1890 AS2 (ld,%0,X) CR_TAB
1891 AS2 (sbiw,r26,%o1));
1894 return AS2 (ldd,%0,%1);
1897 return AS2 (ld,%0,%1);
1901 out_movhi_r_mr (insn, op, l)
1904 int *l; /* instruction length */
1908 rtx base = XEXP (src, 0);
1909 int reg_dest = true_regnum (dest);
1910 int reg_base = true_regnum (base);
1918 if (reg_dest == reg_base) /* R = (R) */
1921 return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1922 AS2 (ld,%B0,%1) CR_TAB
1923 AS2 (mov,%A0,__tmp_reg__));
1925 else if (reg_base == REG_X) /* (R26) */
1927 if (reg_unused_after (insn, base))
1930 return (AS2 (ld,%A0,X+) CR_TAB
1934 return (AS2 (ld,%A0,X+) CR_TAB
1935 AS2 (ld,%B0,X) CR_TAB
1941 return (AS2 (ld,%A0,%1) CR_TAB
1942 AS2 (ldd,%B0,%1+1));
1945 else if (GET_CODE (base) == PLUS) /* (R + i) */
1947 int disp = INTVAL (XEXP (base, 1));
1948 int reg_base = true_regnum (XEXP (base, 0));
1950 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
1952 if (REGNO (XEXP (base, 0)) != REG_Y)
1953 fatal_insn ("incorrect insn:",insn);
1955 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1956 return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
1957 AS2 (ldd,%A0,Y+62) CR_TAB
1958 AS2 (ldd,%B0,Y+63) CR_TAB
1959 AS2 (sbiw,r28,%o1-62));
1961 return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1962 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1963 AS2 (ld,%A0,Y) CR_TAB
1964 AS2 (ldd,%B0,Y+1) CR_TAB
1965 AS2 (subi,r28,lo8(%o1)) CR_TAB
1966 AS2 (sbci,r29,hi8(%o1)));
1968 if (reg_base == REG_X)
1970 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1971 it but I have this situation with extremal
1972 optimization options. */
1975 if (reg_base == reg_dest)
1976 return (AS2 (adiw,r26,%o1) CR_TAB
1977 AS2 (ld,__tmp_reg__,X+) CR_TAB
1978 AS2 (ld,%B0,X) CR_TAB
1979 AS2 (mov,%A0,__tmp_reg__));
1981 return (AS2 (adiw,r26,%o1) CR_TAB
1982 AS2 (ld,%A0,X+) CR_TAB
1983 AS2 (ld,%B0,X) CR_TAB
1984 AS2 (sbiw,r26,%o1+1));
1987 if (reg_base == reg_dest)
1990 return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
1991 AS2 (ldd,%B0,%B1) CR_TAB
1992 AS2 (mov,%A0,__tmp_reg__));
1996 return (AS2 (ldd,%A0,%A1) CR_TAB
1999 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2001 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
2002 fatal_insn ("incorrect insn:", insn);
2005 return (AS2 (ld,%B0,%1) CR_TAB
2008 else if (GET_CODE (base) == POST_INC) /* (R++) */
2010 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
2011 fatal_insn ("incorrect insn:", insn);
2014 return (AS2 (ld,%A0,%1) CR_TAB
2017 else if (CONSTANT_ADDRESS_P (base))
2019 if (avr_io_address_p (base, 2))
2022 return (AS2 (in,%A0,%A1-0x20) CR_TAB
2023 AS2 (in,%B0,%B1-0x20));
2026 return (AS2 (lds,%A0,%A1) CR_TAB
2030 fatal_insn ("unknown move insn:",insn);
2035 out_movsi_r_mr (insn, op, l)
2038 int *l; /* instruction length */
2042 rtx base = XEXP (src, 0);
2043 int reg_dest = true_regnum (dest);
2044 int reg_base = true_regnum (base);
2052 if (reg_base == REG_X) /* (R26) */
2054 if (reg_dest == REG_X)
2055 /* "ld r26,-X" is undefined */
2056 return *l=7, (AS2 (adiw,r26,3) CR_TAB
2057 AS2 (ld,r29,X) CR_TAB
2058 AS2 (ld,r28,-X) CR_TAB
2059 AS2 (ld,__tmp_reg__,-X) CR_TAB
2060 AS2 (sbiw,r26,1) CR_TAB
2061 AS2 (ld,r26,X) CR_TAB
2062 AS2 (mov,r27,__tmp_reg__));
2063 else if (reg_dest == REG_X - 2)
2064 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2065 AS2 (ld,%B0,X+) CR_TAB
2066 AS2 (ld,__tmp_reg__,X+) CR_TAB
2067 AS2 (ld,%D0,X) CR_TAB
2068 AS2 (mov,%C0,__tmp_reg__));
2069 else if (reg_unused_after (insn, base))
2070 return *l=4, (AS2 (ld,%A0,X+) CR_TAB
2071 AS2 (ld,%B0,X+) CR_TAB
2072 AS2 (ld,%C0,X+) CR_TAB
2075 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2076 AS2 (ld,%B0,X+) CR_TAB
2077 AS2 (ld,%C0,X+) CR_TAB
2078 AS2 (ld,%D0,X) CR_TAB
2083 if (reg_dest == reg_base)
2084 return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
2085 AS2 (ldd,%C0,%1+2) CR_TAB
2086 AS2 (ldd,__tmp_reg__,%1+1) CR_TAB
2087 AS2 (ld,%A0,%1) CR_TAB
2088 AS2 (mov,%B0,__tmp_reg__));
2089 else if (reg_base == reg_dest + 2)
2090 return *l=5, (AS2 (ld ,%A0,%1) CR_TAB
2091 AS2 (ldd,%B0,%1+1) CR_TAB
2092 AS2 (ldd,__tmp_reg__,%1+2) CR_TAB
2093 AS2 (ldd,%D0,%1+3) CR_TAB
2094 AS2 (mov,%C0,__tmp_reg__));
2096 return *l=4, (AS2 (ld ,%A0,%1) CR_TAB
2097 AS2 (ldd,%B0,%1+1) CR_TAB
2098 AS2 (ldd,%C0,%1+2) CR_TAB
2099 AS2 (ldd,%D0,%1+3));
2102 else if (GET_CODE (base) == PLUS) /* (R + i) */
2104 int disp = INTVAL (XEXP (base, 1));
2106 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2108 if (REGNO (XEXP (base, 0)) != REG_Y)
2109 fatal_insn ("incorrect insn:",insn);
2111 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2112 return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2113 AS2 (ldd,%A0,Y+60) CR_TAB
2114 AS2 (ldd,%B0,Y+61) CR_TAB
2115 AS2 (ldd,%C0,Y+62) CR_TAB
2116 AS2 (ldd,%D0,Y+63) CR_TAB
2117 AS2 (sbiw,r28,%o1-60));
2119 return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2120 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2121 AS2 (ld,%A0,Y) CR_TAB
2122 AS2 (ldd,%B0,Y+1) CR_TAB
2123 AS2 (ldd,%C0,Y+2) CR_TAB
2124 AS2 (ldd,%D0,Y+3) CR_TAB
2125 AS2 (subi,r28,lo8(%o1)) CR_TAB
2126 AS2 (sbci,r29,hi8(%o1)));
2129 reg_base = true_regnum (XEXP (base, 0));
2130 if (reg_base == REG_X)
2133 if (reg_dest == REG_X)
2136 /* "ld r26,-X" is undefined */
2137 return (AS2 (adiw,r26,%o1+3) CR_TAB
2138 AS2 (ld,r29,X) CR_TAB
2139 AS2 (ld,r28,-X) CR_TAB
2140 AS2 (ld,__tmp_reg__,-X) CR_TAB
2141 AS2 (sbiw,r26,1) CR_TAB
2142 AS2 (ld,r26,X) CR_TAB
2143 AS2 (mov,r27,__tmp_reg__));
2146 if (reg_dest == REG_X - 2)
2147 return (AS2 (adiw,r26,%o1) CR_TAB
2148 AS2 (ld,r24,X+) CR_TAB
2149 AS2 (ld,r25,X+) CR_TAB
2150 AS2 (ld,__tmp_reg__,X+) CR_TAB
2151 AS2 (ld,r27,X) CR_TAB
2152 AS2 (mov,r26,__tmp_reg__));
2154 return (AS2 (adiw,r26,%o1) CR_TAB
2155 AS2 (ld,%A0,X+) CR_TAB
2156 AS2 (ld,%B0,X+) CR_TAB
2157 AS2 (ld,%C0,X+) CR_TAB
2158 AS2 (ld,%D0,X) CR_TAB
2159 AS2 (sbiw,r26,%o1+3));
2161 if (reg_dest == reg_base)
2162 return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2163 AS2 (ldd,%C0,%C1) CR_TAB
2164 AS2 (ldd,__tmp_reg__,%B1) CR_TAB
2165 AS2 (ldd,%A0,%A1) CR_TAB
2166 AS2 (mov,%B0,__tmp_reg__));
2167 else if (reg_dest == reg_base - 2)
2168 return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2169 AS2 (ldd,%B0,%B1) CR_TAB
2170 AS2 (ldd,__tmp_reg__,%C1) CR_TAB
2171 AS2 (ldd,%D0,%D1) CR_TAB
2172 AS2 (mov,%C0,__tmp_reg__));
2173 return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2174 AS2 (ldd,%B0,%B1) CR_TAB
2175 AS2 (ldd,%C0,%C1) CR_TAB
2178 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2179 return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2180 AS2 (ld,%C0,%1) CR_TAB
2181 AS2 (ld,%B0,%1) CR_TAB
2183 else if (GET_CODE (base) == POST_INC) /* (R++) */
2184 return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2185 AS2 (ld,%B0,%1) CR_TAB
2186 AS2 (ld,%C0,%1) CR_TAB
2188 else if (CONSTANT_ADDRESS_P (base))
2189 return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2190 AS2 (lds,%B0,%B1) CR_TAB
2191 AS2 (lds,%C0,%C1) CR_TAB
2194 fatal_insn ("unknown move insn:",insn);
2199 out_movsi_mr_r (insn, op, l)
2206 rtx base = XEXP (dest, 0);
2207 int reg_base = true_regnum (base);
2208 int reg_src = true_regnum (src);
2214 if (CONSTANT_ADDRESS_P (base))
2215 return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2216 AS2 (sts,%B0,%B1) CR_TAB
2217 AS2 (sts,%C0,%C1) CR_TAB
2219 if (reg_base > 0) /* (r) */
2221 if (reg_base == REG_X) /* (R26) */
2223 if (reg_src == REG_X)
2225 /* "st X+,r26" is undefined */
2226 if (reg_unused_after (insn, base))
2227 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2228 AS2 (st,X,r26) CR_TAB
2229 AS2 (adiw,r26,1) CR_TAB
2230 AS2 (st,X+,__tmp_reg__) CR_TAB
2231 AS2 (st,X+,r28) CR_TAB
2234 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2235 AS2 (st,X,r26) CR_TAB
2236 AS2 (adiw,r26,1) CR_TAB
2237 AS2 (st,X+,__tmp_reg__) CR_TAB
2238 AS2 (st,X+,r28) CR_TAB
2239 AS2 (st,X,r29) CR_TAB
2242 else if (reg_base == reg_src + 2)
2244 if (reg_unused_after (insn, base))
2245 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2246 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2247 AS2 (st,%0+,%A1) CR_TAB
2248 AS2 (st,%0+,%B1) CR_TAB
2249 AS2 (st,%0+,__zero_reg__) CR_TAB
2250 AS2 (st,%0,__tmp_reg__) CR_TAB
2251 AS1 (clr,__zero_reg__));
2253 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2254 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2255 AS2 (st,%0+,%A1) CR_TAB
2256 AS2 (st,%0+,%B1) CR_TAB
2257 AS2 (st,%0+,__zero_reg__) CR_TAB
2258 AS2 (st,%0,__tmp_reg__) CR_TAB
2259 AS1 (clr,__zero_reg__) CR_TAB
2262 return *l=5, (AS2 (st,%0+,%A1) CR_TAB
2263 AS2 (st,%0+,%B1) CR_TAB
2264 AS2 (st,%0+,%C1) CR_TAB
2265 AS2 (st,%0,%D1) CR_TAB
2269 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2270 AS2 (std,%0+1,%B1) CR_TAB
2271 AS2 (std,%0+2,%C1) CR_TAB
2272 AS2 (std,%0+3,%D1));
2274 else if (GET_CODE (base) == PLUS) /* (R + i) */
2276 int disp = INTVAL (XEXP (base, 1));
2277 reg_base = REGNO (XEXP (base, 0));
2278 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2280 if (reg_base != REG_Y)
2281 fatal_insn ("incorrect insn:",insn);
2283 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2284 return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2285 AS2 (std,Y+60,%A1) CR_TAB
2286 AS2 (std,Y+61,%B1) CR_TAB
2287 AS2 (std,Y+62,%C1) CR_TAB
2288 AS2 (std,Y+63,%D1) CR_TAB
2289 AS2 (sbiw,r28,%o0-60));
2291 return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2292 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2293 AS2 (st,Y,%A1) CR_TAB
2294 AS2 (std,Y+1,%B1) CR_TAB
2295 AS2 (std,Y+2,%C1) CR_TAB
2296 AS2 (std,Y+3,%D1) CR_TAB
2297 AS2 (subi,r28,lo8(%o0)) CR_TAB
2298 AS2 (sbci,r29,hi8(%o0)));
2300 if (reg_base == REG_X)
2303 if (reg_src == REG_X)
2306 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2307 AS2 (mov,__zero_reg__,r27) CR_TAB
2308 AS2 (adiw,r26,%o0) CR_TAB
2309 AS2 (st,X+,__tmp_reg__) CR_TAB
2310 AS2 (st,X+,__zero_reg__) CR_TAB
2311 AS2 (st,X+,r28) CR_TAB
2312 AS2 (st,X,r29) CR_TAB
2313 AS1 (clr,__zero_reg__) CR_TAB
2314 AS2 (sbiw,r26,%o0+3));
2316 else if (reg_src == REG_X - 2)
2319 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2320 AS2 (mov,__zero_reg__,r27) CR_TAB
2321 AS2 (adiw,r26,%o0) CR_TAB
2322 AS2 (st,X+,r24) CR_TAB
2323 AS2 (st,X+,r25) CR_TAB
2324 AS2 (st,X+,__tmp_reg__) CR_TAB
2325 AS2 (st,X,__zero_reg__) CR_TAB
2326 AS1 (clr,__zero_reg__) CR_TAB
2327 AS2 (sbiw,r26,%o0+3));
2330 return (AS2 (adiw,r26,%o0) CR_TAB
2331 AS2 (st,X+,%A1) CR_TAB
2332 AS2 (st,X+,%B1) CR_TAB
2333 AS2 (st,X+,%C1) CR_TAB
2334 AS2 (st,X,%D1) CR_TAB
2335 AS2 (sbiw,r26,%o0+3));
2337 return *l=4, (AS2 (std,%A0,%A1) CR_TAB
2338 AS2 (std,%B0,%B1) CR_TAB
2339 AS2 (std,%C0,%C1) CR_TAB
2342 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2343 return *l=4, (AS2 (st,%0,%D1) CR_TAB
2344 AS2 (st,%0,%C1) CR_TAB
2345 AS2 (st,%0,%B1) CR_TAB
2347 else if (GET_CODE (base) == POST_INC) /* (R++) */
2348 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2349 AS2 (st,%0,%B1) CR_TAB
2350 AS2 (st,%0,%C1) CR_TAB
2352 fatal_insn ("unknown move insn:",insn);
2357 output_movsisf(insn, operands, l)
2363 rtx dest = operands[0];
2364 rtx src = operands[1];
2370 if (register_operand (dest, VOIDmode))
2372 if (register_operand (src, VOIDmode)) /* mov r,r */
2374 if (true_regnum (dest) > true_regnum (src))
2379 return (AS2 (movw,%C0,%C1) CR_TAB
2380 AS2 (movw,%A0,%A1));
2383 return (AS2 (mov,%D0,%D1) CR_TAB
2384 AS2 (mov,%C0,%C1) CR_TAB
2385 AS2 (mov,%B0,%B1) CR_TAB
2393 return (AS2 (movw,%A0,%A1) CR_TAB
2394 AS2 (movw,%C0,%C1));
2397 return (AS2 (mov,%A0,%A1) CR_TAB
2398 AS2 (mov,%B0,%B1) CR_TAB
2399 AS2 (mov,%C0,%C1) CR_TAB
2403 else if (CONSTANT_P (src))
2405 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2408 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
2409 AS2 (ldi,%B0,hi8(%1)) CR_TAB
2410 AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2411 AS2 (ldi,%D0,hhi8(%1)));
2414 if (GET_CODE (src) == CONST_INT)
2416 const char *const clr_op0 =
2417 AVR_ENHANCED ? (AS1 (clr,%A0) CR_TAB
2418 AS1 (clr,%B0) CR_TAB
2420 : (AS1 (clr,%A0) CR_TAB
2421 AS1 (clr,%B0) CR_TAB
2422 AS1 (clr,%C0) CR_TAB
2425 if (src == const0_rtx) /* mov r,L */
2427 *l = AVR_ENHANCED ? 3 : 4;
2430 else if (src == const1_rtx)
2433 output_asm_insn (clr_op0, operands);
2434 *l = AVR_ENHANCED ? 4 : 5;
2435 return AS1 (inc,%A0);
2437 else if (src == constm1_rtx)
2439 /* Immediate constants -1 to any register */
2443 return (AS1 (clr,%A0) CR_TAB
2444 AS1 (dec,%A0) CR_TAB
2445 AS2 (mov,%B0,%A0) CR_TAB
2446 AS2 (movw,%C0,%A0));
2449 return (AS1 (clr,%A0) CR_TAB
2450 AS1 (dec,%A0) CR_TAB
2451 AS2 (mov,%B0,%A0) CR_TAB
2452 AS2 (mov,%C0,%A0) CR_TAB
2457 int bit_nr = exact_log2 (INTVAL (src));
2461 *l = AVR_ENHANCED ? 5 : 6;
2464 output_asm_insn (clr_op0, operands);
2465 output_asm_insn ("set", operands);
2468 avr_output_bld (operands, bit_nr);
2475 /* Last resort, better than loading from memory. */
2477 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2478 AS2 (ldi,r31,lo8(%1)) CR_TAB
2479 AS2 (mov,%A0,r31) CR_TAB
2480 AS2 (ldi,r31,hi8(%1)) CR_TAB
2481 AS2 (mov,%B0,r31) CR_TAB
2482 AS2 (ldi,r31,hlo8(%1)) CR_TAB
2483 AS2 (mov,%C0,r31) CR_TAB
2484 AS2 (ldi,r31,hhi8(%1)) CR_TAB
2485 AS2 (mov,%D0,r31) CR_TAB
2486 AS2 (mov,r31,__tmp_reg__));
2488 else if (GET_CODE (src) == MEM)
2489 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2491 else if (GET_CODE (dest) == MEM)
2493 const char *template;
2495 if (src == const0_rtx)
2496 operands[1] = zero_reg_rtx;
2498 template = out_movsi_mr_r (insn, operands, real_l);
2501 output_asm_insn (template, operands);
2506 fatal_insn ("invalid insn:", insn);
2511 out_movqi_mr_r (insn, op, l)
2514 int *l; /* instruction length */
2518 rtx x = XEXP (dest, 0);
2524 if (CONSTANT_ADDRESS_P (x))
2526 if (avr_io_address_p (x, 1))
2529 return AS2 (out,%0-0x20,%1);
2532 return AS2 (sts,%0,%1);
2534 /* memory access by reg+disp */
2535 else if (GET_CODE (x) == PLUS
2536 && REG_P (XEXP (x,0))
2537 && GET_CODE (XEXP (x,1)) == CONST_INT)
2539 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2541 int disp = INTVAL (XEXP (x,1));
2542 if (REGNO (XEXP (x,0)) != REG_Y)
2543 fatal_insn ("incorrect insn:",insn);
2545 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2546 return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2547 AS2 (std,Y+63,%1) CR_TAB
2548 AS2 (sbiw,r28,%o0-63));
2550 return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2551 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2552 AS2 (st,Y,%1) CR_TAB
2553 AS2 (subi,r28,lo8(%o0)) CR_TAB
2554 AS2 (sbci,r29,hi8(%o0)));
2556 else if (REGNO (XEXP (x,0)) == REG_X)
2558 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2560 if (reg_unused_after (insn, XEXP (x,0)))
2561 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2562 AS2 (adiw,r26,%o0) CR_TAB
2563 AS2 (st,X,__tmp_reg__));
2565 return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2566 AS2 (adiw,r26,%o0) CR_TAB
2567 AS2 (st,X,__tmp_reg__) CR_TAB
2568 AS2 (sbiw,r26,%o0));
2572 if (reg_unused_after (insn, XEXP (x,0)))
2573 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2576 return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2577 AS2 (st,X,%1) CR_TAB
2578 AS2 (sbiw,r26,%o0));
2582 return AS2 (std,%0,%1);
2585 return AS2 (st,%0,%1);
2589 out_movhi_mr_r (insn, op, l)
2596 rtx base = XEXP (dest, 0);
2597 int reg_base = true_regnum (base);
2598 int reg_src = true_regnum (src);
2602 if (CONSTANT_ADDRESS_P (base))
2604 if (avr_io_address_p (base, 2))
2607 return (AS2 (out,%B0-0x20,%B1) CR_TAB
2608 AS2 (out,%A0-0x20,%A1));
2610 return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2615 if (reg_base == REG_X)
2617 if (reg_src == REG_X)
2619 /* "st X+,r26" is undefined */
2620 if (reg_unused_after (insn, src))
2621 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2622 AS2 (st,X,r26) CR_TAB
2623 AS2 (adiw,r26,1) CR_TAB
2624 AS2 (st,X,__tmp_reg__));
2626 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2627 AS2 (st,X,r26) CR_TAB
2628 AS2 (adiw,r26,1) CR_TAB
2629 AS2 (st,X,__tmp_reg__) CR_TAB
2634 if (reg_unused_after (insn, base))
2635 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2638 return *l=3, (AS2 (st ,X+,%A1) CR_TAB
2639 AS2 (st ,X,%B1) CR_TAB
2644 return *l=2, (AS2 (st ,%0,%A1) CR_TAB
2645 AS2 (std,%0+1,%B1));
2647 else if (GET_CODE (base) == PLUS)
2649 int disp = INTVAL (XEXP (base, 1));
2650 reg_base = REGNO (XEXP (base, 0));
2651 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2653 if (reg_base != REG_Y)
2654 fatal_insn ("incorrect insn:",insn);
2656 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2657 return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2658 AS2 (std,Y+62,%A1) CR_TAB
2659 AS2 (std,Y+63,%B1) CR_TAB
2660 AS2 (sbiw,r28,%o0-62));
2662 return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2663 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2664 AS2 (st,Y,%A1) CR_TAB
2665 AS2 (std,Y+1,%B1) CR_TAB
2666 AS2 (subi,r28,lo8(%o0)) CR_TAB
2667 AS2 (sbci,r29,hi8(%o0)));
2669 if (reg_base == REG_X)
2672 if (reg_src == REG_X)
2675 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2676 AS2 (mov,__zero_reg__,r27) CR_TAB
2677 AS2 (adiw,r26,%o0) CR_TAB
2678 AS2 (st,X+,__tmp_reg__) CR_TAB
2679 AS2 (st,X,__zero_reg__) CR_TAB
2680 AS1 (clr,__zero_reg__) CR_TAB
2681 AS2 (sbiw,r26,%o0+1));
2684 return (AS2 (adiw,r26,%o0) CR_TAB
2685 AS2 (st,X+,%A1) CR_TAB
2686 AS2 (st,X,%B1) CR_TAB
2687 AS2 (sbiw,r26,%o0+1));
2689 return *l=2, (AS2 (std,%A0,%A1) CR_TAB
2692 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2693 return *l=2, (AS2 (st,%0,%B1) CR_TAB
2695 else if (GET_CODE (base) == POST_INC) /* (R++) */
2696 return *l=2, (AS2 (st,%0,%A1) CR_TAB
2698 fatal_insn ("unknown move insn:",insn);
2702 /* Return 1 if frame pointer for current function required */
2705 frame_pointer_required_p ()
2707 return (current_function_calls_alloca
2708 || current_function_args_info.nregs == 0
2709 || get_frame_size () > 0);
2712 /* Returns the condition of compare insn INSN, or UNKNOWN. */
2715 compare_condition (insn)
2718 rtx next = next_real_insn (insn);
2719 RTX_CODE cond = UNKNOWN;
2720 if (next && GET_CODE (next) == JUMP_INSN)
2722 rtx pat = PATTERN (next);
2723 rtx src = SET_SRC (pat);
2724 rtx t = XEXP (src, 0);
2725 cond = GET_CODE (t);
2730 /* Returns nonzero if INSN is a tst insn that only tests the sign. */
2733 compare_sign_p (insn)
2736 RTX_CODE cond = compare_condition (insn);
2737 return (cond == GE || cond == LT);
2740 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
2741 that needs to be swapped (GT, GTU, LE, LEU). */
2744 compare_diff_p (insn)
2747 RTX_CODE cond = compare_condition (insn);
2748 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2751 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition. */
2757 RTX_CODE cond = compare_condition (insn);
2758 return (cond == EQ || cond == NE);
2762 /* Output test instruction for HImode */
2769 if (compare_sign_p (insn))
2772 return AS1 (tst,%B0);
2774 if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
2775 && compare_eq_p (insn))
2777 /* faster than sbiw if we can clobber the operand */
2779 return AS2 (or,%A0,%B0);
2781 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2784 return AS2 (sbiw,%0,0);
2787 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2788 AS2 (cpc,%B0,__zero_reg__));
2792 /* Output test instruction for SImode */
2799 if (compare_sign_p (insn))
2802 return AS1 (tst,%D0);
2804 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2807 return (AS2 (sbiw,%A0,0) CR_TAB
2808 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2809 AS2 (cpc,%D0,__zero_reg__));
2812 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2813 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2814 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2815 AS2 (cpc,%D0,__zero_reg__));
2819 /* Generate asm equivalent for various shifts.
2820 Shift count is a CONST_INT, MEM or REG.
2821 This only handles cases that are not already
2822 carefully hand-optimized in ?sh??i3_out. */
2825 out_shift_with_cnt (template, insn, operands, len, t_len)
2826 const char *template;
2830 int t_len; /* Length of template. */
2834 int second_label = 1;
2835 int saved_in_tmp = 0;
2836 int use_zero_reg = 0;
2838 op[0] = operands[0];
2839 op[1] = operands[1];
2840 op[2] = operands[2];
2841 op[3] = operands[3];
2847 if (GET_CODE (operands[2]) == CONST_INT)
2849 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2850 int count = INTVAL (operands[2]);
2851 int max_len = 10; /* If larger than this, always use a loop. */
2853 if (count < 8 && !scratch)
2857 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
2859 if (t_len * count <= max_len)
2861 /* Output shifts inline with no loop - faster. */
2863 *len = t_len * count;
2867 output_asm_insn (template, op);
2876 strcat (str, AS2 (ldi,%3,%2));
2878 else if (use_zero_reg)
2880 /* Hack to save one word: use __zero_reg__ as loop counter.
2881 Set one bit, then shift in a loop until it is 0 again. */
2883 op[3] = zero_reg_rtx;
2887 strcat (str, ("set" CR_TAB
2888 AS2 (bld,%3,%2-1)));
2892 /* No scratch register available, use one from LD_REGS (saved in
2893 __tmp_reg__) that doesn't overlap with registers to shift. */
2895 op[3] = gen_rtx (REG, QImode,
2896 ((true_regnum (operands[0]) - 1) & 15) + 16);
2897 op[4] = tmp_reg_rtx;
2901 *len = 3; /* Includes "mov %3,%4" after the loop. */
2903 strcat (str, (AS2 (mov,%4,%3) CR_TAB
2909 else if (GET_CODE (operands[2]) == MEM)
2913 op[3] = op_mov[0] = tmp_reg_rtx;
2917 out_movqi_r_mr (insn, op_mov, len);
2919 output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2921 else if (register_operand (operands[2], QImode))
2923 if (reg_unused_after (insn, operands[2]))
2927 op[3] = tmp_reg_rtx;
2929 strcat (str, (AS2 (mov,%3,%2) CR_TAB));
2933 fatal_insn ("bad shift insn:", insn);
2940 strcat (str, AS1 (rjmp,2f));
2944 *len += t_len + 2; /* template + dec + brXX */
2947 strcat (str, "\n1:\t");
2948 strcat (str, template);
2949 strcat (str, second_label ? "\n2:\t" : "\n\t");
2950 strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
2951 strcat (str, CR_TAB);
2952 strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
2954 strcat (str, (CR_TAB AS2 (mov,%3,%4)));
2955 output_asm_insn (str, op);
2960 /* 8bit shift left ((char)x << i) */
2963 ashlqi3_out (insn, operands, len)
2966 int *len; /* insn length (may be NULL) */
2968 if (GET_CODE (operands[2]) == CONST_INT)
2975 switch (INTVAL (operands[2]))
2979 return AS1 (clr,%0);
2983 return AS1 (lsl,%0);
2987 return (AS1 (lsl,%0) CR_TAB
2992 return (AS1 (lsl,%0) CR_TAB
2997 if (test_hard_reg_class (LD_REGS, operands[0]))
3000 return (AS1 (swap,%0) CR_TAB
3001 AS2 (andi,%0,0xf0));
3004 return (AS1 (lsl,%0) CR_TAB
3010 if (test_hard_reg_class (LD_REGS, operands[0]))
3013 return (AS1 (swap,%0) CR_TAB
3015 AS2 (andi,%0,0xe0));
3018 return (AS1 (lsl,%0) CR_TAB
3025 if (test_hard_reg_class (LD_REGS, operands[0]))
3028 return (AS1 (swap,%0) CR_TAB
3031 AS2 (andi,%0,0xc0));
3034 return (AS1 (lsl,%0) CR_TAB
3043 return (AS1 (ror,%0) CR_TAB
3048 else if (CONSTANT_P (operands[2]))
3049 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3051 out_shift_with_cnt (AS1 (lsl,%0),
3052 insn, operands, len, 1);
3057 /* 16bit shift left ((short)x << i) */
3060 ashlhi3_out (insn, operands, len)
3065 if (GET_CODE (operands[2]) == CONST_INT)
3067 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3068 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3075 switch (INTVAL (operands[2]))
3078 if (optimize_size && scratch)
3083 return (AS1 (swap,%A0) CR_TAB
3084 AS1 (swap,%B0) CR_TAB
3085 AS2 (andi,%B0,0xf0) CR_TAB
3086 AS2 (eor,%B0,%A0) CR_TAB
3087 AS2 (andi,%A0,0xf0) CR_TAB
3093 return (AS1 (swap,%A0) CR_TAB
3094 AS1 (swap,%B0) CR_TAB
3095 AS2 (ldi,%3,0xf0) CR_TAB
3096 AS2 (and,%B0,%3) CR_TAB
3097 AS2 (eor,%B0,%A0) CR_TAB
3098 AS2 (and,%A0,%3) CR_TAB
3101 break; /* optimize_size ? 6 : 8 */
3105 break; /* scratch ? 5 : 6 */
3109 return (AS1 (lsl,%A0) CR_TAB
3110 AS1 (rol,%B0) CR_TAB
3111 AS1 (swap,%A0) CR_TAB
3112 AS1 (swap,%B0) CR_TAB
3113 AS2 (andi,%B0,0xf0) CR_TAB
3114 AS2 (eor,%B0,%A0) CR_TAB
3115 AS2 (andi,%A0,0xf0) CR_TAB
3121 return (AS1 (lsl,%A0) CR_TAB
3122 AS1 (rol,%B0) CR_TAB
3123 AS1 (swap,%A0) CR_TAB
3124 AS1 (swap,%B0) CR_TAB
3125 AS2 (ldi,%3,0xf0) CR_TAB
3126 AS2 (and,%B0,%3) CR_TAB
3127 AS2 (eor,%B0,%A0) CR_TAB
3128 AS2 (and,%A0,%3) CR_TAB
3135 break; /* scratch ? 5 : 6 */
3137 return (AS1 (clr,__tmp_reg__) CR_TAB
3138 AS1 (lsr,%B0) CR_TAB
3139 AS1 (ror,%A0) CR_TAB
3140 AS1 (ror,__tmp_reg__) CR_TAB
3141 AS1 (lsr,%B0) CR_TAB
3142 AS1 (ror,%A0) CR_TAB
3143 AS1 (ror,__tmp_reg__) CR_TAB
3144 AS2 (mov,%B0,%A0) CR_TAB
3145 AS2 (mov,%A0,__tmp_reg__));
3149 return (AS1 (lsr,%B0) CR_TAB
3150 AS2 (mov,%B0,%A0) CR_TAB
3151 AS1 (clr,%A0) CR_TAB
3152 AS1 (ror,%B0) CR_TAB
3156 if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
3157 return *len = 1, AS1 (clr,%A0);
3159 return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3164 return (AS2 (mov,%B0,%A0) CR_TAB
3165 AS1 (clr,%A0) CR_TAB
3170 return (AS2 (mov,%B0,%A0) CR_TAB
3171 AS1 (clr,%A0) CR_TAB
3172 AS1 (lsl,%B0) CR_TAB
3177 return (AS2 (mov,%B0,%A0) CR_TAB
3178 AS1 (clr,%A0) CR_TAB
3179 AS1 (lsl,%B0) CR_TAB
3180 AS1 (lsl,%B0) CR_TAB
3187 return (AS2 (mov,%B0,%A0) CR_TAB
3188 AS1 (clr,%A0) CR_TAB
3189 AS1 (swap,%B0) CR_TAB
3190 AS2 (andi,%B0,0xf0));
3195 return (AS2 (mov,%B0,%A0) CR_TAB
3196 AS1 (clr,%A0) CR_TAB
3197 AS1 (swap,%B0) CR_TAB
3198 AS2 (ldi,%3,0xf0) CR_TAB
3202 return (AS2 (mov,%B0,%A0) CR_TAB
3203 AS1 (clr,%A0) CR_TAB
3204 AS1 (lsl,%B0) CR_TAB
3205 AS1 (lsl,%B0) CR_TAB
3206 AS1 (lsl,%B0) CR_TAB
3213 return (AS2 (mov,%B0,%A0) CR_TAB
3214 AS1 (clr,%A0) CR_TAB
3215 AS1 (swap,%B0) CR_TAB
3216 AS1 (lsl,%B0) CR_TAB
3217 AS2 (andi,%B0,0xe0));
3219 if (AVR_ENHANCED && scratch)
3222 return (AS2 (ldi,%3,0x20) CR_TAB
3223 AS2 (mul,%A0,%3) CR_TAB
3224 AS2 (mov,%B0,r0) CR_TAB
3225 AS1 (clr,%A0) CR_TAB
3226 AS1 (clr,__zero_reg__));
3228 if (optimize_size && scratch)
3233 return (AS2 (mov,%B0,%A0) CR_TAB
3234 AS1 (clr,%A0) CR_TAB
3235 AS1 (swap,%B0) CR_TAB
3236 AS1 (lsl,%B0) CR_TAB
3237 AS2 (ldi,%3,0xe0) CR_TAB
3243 return ("set" CR_TAB
3244 AS2 (bld,r1,5) CR_TAB
3245 AS2 (mul,%A0,r1) CR_TAB
3246 AS2 (mov,%B0,r0) CR_TAB
3247 AS1 (clr,%A0) CR_TAB
3248 AS1 (clr,__zero_reg__));
3251 return (AS2 (mov,%B0,%A0) CR_TAB
3252 AS1 (clr,%A0) CR_TAB
3253 AS1 (lsl,%B0) CR_TAB
3254 AS1 (lsl,%B0) CR_TAB
3255 AS1 (lsl,%B0) CR_TAB
3256 AS1 (lsl,%B0) CR_TAB
3260 if (AVR_ENHANCED && ldi_ok)
3263 return (AS2 (ldi,%B0,0x40) CR_TAB
3264 AS2 (mul,%A0,%B0) CR_TAB
3265 AS2 (mov,%B0,r0) CR_TAB
3266 AS1 (clr,%A0) CR_TAB
3267 AS1 (clr,__zero_reg__));
3269 if (AVR_ENHANCED && scratch)
3272 return (AS2 (ldi,%3,0x40) CR_TAB
3273 AS2 (mul,%A0,%3) CR_TAB
3274 AS2 (mov,%B0,r0) CR_TAB
3275 AS1 (clr,%A0) CR_TAB
3276 AS1 (clr,__zero_reg__));
3278 if (optimize_size && ldi_ok)
3281 return (AS2 (mov,%B0,%A0) CR_TAB
3282 AS2 (ldi,%A0,6) "\n1:\t"
3283 AS1 (lsl,%B0) CR_TAB
3284 AS1 (dec,%A0) CR_TAB
3287 if (optimize_size && scratch)
3290 return (AS1 (clr,%B0) CR_TAB
3291 AS1 (lsr,%A0) CR_TAB
3292 AS1 (ror,%B0) CR_TAB
3293 AS1 (lsr,%A0) CR_TAB
3294 AS1 (ror,%B0) CR_TAB
3299 return (AS1 (clr,%B0) CR_TAB
3300 AS1 (lsr,%A0) CR_TAB
3301 AS1 (ror,%B0) CR_TAB
3306 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3308 insn, operands, len, 2);
3313 /* 32bit shift left ((long)x << i) */
3316 ashlsi3_out (insn, operands, len)
3321 if (GET_CODE (operands[2]) == CONST_INT)
3329 switch (INTVAL (operands[2]))
3333 int reg0 = true_regnum (operands[0]);
3334 int reg1 = true_regnum (operands[1]);
3337 return (AS2 (mov,%D0,%C1) CR_TAB
3338 AS2 (mov,%C0,%B1) CR_TAB
3339 AS2 (mov,%B0,%A1) CR_TAB
3341 else if (reg0 + 1 == reg1)
3344 return AS1 (clr,%A0);
3347 return (AS1 (clr,%A0) CR_TAB
3348 AS2 (mov,%B0,%A1) CR_TAB
3349 AS2 (mov,%C0,%B1) CR_TAB
3355 int reg0 = true_regnum (operands[0]);
3356 int reg1 = true_regnum (operands[1]);
3358 if (AVR_ENHANCED && (reg0 + 2 != reg1))
3361 return (AS2 (movw,%C0,%A1) CR_TAB
3362 AS1 (clr,%B0) CR_TAB
3365 if (reg0 + 1 >= reg1)
3366 return (AS2 (mov,%D0,%B1) CR_TAB
3367 AS2 (mov,%C0,%A1) CR_TAB
3368 AS1 (clr,%B0) CR_TAB
3370 if (reg0 + 2 == reg1)
3373 return (AS1 (clr,%B0) CR_TAB
3377 return (AS2 (mov,%C0,%A1) CR_TAB
3378 AS2 (mov,%D0,%B1) CR_TAB
3379 AS1 (clr,%B0) CR_TAB
3385 if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
3386 return (AS2 (mov,%D0,%A1) CR_TAB
3387 AS1 (clr,%C0) CR_TAB
3388 AS1 (clr,%B0) CR_TAB
3393 return (AS1 (clr,%C0) CR_TAB
3394 AS1 (clr,%B0) CR_TAB
3400 return (AS1 (clr,%D0) CR_TAB
3401 AS1 (lsr,%A0) CR_TAB
3402 AS1 (ror,%D0) CR_TAB
3403 AS1 (clr,%C0) CR_TAB
3404 AS1 (clr,%B0) CR_TAB
3409 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3410 AS1 (rol,%B0) CR_TAB
3411 AS1 (rol,%C0) CR_TAB
3413 insn, operands, len, 4);
3417 /* 8bit arithmetic shift right ((signed char)x >> i) */
3420 ashrqi3_out (insn, operands, len)
3423 int *len; /* insn length */
3425 if (GET_CODE (operands[2]) == CONST_INT)
3432 switch (INTVAL (operands[2]))
3436 return AS1 (asr,%0);
3440 return (AS1 (asr,%0) CR_TAB
3445 return (AS1 (asr,%0) CR_TAB
3451 return (AS1 (asr,%0) CR_TAB
3458 return (AS1 (asr,%0) CR_TAB
3466 return (AS2 (bst,%0,6) CR_TAB
3468 AS2 (sbc,%0,%0) CR_TAB
3474 return (AS1 (lsl,%0) CR_TAB
3478 else if (CONSTANT_P (operands[2]))
3479 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3481 out_shift_with_cnt (AS1 (asr,%0),
3482 insn, operands, len, 1);
3487 /* 16bit arithmetic shift right ((signed short)x >> i) */
3490 ashrhi3_out (insn, operands, len)
3495 if (GET_CODE (operands[2]) == CONST_INT)
3497 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3498 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3505 switch (INTVAL (operands[2]))
3509 /* XXX try to optimize this too? */
3514 break; /* scratch ? 5 : 6 */
3516 return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3517 AS2 (mov,%A0,%B0) CR_TAB
3518 AS1 (lsl,__tmp_reg__) CR_TAB
3519 AS1 (rol,%A0) CR_TAB
3520 AS2 (sbc,%B0,%B0) CR_TAB
3521 AS1 (lsl,__tmp_reg__) CR_TAB
3522 AS1 (rol,%A0) CR_TAB
3527 return (AS1 (lsl,%A0) CR_TAB
3528 AS2 (mov,%A0,%B0) CR_TAB
3529 AS1 (rol,%A0) CR_TAB
3534 int reg0 = true_regnum (operands[0]);
3535 int reg1 = true_regnum (operands[1]);
3538 return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3539 AS1 (lsl,%B0) CR_TAB
3541 else if (reg0 == reg1 + 1)
3542 return *len = 3, (AS1 (clr,%B0) CR_TAB
3543 AS2 (sbrc,%A0,7) CR_TAB
3546 return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3547 AS1 (clr,%B0) CR_TAB
3548 AS2 (sbrc,%A0,7) CR_TAB
3554 return (AS2 (mov,%A0,%B0) CR_TAB
3555 AS1 (lsl,%B0) CR_TAB
3556 AS2 (sbc,%B0,%B0) CR_TAB
3561 return (AS2 (mov,%A0,%B0) CR_TAB
3562 AS1 (lsl,%B0) CR_TAB
3563 AS2 (sbc,%B0,%B0) CR_TAB
3564 AS1 (asr,%A0) CR_TAB
3568 if (AVR_ENHANCED && ldi_ok)
3571 return (AS2 (ldi,%A0,0x20) CR_TAB
3572 AS2 (muls,%B0,%A0) CR_TAB
3573 AS2 (mov,%A0,r1) CR_TAB
3574 AS2 (sbc,%B0,%B0) CR_TAB
3575 AS1 (clr,__zero_reg__));
3577 if (optimize_size && scratch)
3580 return (AS2 (mov,%A0,%B0) CR_TAB
3581 AS1 (lsl,%B0) CR_TAB
3582 AS2 (sbc,%B0,%B0) CR_TAB
3583 AS1 (asr,%A0) CR_TAB
3584 AS1 (asr,%A0) CR_TAB
3588 if (AVR_ENHANCED && ldi_ok)
3591 return (AS2 (ldi,%A0,0x10) CR_TAB
3592 AS2 (muls,%B0,%A0) CR_TAB
3593 AS2 (mov,%A0,r1) CR_TAB
3594 AS2 (sbc,%B0,%B0) CR_TAB
3595 AS1 (clr,__zero_reg__));
3597 if (optimize_size && scratch)
3600 return (AS2 (mov,%A0,%B0) CR_TAB
3601 AS1 (lsl,%B0) CR_TAB
3602 AS2 (sbc,%B0,%B0) CR_TAB
3603 AS1 (asr,%A0) CR_TAB
3604 AS1 (asr,%A0) CR_TAB
3605 AS1 (asr,%A0) CR_TAB
3609 if (AVR_ENHANCED && ldi_ok)
3612 return (AS2 (ldi,%A0,0x08) CR_TAB
3613 AS2 (muls,%B0,%A0) CR_TAB
3614 AS2 (mov,%A0,r1) CR_TAB
3615 AS2 (sbc,%B0,%B0) CR_TAB
3616 AS1 (clr,__zero_reg__));
3619 break; /* scratch ? 5 : 7 */
3621 return (AS2 (mov,%A0,%B0) CR_TAB
3622 AS1 (lsl,%B0) CR_TAB
3623 AS2 (sbc,%B0,%B0) CR_TAB
3624 AS1 (asr,%A0) CR_TAB
3625 AS1 (asr,%A0) CR_TAB
3626 AS1 (asr,%A0) CR_TAB
3627 AS1 (asr,%A0) CR_TAB
3632 return (AS1 (lsl,%B0) CR_TAB
3633 AS2 (sbc,%A0,%A0) CR_TAB
3634 AS1 (lsl,%B0) CR_TAB
3635 AS2 (mov,%B0,%A0) CR_TAB
3639 return *len = 3, (AS1 (lsl,%B0) CR_TAB
3640 AS2 (sbc,%A0,%A0) CR_TAB
3645 out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3647 insn, operands, len, 2);
3652 /* 32bit arithmetic shift right ((signed long)x >> i) */
3655 ashrsi3_out (insn, operands, len)
3660 if (GET_CODE (operands[2]) == CONST_INT)
3668 switch (INTVAL (operands[2]))
3672 int reg0 = true_regnum (operands[0]);
3673 int reg1 = true_regnum (operands[1]);
3676 return (AS2 (mov,%A0,%B1) CR_TAB
3677 AS2 (mov,%B0,%C1) CR_TAB
3678 AS2 (mov,%C0,%D1) CR_TAB
3679 AS1 (clr,%D0) CR_TAB
3680 AS2 (sbrc,%C0,7) CR_TAB
3682 else if (reg0 == reg1 + 1)
3685 return (AS1 (clr,%D0) CR_TAB
3686 AS2 (sbrc,%C0,7) CR_TAB
3690 return (AS1 (clr,%D0) CR_TAB
3691 AS2 (sbrc,%D1,7) CR_TAB
3692 AS1 (dec,%D0) CR_TAB
3693 AS2 (mov,%C0,%D1) CR_TAB
3694 AS2 (mov,%B0,%C1) CR_TAB
3700 int reg0 = true_regnum (operands[0]);
3701 int reg1 = true_regnum (operands[1]);
3703 if (AVR_ENHANCED && (reg0 != reg1 + 2))
3706 return (AS2 (movw,%A0,%C1) CR_TAB
3707 AS1 (clr,%D0) CR_TAB
3708 AS2 (sbrc,%B0,7) CR_TAB
3709 AS1 (com,%D0) CR_TAB
3712 if (reg0 <= reg1 + 1)
3713 return (AS2 (mov,%A0,%C1) CR_TAB
3714 AS2 (mov,%B0,%D1) CR_TAB
3715 AS1 (clr,%D0) CR_TAB
3716 AS2 (sbrc,%B0,7) CR_TAB
3717 AS1 (com,%D0) CR_TAB
3719 else if (reg0 == reg1 + 2)
3720 return *len = 4, (AS1 (clr,%D0) CR_TAB
3721 AS2 (sbrc,%B0,7) CR_TAB
3722 AS1 (com,%D0) CR_TAB
3725 return (AS2 (mov,%B0,%D1) CR_TAB
3726 AS2 (mov,%A0,%C1) CR_TAB
3727 AS1 (clr,%D0) CR_TAB
3728 AS2 (sbrc,%B0,7) CR_TAB
3729 AS1 (com,%D0) CR_TAB
3734 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3735 return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3736 AS1 (clr,%D0) CR_TAB
3737 AS2 (sbrc,%A0,7) CR_TAB
3738 AS1 (com,%D0) CR_TAB
3739 AS2 (mov,%B0,%D0) CR_TAB
3742 return *len = 5, (AS1 (clr,%D0) CR_TAB
3743 AS2 (sbrc,%A0,7) CR_TAB
3744 AS1 (com,%D0) CR_TAB
3745 AS2 (mov,%B0,%D0) CR_TAB
3750 return *len = 4, (AS1 (lsl,%D0) CR_TAB
3751 AS2 (sbc,%A0,%A0) CR_TAB
3752 AS2 (mov,%B0,%A0) CR_TAB
3753 AS2 (movw,%C0,%A0));
3755 return *len = 5, (AS1 (lsl,%D0) CR_TAB
3756 AS2 (sbc,%A0,%A0) CR_TAB
3757 AS2 (mov,%B0,%A0) CR_TAB
3758 AS2 (mov,%C0,%A0) CR_TAB
3763 out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
3764 AS1 (ror,%C0) CR_TAB
3765 AS1 (ror,%B0) CR_TAB
3767 insn, operands, len, 4);
3771 /* 8bit logic shift right ((unsigned char)x >> i) */
3774 lshrqi3_out (insn, operands, len)
3779 if (GET_CODE (operands[2]) == CONST_INT)
3786 switch (INTVAL (operands[2]))
3790 return AS1 (clr,%0);
3794 return AS1 (lsr,%0);
3798 return (AS1 (lsr,%0) CR_TAB
3802 return (AS1 (lsr,%0) CR_TAB
3807 if (test_hard_reg_class (LD_REGS, operands[0]))
3810 return (AS1 (swap,%0) CR_TAB
3811 AS2 (andi,%0,0x0f));
3814 return (AS1 (lsr,%0) CR_TAB
3820 if (test_hard_reg_class (LD_REGS, operands[0]))
3823 return (AS1 (swap,%0) CR_TAB
3828 return (AS1 (lsr,%0) CR_TAB
3835 if (test_hard_reg_class (LD_REGS, operands[0]))
3838 return (AS1 (swap,%0) CR_TAB
3844 return (AS1 (lsr,%0) CR_TAB
3853 return (AS1 (rol,%0) CR_TAB
3858 else if (CONSTANT_P (operands[2]))
3859 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3861 out_shift_with_cnt (AS1 (lsr,%0),
3862 insn, operands, len, 1);
3866 /* 16bit logic shift right ((unsigned short)x >> i) */
3869 lshrhi3_out (insn, operands, len)
3874 if (GET_CODE (operands[2]) == CONST_INT)
3876 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3877 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3884 switch (INTVAL (operands[2]))
3887 if (optimize_size && scratch)
3892 return (AS1 (swap,%B0) CR_TAB
3893 AS1 (swap,%A0) CR_TAB
3894 AS2 (andi,%A0,0x0f) CR_TAB
3895 AS2 (eor,%A0,%B0) CR_TAB
3896 AS2 (andi,%B0,0x0f) CR_TAB
3902 return (AS1 (swap,%B0) CR_TAB
3903 AS1 (swap,%A0) CR_TAB
3904 AS2 (ldi,%3,0x0f) CR_TAB
3905 AS2 (and,%A0,%3) CR_TAB
3906 AS2 (eor,%A0,%B0) CR_TAB
3907 AS2 (and,%B0,%3) CR_TAB
3910 break; /* optimize_size ? 6 : 8 */
3914 break; /* scratch ? 5 : 6 */
3918 return (AS1 (lsr,%B0) CR_TAB
3919 AS1 (ror,%A0) CR_TAB
3920 AS1 (swap,%B0) CR_TAB
3921 AS1 (swap,%A0) CR_TAB
3922 AS2 (andi,%A0,0x0f) CR_TAB
3923 AS2 (eor,%A0,%B0) CR_TAB
3924 AS2 (andi,%B0,0x0f) CR_TAB
3930 return (AS1 (lsr,%B0) CR_TAB
3931 AS1 (ror,%A0) CR_TAB
3932 AS1 (swap,%B0) CR_TAB
3933 AS1 (swap,%A0) CR_TAB
3934 AS2 (ldi,%3,0x0f) CR_TAB
3935 AS2 (and,%A0,%3) CR_TAB
3936 AS2 (eor,%A0,%B0) CR_TAB
3937 AS2 (and,%B0,%3) CR_TAB
3944 break; /* scratch ? 5 : 6 */
3946 return (AS1 (clr,__tmp_reg__) CR_TAB
3947 AS1 (lsl,%A0) CR_TAB
3948 AS1 (rol,%B0) CR_TAB
3949 AS1 (rol,__tmp_reg__) CR_TAB
3950 AS1 (lsl,%A0) CR_TAB
3951 AS1 (rol,%B0) CR_TAB
3952 AS1 (rol,__tmp_reg__) CR_TAB
3953 AS2 (mov,%A0,%B0) CR_TAB
3954 AS2 (mov,%B0,__tmp_reg__));
3958 return (AS1 (lsl,%A0) CR_TAB
3959 AS2 (mov,%A0,%B0) CR_TAB
3960 AS1 (rol,%A0) CR_TAB
3961 AS2 (sbc,%B0,%B0) CR_TAB
3965 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
3966 return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
3969 return *len = 1, AS1 (clr,%B0);
3973 return (AS2 (mov,%A0,%B0) CR_TAB
3974 AS1 (clr,%B0) CR_TAB
3979 return (AS2 (mov,%A0,%B0) CR_TAB
3980 AS1 (clr,%B0) CR_TAB
3981 AS1 (lsr,%A0) CR_TAB
3986 return (AS2 (mov,%A0,%B0) CR_TAB
3987 AS1 (clr,%B0) CR_TAB
3988 AS1 (lsr,%A0) CR_TAB
3989 AS1 (lsr,%A0) CR_TAB
3996 return (AS2 (mov,%A0,%B0) CR_TAB
3997 AS1 (clr,%B0) CR_TAB
3998 AS1 (swap,%A0) CR_TAB
3999 AS2 (andi,%A0,0x0f));
4004 return (AS2 (mov,%A0,%B0) CR_TAB
4005 AS1 (clr,%B0) CR_TAB
4006 AS1 (swap,%A0) CR_TAB
4007 AS2 (ldi,%3,0x0f) CR_TAB
4011 return (AS2 (mov,%A0,%B0) CR_TAB
4012 AS1 (clr,%B0) CR_TAB
4013 AS1 (lsr,%A0) CR_TAB
4014 AS1 (lsr,%A0) CR_TAB
4015 AS1 (lsr,%A0) CR_TAB
4022 return (AS2 (mov,%A0,%B0) CR_TAB
4023 AS1 (clr,%B0) CR_TAB
4024 AS1 (swap,%A0) CR_TAB
4025 AS1 (lsr,%A0) CR_TAB
4026 AS2 (andi,%A0,0x07));
4028 if (AVR_ENHANCED && scratch)
4031 return (AS2 (ldi,%3,0x08) CR_TAB
4032 AS2 (mul,%B0,%3) CR_TAB
4033 AS2 (mov,%A0,r1) CR_TAB
4034 AS1 (clr,%B0) CR_TAB
4035 AS1 (clr,__zero_reg__));
4037 if (optimize_size && scratch)
4042 return (AS2 (mov,%A0,%B0) CR_TAB
4043 AS1 (clr,%B0) CR_TAB
4044 AS1 (swap,%A0) CR_TAB
4045 AS1 (lsr,%A0) CR_TAB
4046 AS2 (ldi,%3,0x07) CR_TAB
4052 return ("set" CR_TAB
4053 AS2 (bld,r1,3) CR_TAB
4054 AS2 (mul,%B0,r1) CR_TAB
4055 AS2 (mov,%A0,r1) CR_TAB
4056 AS1 (clr,%B0) CR_TAB
4057 AS1 (clr,__zero_reg__));
4060 return (AS2 (mov,%A0,%B0) CR_TAB
4061 AS1 (clr,%B0) CR_TAB
4062 AS1 (lsr,%A0) CR_TAB
4063 AS1 (lsr,%A0) CR_TAB
4064 AS1 (lsr,%A0) CR_TAB
4065 AS1 (lsr,%A0) CR_TAB
4069 if (AVR_ENHANCED && ldi_ok)
4072 return (AS2 (ldi,%A0,0x04) CR_TAB
4073 AS2 (mul,%B0,%A0) CR_TAB
4074 AS2 (mov,%A0,r1) CR_TAB
4075 AS1 (clr,%B0) CR_TAB
4076 AS1 (clr,__zero_reg__));
4078 if (AVR_ENHANCED && scratch)
4081 return (AS2 (ldi,%3,0x04) CR_TAB
4082 AS2 (mul,%B0,%3) CR_TAB
4083 AS2 (mov,%A0,r1) CR_TAB
4084 AS1 (clr,%B0) CR_TAB
4085 AS1 (clr,__zero_reg__));
4087 if (optimize_size && ldi_ok)
4090 return (AS2 (mov,%A0,%B0) CR_TAB
4091 AS2 (ldi,%B0,6) "\n1:\t"
4092 AS1 (lsr,%A0) CR_TAB
4093 AS1 (dec,%B0) CR_TAB
4096 if (optimize_size && scratch)
4099 return (AS1 (clr,%A0) CR_TAB
4100 AS1 (lsl,%B0) CR_TAB
4101 AS1 (rol,%A0) CR_TAB
4102 AS1 (lsl,%B0) CR_TAB
4103 AS1 (rol,%A0) CR_TAB
4108 return (AS1 (clr,%A0) CR_TAB
4109 AS1 (lsl,%B0) CR_TAB
4110 AS1 (rol,%A0) CR_TAB
4115 out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
4117 insn, operands, len, 2);
4121 /* 32bit logic shift right ((unsigned int)x >> i) */
4124 lshrsi3_out (insn, operands, len)
4129 if (GET_CODE (operands[2]) == CONST_INT)
4137 switch (INTVAL (operands[2]))
4141 int reg0 = true_regnum (operands[0]);
4142 int reg1 = true_regnum (operands[1]);
4145 return (AS2 (mov,%A0,%B1) CR_TAB
4146 AS2 (mov,%B0,%C1) CR_TAB
4147 AS2 (mov,%C0,%D1) CR_TAB
4149 else if (reg0 == reg1 + 1)
4150 return *len = 1, AS1 (clr,%D0);
4152 return (AS1 (clr,%D0) CR_TAB
4153 AS2 (mov,%C0,%D1) CR_TAB
4154 AS2 (mov,%B0,%C1) CR_TAB
4160 int reg0 = true_regnum (operands[0]);
4161 int reg1 = true_regnum (operands[1]);
4163 if (AVR_ENHANCED && (reg0 != reg1 + 2))
4166 return (AS2 (movw,%A0,%C1) CR_TAB
4167 AS1 (clr,%C0) CR_TAB
4170 if (reg0 <= reg1 + 1)
4171 return (AS2 (mov,%A0,%C1) CR_TAB
4172 AS2 (mov,%B0,%D1) CR_TAB
4173 AS1 (clr,%C0) CR_TAB
4175 else if (reg0 == reg1 + 2)
4176 return *len = 2, (AS1 (clr,%C0) CR_TAB
4179 return (AS2 (mov,%B0,%D1) CR_TAB
4180 AS2 (mov,%A0,%C1) CR_TAB
4181 AS1 (clr,%C0) CR_TAB
4186 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
4187 return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4188 AS1 (clr,%B0) CR_TAB
4189 AS1 (clr,%C0) CR_TAB
4192 return *len = 3, (AS1 (clr,%B0) CR_TAB
4193 AS1 (clr,%C0) CR_TAB
4198 return (AS1 (clr,%A0) CR_TAB
4199 AS2 (sbrc,%D0,7) CR_TAB
4200 AS1 (inc,%A0) CR_TAB
4201 AS1 (clr,%B0) CR_TAB
4202 AS1 (clr,%C0) CR_TAB
4207 out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4208 AS1 (ror,%C0) CR_TAB
4209 AS1 (ror,%B0) CR_TAB
4211 insn, operands, len, 4);
4215 /* Modifies the length assigned to instruction INSN
4216 LEN is the initially computed length of the insn. */
4219 adjust_insn_length (insn, len)
4223 rtx patt = PATTERN (insn);
4226 if (GET_CODE (patt) == SET)
4229 op[1] = SET_SRC (patt);
4230 op[0] = SET_DEST (patt);
4231 if (general_operand (op[1], VOIDmode)
4232 && general_operand (op[0], VOIDmode))
4234 switch (GET_MODE (op[0]))
4237 output_movqi (insn, op, &len);
4240 output_movhi (insn, op, &len);
4244 output_movsisf (insn, op, &len);
4250 else if (op[0] == cc0_rtx && REG_P (op[1]))
4252 switch (GET_MODE (op[1]))
4254 case HImode: out_tsthi (insn,&len); break;
4255 case SImode: out_tstsi (insn,&len); break;
4259 else if (GET_CODE (op[1]) == AND)
4261 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4263 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4264 if (GET_MODE (op[1]) == SImode)
4265 len = (((mask & 0xff) != 0xff)
4266 + ((mask & 0xff00) != 0xff00)
4267 + ((mask & 0xff0000L) != 0xff0000L)
4268 + ((mask & 0xff000000L) != 0xff000000L));
4269 else if (GET_MODE (op[1]) == HImode)
4270 len = (((mask & 0xff) != 0xff)
4271 + ((mask & 0xff00) != 0xff00));
4274 else if (GET_CODE (op[1]) == IOR)
4276 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4278 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4279 if (GET_MODE (op[1]) == SImode)
4280 len = (((mask & 0xff) != 0)
4281 + ((mask & 0xff00) != 0)
4282 + ((mask & 0xff0000L) != 0)
4283 + ((mask & 0xff000000L) != 0));
4284 else if (GET_MODE (op[1]) == HImode)
4285 len = (((mask & 0xff) != 0)
4286 + ((mask & 0xff00) != 0));
4290 set = single_set (insn);
4295 op[1] = SET_SRC (set);
4296 op[0] = SET_DEST (set);
4298 if (GET_CODE (patt) == PARALLEL
4299 && general_operand (op[1], VOIDmode)
4300 && general_operand (op[0], VOIDmode))
4302 if (XVECLEN (patt, 0) == 2)
4303 op[2] = XVECEXP (patt, 0, 1);
4305 switch (GET_MODE (op[0]))
4311 output_reload_inhi (insn, op, &len);
4315 output_reload_insisf (insn, op, &len);
4321 else if (GET_CODE (op[1]) == ASHIFT
4322 || GET_CODE (op[1]) == ASHIFTRT
4323 || GET_CODE (op[1]) == LSHIFTRT)
4327 ops[1] = XEXP (op[1],0);
4328 ops[2] = XEXP (op[1],1);
4329 switch (GET_CODE (op[1]))
4332 switch (GET_MODE (op[0]))
4334 case QImode: ashlqi3_out (insn,ops,&len); break;
4335 case HImode: ashlhi3_out (insn,ops,&len); break;
4336 case SImode: ashlsi3_out (insn,ops,&len); break;
4341 switch (GET_MODE (op[0]))
4343 case QImode: ashrqi3_out (insn,ops,&len); break;
4344 case HImode: ashrhi3_out (insn,ops,&len); break;
4345 case SImode: ashrsi3_out (insn,ops,&len); break;
4350 switch (GET_MODE (op[0]))
4352 case QImode: lshrqi3_out (insn,ops,&len); break;
4353 case HImode: lshrhi3_out (insn,ops,&len); break;
4354 case SImode: lshrsi3_out (insn,ops,&len); break;
4366 /* Return nonzero if register REG dead after INSN */
4369 reg_unused_after (insn, reg)
4373 return (dead_or_set_p (insn, reg)
4374 || (REG_P(reg) && _reg_unused_after (insn, reg)));
4377 /* Return nonzero if REG is not used after INSN.
4378 We assume REG is a reload reg, and therefore does
4379 not live past labels. It may live past calls or jumps though. */
4382 _reg_unused_after (insn, reg)
4389 /* If the reg is set by this instruction, then it is safe for our
4390 case. Disregard the case where this is a store to memory, since
4391 we are checking a register used in the store address. */
4392 set = single_set (insn);
4393 if (set && GET_CODE (SET_DEST (set)) != MEM
4394 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4397 while ((insn = NEXT_INSN (insn)))
4399 code = GET_CODE (insn);
4402 /* If this is a label that existed before reload, then the register
4403 if dead here. However, if this is a label added by reorg, then
4404 the register may still be live here. We can't tell the difference,
4405 so we just ignore labels completely. */
4406 if (code == CODE_LABEL)
4411 if (code == JUMP_INSN)
4414 /* If this is a sequence, we must handle them all at once.
4415 We could have for instance a call that sets the target register,
4416 and an insn in a delay slot that uses the register. In this case,
4417 we must return 0. */
4418 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
4423 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
4425 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
4426 rtx set = single_set (this_insn);
4428 if (GET_CODE (this_insn) == CALL_INSN)
4430 else if (GET_CODE (this_insn) == JUMP_INSN)
4432 if (INSN_ANNULLED_BRANCH_P (this_insn))
4437 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4439 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4441 if (GET_CODE (SET_DEST (set)) != MEM)
4447 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
4452 else if (code == JUMP_INSN)
4456 if (code == CALL_INSN)
4459 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4460 if (GET_CODE (XEXP (tem, 0)) == USE
4461 && REG_P (XEXP (XEXP (tem, 0), 0))
4462 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
4464 if (call_used_regs[REGNO (reg)])
4468 if (GET_RTX_CLASS (code) == 'i')
4470 rtx set = single_set (insn);
4472 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4474 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4475 return GET_CODE (SET_DEST (set)) != MEM;
4476 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
4483 /* Target hook for assembling integer objects. The AVR version needs
4484 special handling for references to certain labels. */
4487 avr_assemble_integer (x, size, aligned_p)
4492 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
4493 && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x))
4494 || GET_CODE (x) == LABEL_REF))
4496 fputs ("\t.word\tpm(", asm_out_file);
4497 output_addr_const (asm_out_file, x);
4498 fputs (")\n", asm_out_file);
4501 return default_assemble_integer (x, size, aligned_p);
4504 /* Sets section name for declaration DECL */
4507 avr_unique_section (decl, reloc)
4509 int reloc ATTRIBUTE_UNUSED;
4512 const char *name, *prefix;
4515 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
4516 name = (* targetm.strip_name_encoding) (name);
4518 if (TREE_CODE (decl) == FUNCTION_DECL)
4520 if (flag_function_sections)
4528 if (flag_function_sections)
4530 len = strlen (name) + strlen (prefix);
4531 string = alloca (len + 1);
4532 sprintf (string, "%s%s", prefix, name);
4533 DECL_SECTION_NAME (decl) = build_string (len, string);
4538 /* The routine used to output NUL terminated strings. We use a special
4539 version of this for most svr4 targets because doing so makes the
4540 generated assembly code more compact (and thus faster to assemble)
4541 as well as more readable, especially for targets like the i386
4542 (where the only alternative is to output character sequences as
4543 comma separated lists of numbers). */
4546 gas_output_limited_string(file, str)
4550 const unsigned char *_limited_str = (unsigned char *) str;
4552 fprintf (file, "%s\"", STRING_ASM_OP);
4553 for (; (ch = *_limited_str); _limited_str++)
4556 switch (escape = ESCAPES[ch])
4562 fprintf (file, "\\%03o", ch);
4566 putc (escape, file);
4570 fprintf (file, "\"\n");
4573 /* The routine used to output sequences of byte values. We use a special
4574 version of this for most svr4 targets because doing so makes the
4575 generated assembly code more compact (and thus faster to assemble)
4576 as well as more readable. Note that if we find subparts of the
4577 character sequence which end with NUL (and which are shorter than
4578 STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
4581 gas_output_ascii(file, str, length)
4586 const unsigned char *_ascii_bytes = (const unsigned char *) str;
4587 const unsigned char *limit = _ascii_bytes + length;
4588 unsigned bytes_in_chunk = 0;
4589 for (; _ascii_bytes < limit; _ascii_bytes++)
4591 const unsigned char *p;
4592 if (bytes_in_chunk >= 60)
4594 fprintf (file, "\"\n");
4597 for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
4599 if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
4601 if (bytes_in_chunk > 0)
4603 fprintf (file, "\"\n");
4606 gas_output_limited_string (file, (char*)_ascii_bytes);
4613 if (bytes_in_chunk == 0)
4614 fprintf (file, "\t.ascii\t\"");
4615 switch (escape = ESCAPES[ch = *_ascii_bytes])
4622 fprintf (file, "\\%03o", ch);
4623 bytes_in_chunk += 4;
4627 putc (escape, file);
4628 bytes_in_chunk += 2;
4633 if (bytes_in_chunk > 0)
4634 fprintf (file, "\"\n");
4637 /* Return value is nonzero if pseudos that have been
4638 assigned to registers of class CLASS would likely be spilled
4639 because registers of CLASS are needed for spill registers. */
4642 class_likely_spilled_p (c)
4645 return (c != ALL_REGS && c != ADDW_REGS);
4648 /* Valid attributes:
4649 progmem - put data to program memory;
4650 signal - make a function to be hardware interrupt. After function
4651 prologue interrupts are disabled;
4652 interrupt - make a function to be hardware interrupt. After function
4653 prologue interrupts are enabled;
4654 naked - don't generate function prologue/epilogue and `ret' command.
4656 Only `progmem' attribute valid for type. */
4658 const struct attribute_spec avr_attribute_table[] =
4660 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
4661 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute },
4662 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4663 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4664 { "naked", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4665 { NULL, 0, 0, false, false, false, NULL }
4668 /* Handle a "progmem" attribute; arguments as in
4669 struct attribute_spec.handler. */
4671 avr_handle_progmem_attribute (node, name, args, flags, no_add_attrs)
4674 tree args ATTRIBUTE_UNUSED;
4675 int flags ATTRIBUTE_UNUSED;
4680 if (TREE_CODE (*node) == TYPE_DECL)
4682 /* This is really a decl attribute, not a type attribute,
4683 but try to handle it for GCC 3.0 backwards compatibility. */
4685 tree type = TREE_TYPE (*node);
4686 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
4687 tree newtype = build_type_attribute_variant (type, attr);
4689 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
4690 TREE_TYPE (*node) = newtype;
4691 *no_add_attrs = true;
4693 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
4695 if (DECL_INITIAL (*node) == NULL_TREE && !DECL_EXTERNAL (*node))
4697 warning ("only initialized variables can be placed into "
4698 "program memory area");
4699 *no_add_attrs = true;
4704 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
4705 *no_add_attrs = true;
4712 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
4713 struct attribute_spec.handler. */
4715 avr_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
4718 tree args ATTRIBUTE_UNUSED;
4719 int flags ATTRIBUTE_UNUSED;
4722 if (TREE_CODE (*node) != FUNCTION_DECL)
4724 warning ("`%s' attribute only applies to functions",
4725 IDENTIFIER_POINTER (name));
4726 *no_add_attrs = true;
4732 /* Look for attribute `progmem' in DECL
4733 if found return 1, otherwise 0. */
4736 avr_progmem_p (decl)
4741 if (TREE_CODE (decl) != VAR_DECL)
4745 != lookup_attribute ("progmem", DECL_ATTRIBUTES (decl)))
4751 while (TREE_CODE (a) == ARRAY_TYPE);
4753 if (a == error_mark_node)
4756 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
4762 /* Add the section attribute if the variable is in progmem. */
4765 avr_insert_attributes (node, attributes)
4769 if (TREE_CODE (node) == VAR_DECL
4770 && (TREE_STATIC (node) || DECL_EXTERNAL (node))
4771 && avr_progmem_p (node))
4773 static const char dsec[] = ".progmem.data";
4774 *attributes = tree_cons (get_identifier ("section"),
4775 build_tree_list (NULL, build_string (strlen (dsec), dsec)),
4778 /* ??? This seems sketchy. Why can't the user declare the
4779 thing const in the first place? */
4780 TREE_READONLY (node) = 1;
4785 avr_section_type_flags (decl, name, reloc)
4790 unsigned int flags = default_section_type_flags (decl, name, reloc);
4792 if (strncmp (name, ".noinit", 7) == 0)
4794 if (decl && TREE_CODE (decl) == VAR_DECL
4795 && DECL_INITIAL (decl) == NULL_TREE)
4796 flags |= SECTION_BSS; /* @nobits */
4798 warning ("only uninitialized variables can be placed in the "
4805 /* Outputs some appropriate text to go at the start of an assembler
4812 error ("MCU `%s' supported for assembler only", avr_mcu_name);
4814 default_file_start ();
4816 fprintf (asm_out_file, "\t.arch %s\n", avr_mcu_name);
4817 fputs ("__SREG__ = 0x3f\n"
4819 "__SP_L__ = 0x3d\n", asm_out_file);
4821 fputs ("__tmp_reg__ = 0\n"
4822 "__zero_reg__ = 1\n", asm_out_file);
4824 /* FIXME: output these only if there is anything in the .data / .bss
4825 sections - some code size could be saved by not linking in the
4826 initialization code from libgcc if one or both sections are empty. */
4827 fputs ("\t.global __do_copy_data\n", asm_out_file);
4828 fputs ("\t.global __do_clear_bss\n", asm_out_file);
4830 commands_in_file = 0;
4831 commands_in_prologues = 0;
4832 commands_in_epilogues = 0;
4835 /* Outputs to the stdio stream FILE some
4836 appropriate text to go at the end of an assembler file. */
4841 fputs ("/* File ", asm_out_file);
4842 output_quoted_string (asm_out_file, main_input_filename);
4843 fprintf (asm_out_file,
4844 ": code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
4847 commands_in_file - commands_in_prologues - commands_in_epilogues,
4848 commands_in_prologues, commands_in_epilogues);
4851 /* Choose the order in which to allocate hard registers for
4852 pseudo-registers local to a basic block.
4854 Store the desired register order in the array `reg_alloc_order'.
4855 Element 0 should be the register to allocate first; element 1, the
4856 next register; and so on. */
4859 order_regs_for_local_alloc ()
4862 static const int order_0[] = {
4870 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4874 static const int order_1[] = {
4882 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4886 static const int order_2[] = {
4895 15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4900 const int *order = (TARGET_ORDER_1 ? order_1 :
4901 TARGET_ORDER_2 ? order_2 :
4903 for (i=0; i < ARRAY_SIZE (order_0); ++i)
4904 reg_alloc_order[i] = order[i];
4907 /* Calculate the cost of X code of the expression in which it is contained,
4908 found in OUTER_CODE */
4911 default_rtx_costs (X, code, outer_code)
4914 enum rtx_code outer_code;
4921 cost = 2 * GET_MODE_SIZE (GET_MODE (X));
4924 if (outer_code != SET)
4926 if (GET_CODE (XEXP (X,0)) == SYMBOL_REF)
4927 cost += 2 * GET_MODE_SIZE (GET_MODE (X));
4929 cost += GET_MODE_SIZE (GET_MODE (X));
4935 if (outer_code == SET)
4936 cost = GET_MODE_SIZE (GET_MODE (X));
4938 cost = -GET_MODE_SIZE (GET_MODE (X));
4941 if (outer_code == SET)
4942 cost = GET_MODE_SIZE (GET_MODE (X));
4948 if (outer_code == SET)
4950 if (X == stack_pointer_rtx)
4952 else if (GET_CODE (XEXP (X,1)) == CONST_INT)
4953 cost = (INTVAL (XEXP (X,1)) <= 63 ? 1 :
4954 GET_MODE_SIZE (GET_MODE (X)));
4956 cost = GET_MODE_SIZE (GET_MODE (X));
4960 if (GET_CODE (XEXP (X,1)) == CONST_INT)
4961 cost = GET_MODE_SIZE (GET_MODE (XEXP (X,0)));
4970 avr_rtx_costs (x, code, outer_code, total)
4972 int code, outer_code;
4980 if (outer_code == PLUS
4981 || outer_code == IOR
4982 || outer_code == AND
4983 || outer_code == MINUS
4984 || outer_code == SET
4990 if (outer_code == COMPARE
4992 && INTVAL (x) <= 255)
5007 cst = default_rtx_costs (x, code, outer_code);
5019 /* Calculate the cost of a memory address */
5022 avr_address_cost (x)
5025 if (GET_CODE (x) == PLUS
5026 && GET_CODE (XEXP (x,1)) == CONST_INT
5027 && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
5028 && INTVAL (XEXP (x,1)) >= 61)
5030 if (CONSTANT_ADDRESS_P (x))
5032 if (avr_io_address_p (x, 1))
5039 /* EXTRA_CONSTRAINT helper */
5042 extra_constraint (x, c)
5047 && GET_CODE (x) == MEM
5048 && GET_CODE (XEXP (x,0)) == PLUS)
5050 if (TARGET_ALL_DEBUG)
5052 fprintf (stderr, ("extra_constraint:\n"
5053 "reload_completed: %d\n"
5054 "reload_in_progress: %d\n"),
5055 reload_completed, reload_in_progress);
5058 if (GET_CODE (x) == MEM
5059 && GET_CODE (XEXP (x,0)) == PLUS
5060 && REG_P (XEXP (XEXP (x,0), 0))
5061 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
5062 && (INTVAL (XEXP (XEXP (x,0), 1))
5063 <= MAX_LD_OFFSET (GET_MODE (x))))
5065 rtx xx = XEXP (XEXP (x,0), 0);
5066 int regno = REGNO (xx);
5067 if (TARGET_ALL_DEBUG)
5069 fprintf (stderr, ("extra_constraint:\n"
5070 "reload_completed: %d\n"
5071 "reload_in_progress: %d\n"),
5072 reload_completed, reload_in_progress);
5075 if (regno >= FIRST_PSEUDO_REGISTER)
5076 return 1; /* allocate pseudos */
5077 else if (regno == REG_Z || regno == REG_Y)
5078 return 1; /* strictly check */
5079 else if (xx == frame_pointer_rtx
5080 || xx == arg_pointer_rtx)
5081 return 1; /* XXX frame & arg pointer checks */
5087 /* Convert condition code CONDITION to the valid AVR condition code */
5090 avr_normalize_condition (condition)
5108 /* This function optimizes conditional jumps. */
5115 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5117 if (! (GET_CODE (insn) == INSN
5118 || GET_CODE (insn) == CALL_INSN
5119 || GET_CODE (insn) == JUMP_INSN)
5120 || !single_set (insn))
5123 pattern = PATTERN (insn);
5125 if (GET_CODE (pattern) == PARALLEL)
5126 pattern = XVECEXP (pattern, 0, 0);
5127 if (GET_CODE (pattern) == SET
5128 && SET_DEST (pattern) == cc0_rtx
5129 && compare_diff_p (insn))
5131 if (GET_CODE (SET_SRC (pattern)) == COMPARE)
5133 /* Now we work under compare insn */
5135 pattern = SET_SRC (pattern);
5136 if (true_regnum (XEXP (pattern,0)) >= 0
5137 && true_regnum (XEXP (pattern,1)) >= 0 )
5139 rtx x = XEXP (pattern,0);
5140 rtx next = next_real_insn (insn);
5141 rtx pat = PATTERN (next);
5142 rtx src = SET_SRC (pat);
5143 rtx t = XEXP (src,0);
5144 PUT_CODE (t, swap_condition (GET_CODE (t)));
5145 XEXP (pattern,0) = XEXP (pattern,1);
5146 XEXP (pattern,1) = x;
5147 INSN_CODE (next) = -1;
5149 else if (true_regnum (XEXP (pattern,0)) >= 0
5150 && GET_CODE (XEXP (pattern,1)) == CONST_INT)
5152 rtx x = XEXP (pattern,1);
5153 rtx next = next_real_insn (insn);
5154 rtx pat = PATTERN (next);
5155 rtx src = SET_SRC (pat);
5156 rtx t = XEXP (src,0);
5157 enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
5159 if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
5161 XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
5162 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
5163 INSN_CODE (next) = -1;
5164 INSN_CODE (insn) = -1;
5168 else if (true_regnum (SET_SRC (pattern)) >= 0)
5170 /* This is a tst insn */
5171 rtx next = next_real_insn (insn);
5172 rtx pat = PATTERN (next);
5173 rtx src = SET_SRC (pat);
5174 rtx t = XEXP (src,0);
5176 PUT_CODE (t, swap_condition (GET_CODE (t)));
5177 SET_SRC (pattern) = gen_rtx (NEG,
5178 GET_MODE (SET_SRC (pattern)),
5180 INSN_CODE (next) = -1;
5181 INSN_CODE (insn) = -1;
5187 /* Returns register number for function return value.*/
5195 /* Ceate an RTX representing the place where a
5196 library function returns a value of mode MODE. */
5199 avr_libcall_value (mode)
5200 enum machine_mode mode;
5202 int offs = GET_MODE_SIZE (mode);
5205 return gen_rtx (REG, mode, RET_REGISTER + 2 - offs);
5208 /* Create an RTX representing the place where a
5209 function returns a value of data type VALTYPE. */
5212 avr_function_value (type, func)
5214 tree func ATTRIBUTE_UNUSED;
5218 if (TYPE_MODE (type) != BLKmode)
5219 return avr_libcall_value (TYPE_MODE (type));
5221 offs = int_size_in_bytes (type);
5224 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
5225 offs = GET_MODE_SIZE (SImode);
5226 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
5227 offs = GET_MODE_SIZE (DImode);
5229 return gen_rtx (REG, BLKmode, RET_REGISTER + 2 - offs);
5232 /* Returns nonzero if the number MASK has only one bit set. */
5235 mask_one_bit_p (mask)
5239 unsigned HOST_WIDE_INT n=mask;
5240 for (i = 0; i < 32; ++i)
5242 if (n & 0x80000000L)
5244 if (n & 0x7fffffffL)
5255 /* Places additional restrictions on the register class to
5256 use when it is necessary to copy value X into a register
5260 preferred_reload_class (x, class)
5261 rtx x ATTRIBUTE_UNUSED;
5262 enum reg_class class;
5268 test_hard_reg_class (class, x)
5269 enum reg_class class;
5272 int regno = true_regnum (x);
5276 if (TEST_HARD_REG_CLASS (class, regno))
5284 jump_over_one_insn_p (insn, dest)
5288 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
5291 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
5292 int dest_addr = INSN_ADDRESSES (uid);
5293 return dest_addr - jump_addr == get_attr_length (insn) + 1;
5296 /* Returns 1 if a value of mode MODE can be stored starting with hard
5297 register number REGNO. On the enhanced core, anything larger than
5298 1 byte must start in even numbered register for "movw" to work
5299 (this way we don't have to check for odd registers everywhere). */
5302 avr_hard_regno_mode_ok (regno, mode)
5304 enum machine_mode mode;
5306 /* Bug workaround: recog.c (peep2_find_free_register) and probably
5307 a few other places assume that the frame pointer is a single hard
5308 register, so r29 may be allocated and overwrite the high byte of
5309 the frame pointer. Do not allow any value to start in r29. */
5310 if (regno == REG_Y + 1)
5315 /* if (regno < 24 && !AVR_ENHANCED)
5317 return !(regno & 1);
5320 /* Returns 1 if X is a valid address for an I/O register of size SIZE
5321 (1 or 2). Used for lds/sts -> in/out optimization. Add 0x20 to SIZE
5322 to check for the lower half of I/O space (for cbi/sbi/sbic/sbis). */
5325 avr_io_address_p (x, size)
5329 return (optimize > 0 && GET_CODE (x) == CONST_INT
5330 && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size);
5333 /* Returns nonzero (bit number + 1) if X, or -X, is a constant power of 2. */
5336 const_int_pow2_p (x)
5339 if (GET_CODE (x) == CONST_INT)
5341 HOST_WIDE_INT d = INTVAL (x);
5342 HOST_WIDE_INT abs_d = (d >= 0) ? d : -d;
5343 return exact_log2 (abs_d) + 1;
5349 output_reload_inhi (insn, operands, len)
5350 rtx insn ATTRIBUTE_UNUSED;
5358 if (GET_CODE (operands[1]) == CONST_INT)
5360 int val = INTVAL (operands[1]);
5361 if ((val & 0xff) == 0)
5364 return (AS2 (mov,%A0,__zero_reg__) CR_TAB
5365 AS2 (ldi,%2,hi8(%1)) CR_TAB
5368 else if ((val & 0xff00) == 0)
5371 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5372 AS2 (mov,%A0,%2) CR_TAB
5373 AS2 (mov,%B0,__zero_reg__));
5375 else if ((val & 0xff) == ((val & 0xff00) >> 8))
5378 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5379 AS2 (mov,%A0,%2) CR_TAB
5384 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5385 AS2 (mov,%A0,%2) CR_TAB
5386 AS2 (ldi,%2,hi8(%1)) CR_TAB
5392 output_reload_insisf (insn, operands, len)
5393 rtx insn ATTRIBUTE_UNUSED;
5397 rtx src = operands[1];
5398 int cnst = (GET_CODE (src) == CONST_INT);
5403 *len = 4 + ((INTVAL (src) & 0xff) != 0)
5404 + ((INTVAL (src) & 0xff00) != 0)
5405 + ((INTVAL (src) & 0xff0000) != 0)
5406 + ((INTVAL (src) & 0xff000000) != 0);
5413 if (cnst && ((INTVAL (src) & 0xff) == 0))
5414 output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
5417 output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
5418 output_asm_insn (AS2 (mov, %A0, %2), operands);
5420 if (cnst && ((INTVAL (src) & 0xff00) == 0))
5421 output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
5424 output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
5425 output_asm_insn (AS2 (mov, %B0, %2), operands);
5427 if (cnst && ((INTVAL (src) & 0xff0000) == 0))
5428 output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
5431 output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
5432 output_asm_insn (AS2 (mov, %C0, %2), operands);
5434 if (cnst && ((INTVAL (src) & 0xff000000) == 0))
5435 output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
5438 output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
5439 output_asm_insn (AS2 (mov, %D0, %2), operands);
5445 avr_output_bld (operands, bit_nr)
5449 static char s[] = "bld %A0,0";
5451 s[5] = 'A' + (bit_nr >> 3);
5452 s[8] = '0' + (bit_nr & 7);
5453 output_asm_insn (s, operands);
5457 avr_output_addr_vec_elt (stream, value)
5462 fprintf (stream, "\t.word pm(.L%d)\n", value);
5464 fprintf (stream, "\trjmp .L%d\n", value);
5469 /* Returns 1 if SCRATCH are safe to be allocated as a scratch
5470 registers (for a define_peephole2) in the current function. */
5473 avr_peep2_scratch_safe (scratch)
5476 if ((interrupt_function_p (current_function_decl)
5477 || signal_function_p (current_function_decl))
5478 && leaf_function_p ())
5480 int first_reg = true_regnum (scratch);
5481 int last_reg = first_reg + GET_MODE_SIZE (GET_MODE (scratch)) - 1;
5484 for (reg = first_reg; reg <= last_reg; reg++)
5486 if (!regs_ever_live[reg])
5493 /* Output a branch that tests a single bit of a register (QI, HI or SImode)
5494 or memory location in the I/O space (QImode only).
5496 Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
5497 Operand 1: register operand to test, or CONST_INT memory address.
5498 Operand 2: bit number (for QImode operand) or mask (HImode, SImode).
5499 Operand 3: label to jump to if the test is true. */
5502 avr_out_sbxx_branch (insn, operands)
5506 enum rtx_code comp = GET_CODE (operands[0]);
5507 int long_jump = (get_attr_length (insn) >= 4);
5508 int reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
5512 else if (comp == LT)
5516 comp = reverse_condition (comp);
5518 if (GET_CODE (operands[1]) == CONST_INT)
5520 if (INTVAL (operands[1]) < 0x40)
5523 output_asm_insn (AS2 (sbis,%1-0x20,%2), operands);
5525 output_asm_insn (AS2 (sbic,%1-0x20,%2), operands);
5529 output_asm_insn (AS2 (in,__tmp_reg__,%1-0x20), operands);
5531 output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands);
5533 output_asm_insn (AS2 (sbrc,__tmp_reg__,%2), operands);
5536 else /* GET_CODE (operands[1]) == REG */
5538 if (GET_MODE (operands[1]) == QImode)
5541 output_asm_insn (AS2 (sbrs,%1,%2), operands);
5543 output_asm_insn (AS2 (sbrc,%1,%2), operands);
5545 else /* HImode or SImode */
5547 static char buf[] = "sbrc %A1,0";
5548 int bit_nr = exact_log2 (INTVAL (operands[2])
5549 & GET_MODE_MASK (GET_MODE (operands[1])));
5551 buf[3] = (comp == EQ) ? 's' : 'c';
5552 buf[6] = 'A' + (bit_nr >> 3);
5553 buf[9] = '0' + (bit_nr & 7);
5554 output_asm_insn (buf, operands);
5559 return (AS1 (rjmp,.+4) CR_TAB
5562 return AS1 (rjmp,%3);
5567 avr_asm_out_ctor (symbol, priority)
5571 fputs ("\t.global __do_global_ctors\n", asm_out_file);
5572 default_ctor_section_asm_out_constructor (symbol, priority);
5576 avr_asm_out_dtor (symbol, priority)
5580 fputs ("\t.global __do_global_dtors\n", asm_out_file);
5581 default_dtor_section_asm_out_destructor (symbol, priority);