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. */
26 #include "hard-reg-set.h"
28 #include "insn-config.h"
29 #include "conditions.h"
31 #include "insn-attr.h"
42 #include "target-def.h"
44 /* Maximal allowed offset for an address in the LD command */
45 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
47 static int avr_naked_function_p PARAMS ((tree));
48 static int interrupt_function_p PARAMS ((tree));
49 static int signal_function_p PARAMS ((tree));
50 static int avr_regs_to_save PARAMS ((HARD_REG_SET *));
51 static int sequent_regs_live PARAMS ((void));
52 static const char * ptrreg_to_str PARAMS ((int));
53 static const char * cond_string PARAMS ((enum rtx_code));
54 static int avr_num_arg_regs PARAMS ((enum machine_mode, tree));
55 static int out_adj_frame_ptr PARAMS ((FILE *, int));
56 static int out_set_stack_ptr PARAMS ((FILE *, int, int));
57 static RTX_CODE compare_condition PARAMS ((rtx insn));
58 static int compare_sign_p PARAMS ((rtx insn));
59 static int reg_was_0 PARAMS ((rtx insn, rtx op));
60 void debug_hard_reg_set PARAMS ((HARD_REG_SET set));
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_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
66 static void avr_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
67 static void avr_unique_section PARAMS ((tree, int));
68 static void avr_encode_section_info PARAMS ((tree, int));
70 static void avr_asm_out_ctor PARAMS ((rtx, int));
71 static void avr_asm_out_dtor PARAMS ((rtx, int));
73 /* Allocate registers from r25 to r8 for parameters for function calls */
74 #define FIRST_CUM_REG 26
76 /* Temporary register RTX (gen_rtx (REG,QImode,TMP_REGNO)) */
79 /* Zeroed register RTX (gen_rtx (REG,QImode,ZERO_REGNO)) */
82 /* RTX for register which will be used for loading immediate values to
86 /* AVR register names {"r0", "r1", ..., "r31"} */
87 static const char *const avr_regnames[] = REGISTER_NAMES;
89 /* This holds the last insn address. */
90 static int last_insn_address = 0;
92 /* Commands count in the compiled file */
93 static int commands_in_file;
95 /* Commands in the functions prologues in the compiled file */
96 static int commands_in_prologues;
98 /* Commands in the functions epilogues in the compiled file */
99 static int commands_in_epilogues;
101 /* Prologue/Epilogue size in words */
102 static int prologue_size;
103 static int epilogue_size;
105 /* Size of all jump tables in the current function, in words. */
106 static int jump_tables_size;
108 /* Initial stack value specified by the `-minit-stack=' option */
109 const char *avr_init_stack = "__stack";
111 /* Default MCU name */
112 const char *avr_mcu_name = "avr2";
114 /* Preprocessor macros to define depending on MCU type. */
115 const char *avr_base_arch_macro;
116 const char *avr_extra_arch_macro;
118 /* More than 8K of program memory: use "call" and "jmp". */
121 /* Enhanced core: use "movw", "mul", ... */
122 int avr_enhanced_p = 0;
124 /* Assembler only. */
125 int avr_asm_only_p = 0;
131 const char *const macro;
134 static const struct base_arch_s avr_arch_types[] = {
135 { 1, 0, 0, NULL }, /* unknown device specified */
136 { 1, 0, 0, "__AVR_ARCH__=1" },
137 { 0, 0, 0, "__AVR_ARCH__=2" },
138 { 0, 0, 1, "__AVR_ARCH__=3" },
139 { 0, 1, 0, "__AVR_ARCH__=4" },
140 { 0, 1, 1, "__AVR_ARCH__=5" }
144 const char *const name;
145 int arch; /* index in avr_arch_types[] */
146 /* Must lie outside user's namespace. NULL == no macro. */
147 const char *const macro;
150 /* List of all known AVR MCU types - if updated, it has to be kept
151 in sync in several places (FIXME: is there a better way?):
153 - avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
154 - t-avr (MULTILIB_MATCHES)
155 - gas/config/tc-avr.c
158 static const struct mcu_type_s avr_mcu_types[] = {
159 /* Classic, <= 8K. */
161 { "at90s2313", 2, "__AVR_AT90S2313__" },
162 { "at90s2323", 2, "__AVR_AT90S2323__" },
163 { "at90s2333", 2, "__AVR_AT90S2333__" },
164 { "at90s2343", 2, "__AVR_AT90S2343__" },
165 { "attiny22", 2, "__AVR_ATtiny22__" },
166 { "attiny26", 2, "__AVR_ATtiny26__" },
167 { "at90s4414", 2, "__AVR_AT90S4414__" },
168 { "at90s4433", 2, "__AVR_AT90S4433__" },
169 { "at90s4434", 2, "__AVR_AT90S4434__" },
170 { "at90s8515", 2, "__AVR_AT90S8515__" },
171 { "at90c8534", 2, "__AVR_AT90C8534__" },
172 { "at90s8535", 2, "__AVR_AT90S8535__" },
175 { "atmega103", 3, "__AVR_ATmega103__" },
176 { "atmega603", 3, "__AVR_ATmega603__" },
177 { "at43usb320", 3, "__AVR_AT43USB320__" },
178 { "at43usb355", 3, "__AVR_AT43USB355__" },
179 { "at76c711", 3, "__AVR_AT76C711__" },
180 /* Enhanced, <= 8K. */
182 { "atmega8", 4, "__AVR_ATmega8__" },
183 { "atmega8515", 4, "__AVR_ATmega8515__" },
184 /* Enhanced, > 8K. */
186 { "atmega16", 5, "__AVR_ATmega16__" },
187 { "atmega161", 5, "__AVR_ATmega161__" },
188 { "atmega162", 5, "__AVR_ATmega162__" },
189 { "atmega163", 5, "__AVR_ATmega163__" },
190 { "atmega32", 5, "__AVR_ATmega32__" },
191 { "atmega323", 5, "__AVR_ATmega323__" },
192 { "atmega64", 5, "__AVR_ATmega64__" },
193 { "atmega128", 5, "__AVR_ATmega128__" },
194 { "at94k", 5, "__AVR_AT94K__" },
195 /* Assembler only. */
197 { "at90s1200", 1, "__AVR_AT90S1200__" },
198 { "attiny11", 1, "__AVR_ATtiny11__" },
199 { "attiny12", 1, "__AVR_ATtiny12__" },
200 { "attiny15", 1, "__AVR_ATtiny15__" },
201 { "attiny28", 1, "__AVR_ATtiny28__" },
205 int avr_case_values_threshold = 30000;
207 /* Initialize the GCC target structure. */
208 #undef TARGET_ASM_ALIGNED_HI_OP
209 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
210 #undef TARGET_ASM_INTEGER
211 #define TARGET_ASM_INTEGER avr_assemble_integer
213 #undef TARGET_ASM_FUNCTION_PROLOGUE
214 #define TARGET_ASM_FUNCTION_PROLOGUE avr_output_function_prologue
215 #undef TARGET_ASM_FUNCTION_EPILOGUE
216 #define TARGET_ASM_FUNCTION_EPILOGUE avr_output_function_epilogue
217 #undef TARGET_ATTRIBUTE_TABLE
218 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
219 #undef TARGET_ASM_UNIQUE_SECTION
220 #define TARGET_ASM_UNIQUE_SECTION avr_unique_section
221 #undef TARGET_ENCODE_SECTION_INFO
222 #define TARGET_ENCODE_SECTION_INFO avr_encode_section_info
224 struct gcc_target targetm = TARGET_INITIALIZER;
227 avr_override_options ()
229 const struct mcu_type_s *t;
230 const struct base_arch_s *base;
232 for (t = avr_mcu_types; t->name; t++)
233 if (strcmp (t->name, avr_mcu_name) == 0)
238 fprintf (stderr, "unknown MCU `%s' specified\nKnown MCU names:\n",
240 for (t = avr_mcu_types; t->name; t++)
241 fprintf (stderr," %s\n", t->name);
244 base = &avr_arch_types[t->arch];
245 avr_asm_only_p = base->asm_only;
246 avr_enhanced_p = base->enhanced;
247 avr_mega_p = base->mega;
248 avr_base_arch_macro = base->macro;
249 avr_extra_arch_macro = t->macro;
251 if (optimize && !TARGET_NO_TABLEJUMP)
252 avr_case_values_threshold = (!AVR_MEGA || TARGET_CALL_PROLOGUES) ? 8 : 17;
256 /* Initialize TMP_REG_RTX and ZERO_REG_RTX */
260 tmp_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
261 memset (tmp_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
262 PUT_CODE (tmp_reg_rtx, REG);
263 PUT_MODE (tmp_reg_rtx, QImode);
264 XINT (tmp_reg_rtx, 0) = TMP_REGNO;
266 zero_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
267 memset (zero_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
268 PUT_CODE (zero_reg_rtx, REG);
269 PUT_MODE (zero_reg_rtx, QImode);
270 XINT (zero_reg_rtx, 0) = ZERO_REGNO;
272 ldi_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
273 memset (ldi_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
274 PUT_CODE (ldi_reg_rtx, REG);
275 PUT_MODE (ldi_reg_rtx, QImode);
276 XINT (ldi_reg_rtx, 0) = LDI_REG_REGNO;
279 /* return register class from register number */
281 static const int reg_class_tab[]={
282 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
283 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
284 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
285 GENERAL_REGS, /* r0 - r15 */
286 LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
287 LD_REGS, /* r16 - 23 */
288 ADDW_REGS,ADDW_REGS, /* r24,r25 */
289 POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
290 POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
291 POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
292 STACK_REG,STACK_REG /* SPL,SPH */
295 /* Return register class for register R */
298 avr_regno_reg_class (r)
302 return reg_class_tab[r];
307 /* A C expression which defines the machine-dependent operand
308 constraint letters for register classes. If C is such a
309 letter, the value should be the register class corresponding to
310 it. Otherwise, the value should be `NO_REGS'. The register
311 letter `r', corresponding to class `GENERAL_REGS', will not be
312 passed to this macro; you do not need to handle it. */
315 avr_reg_class_from_letter (c)
320 case 't' : return R0_REG;
321 case 'b' : return BASE_POINTER_REGS;
322 case 'e' : return POINTER_REGS;
323 case 'w' : return ADDW_REGS;
324 case 'd' : return LD_REGS;
325 case 'l' : return NO_LD_REGS;
326 case 'a' : return SIMPLE_LD_REGS;
327 case 'x' : return POINTER_X_REGS;
328 case 'y' : return POINTER_Y_REGS;
329 case 'z' : return POINTER_Z_REGS;
330 case 'q' : return STACK_REG;
336 /* Return non-zero if FUNC is a naked function. */
339 avr_naked_function_p (func)
344 if (TREE_CODE (func) != FUNCTION_DECL)
347 a = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
348 return a != NULL_TREE;
351 /* Return nonzero if FUNC is an interrupt function as specified
352 by the "interrupt" attribute. */
355 interrupt_function_p (func)
360 if (TREE_CODE (func) != FUNCTION_DECL)
363 a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
364 return a != NULL_TREE;
367 /* Return nonzero if FUNC is a signal function as specified
368 by the "signal" attribute. */
371 signal_function_p (func)
376 if (TREE_CODE (func) != FUNCTION_DECL)
379 a = lookup_attribute ("signal", DECL_ATTRIBUTES (func));
380 return a != NULL_TREE;
383 /* Return the number of hard registers to push/pop in the prologue/epilogue
384 of the current function, and optionally store these registers in SET. */
387 avr_regs_to_save (set)
391 int int_or_sig_p = (interrupt_function_p (current_function_decl)
392 || signal_function_p (current_function_decl));
393 int leaf_func_p = leaf_function_p ();
396 CLEAR_HARD_REG_SET (*set);
398 for (reg = 0; reg < 32; reg++)
400 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
401 any global register variables. */
405 if ((int_or_sig_p && !leaf_func_p && call_used_regs[reg])
406 || (regs_ever_live[reg]
407 && (int_or_sig_p || !call_used_regs[reg])
408 && !(frame_pointer_needed
409 && (reg == REG_Y || reg == (REG_Y+1)))))
412 SET_HARD_REG_BIT (*set, reg);
419 /* Compute offset between arg_pointer and frame_pointer */
422 initial_elimination_offset (from, to)
426 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
430 int offset = frame_pointer_needed ? 2 : 0;
432 offset += avr_regs_to_save (NULL);
433 return get_frame_size () + 2 + 1 + offset;
437 /* This function checks sequence of live registers */
446 for (reg = 0; reg < 18; ++reg)
448 if (!call_used_regs[reg])
450 if (regs_ever_live[reg])
460 if (!frame_pointer_needed)
462 if (regs_ever_live[REG_Y])
470 if (regs_ever_live[REG_Y+1])
483 return (cur_seq == live_seq) ? live_seq : 0;
487 /* Output to FILE the asm instructions to adjust the frame pointer by
488 ADJ (r29:r28 -= ADJ;) which can be positive (prologue) or negative
489 (epilogue). Returns the number of instructions generated. */
492 out_adj_frame_ptr (file, adj)
500 if (TARGET_TINY_STACK)
502 if (adj < -63 || adj > 63)
503 warning ("large frame pointer change (%d) with -mtiny-stack", adj);
505 /* The high byte (r29) doesn't change - prefer "subi" (1 cycle)
506 over "sbiw" (2 cycles, same size). */
508 fprintf (file, (AS2 (subi, r28, %d) CR_TAB), adj);
511 else if (adj < -63 || adj > 63)
513 fprintf (file, (AS2 (subi, r28, lo8(%d)) CR_TAB
514 AS2 (sbci, r29, hi8(%d)) CR_TAB),
520 fprintf (file, (AS2 (adiw, r28, %d) CR_TAB), -adj);
525 fprintf (file, (AS2 (sbiw, r28, %d) CR_TAB), adj);
533 /* Output to FILE the asm instructions to copy r29:r28 to SPH:SPL,
534 handling various cases of interrupt enable flag state BEFORE and AFTER
535 (0=disabled, 1=enabled, -1=unknown/unchanged) and target_flags.
536 Returns the number of instructions generated. */
539 out_set_stack_ptr (file, before, after)
544 int do_sph, do_cli, do_save, do_sei, lock_sph, size;
546 /* The logic here is so that -mno-interrupts actually means
547 "it is safe to write SPH in one instruction, then SPL in the
548 next instruction, without disabling interrupts first".
549 The after != -1 case (interrupt/signal) is not affected. */
551 do_sph = !TARGET_TINY_STACK;
552 lock_sph = do_sph && !TARGET_NO_INTERRUPTS;
553 do_cli = (before != 0 && (after == 0 || lock_sph));
554 do_save = (do_cli && before == -1 && after == -1);
555 do_sei = ((do_cli || before != 1) && after == 1);
560 fprintf (file, AS2 (in, __tmp_reg__, __SREG__) CR_TAB);
566 fprintf (file, "cli" CR_TAB);
570 /* Do SPH first - maybe this will disable interrupts for one instruction
571 someday (a suggestion has been sent to avr@atmel.com for consideration
572 in future devices - that would make -mno-interrupts always safe). */
575 fprintf (file, AS2 (out, __SP_H__, r29) CR_TAB);
579 /* Set/restore the I flag now - interrupts will be really enabled only
580 after the next instruction. This is not clearly documented, but
581 believed to be true for all AVR devices. */
584 fprintf (file, AS2 (out, __SREG__, __tmp_reg__) CR_TAB);
589 fprintf (file, "sei" CR_TAB);
593 fprintf (file, AS2 (out, __SP_L__, r28) "\n");
599 /* Output function prologue */
602 avr_output_function_prologue (file, size)
607 int interrupt_func_p;
613 if (avr_naked_function_p (current_function_decl))
615 fprintf (file, "/* prologue: naked */\n");
619 interrupt_func_p = interrupt_function_p (current_function_decl);
620 signal_func_p = signal_function_p (current_function_decl);
621 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
622 live_seq = sequent_regs_live ();
623 minimize = (TARGET_CALL_PROLOGUES
624 && !interrupt_func_p && !signal_func_p && live_seq);
626 last_insn_address = 0;
627 jump_tables_size = 0;
629 fprintf (file, "/* prologue: frame size=%d */\n", size);
631 if (interrupt_func_p)
633 fprintf (file,"\tsei\n");
636 if (interrupt_func_p || signal_func_p)
639 AS1 (push,__zero_reg__) CR_TAB
640 AS1 (push,__tmp_reg__) CR_TAB
641 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
642 AS1 (push,__tmp_reg__) CR_TAB
643 AS1 (clr,__zero_reg__) "\n");
649 AS2 (ldi,r28,lo8(%s - %d)) CR_TAB
650 AS2 (ldi,r29,hi8(%s - %d)) CR_TAB
651 AS2 (out,__SP_H__,r29) CR_TAB
652 AS2 (out,__SP_L__,r28) "\n"),
653 avr_init_stack, size, avr_init_stack, size);
657 else if (minimize && (frame_pointer_needed || live_seq > 6))
660 AS2 (ldi, r26, lo8(%d)) CR_TAB
661 AS2 (ldi, r27, hi8(%d)) CR_TAB), size, size);
663 fprintf (file, (AS2 (ldi, r30, pm_lo8(.L_%s_body)) CR_TAB
664 AS2 (ldi, r31, pm_hi8(.L_%s_body)) CR_TAB)
665 ,current_function_name, current_function_name);
671 fprintf (file, AS1 (jmp,__prologue_saves__+%d) "\n",
672 (18 - live_seq) * 2);
677 fprintf (file, AS1 (rjmp,__prologue_saves__+%d) "\n",
678 (18 - live_seq) * 2);
681 fprintf (file, ".L_%s_body:\n", current_function_name);
687 prologue_size += avr_regs_to_save (&set);
688 for (reg = 0; reg < 32; ++reg)
690 if (TEST_HARD_REG_BIT (set, reg))
692 fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
695 if (frame_pointer_needed)
699 AS1 (push,r28) CR_TAB
700 AS1 (push,r29) CR_TAB
701 AS2 (in,r28,__SP_L__) CR_TAB
702 AS2 (in,r29,__SP_H__) "\n");
707 prologue_size += out_adj_frame_ptr (file, size);
709 if (interrupt_func_p)
711 prologue_size += out_set_stack_ptr (file, 1, 1);
713 else if (signal_func_p)
715 prologue_size += out_set_stack_ptr (file, 0, 0);
719 prologue_size += out_set_stack_ptr (file, -1, -1);
725 fprintf (file, "/* prologue end (size=%d) */\n", prologue_size);
728 /* Output function epilogue */
731 avr_output_function_epilogue (file, size)
736 int interrupt_func_p;
743 if (avr_naked_function_p (current_function_decl))
745 fprintf (file, "/* epilogue: naked */\n");
749 interrupt_func_p = interrupt_function_p (current_function_decl);
750 signal_func_p = signal_function_p (current_function_decl);
751 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
752 function_size = (INSN_ADDRESSES (INSN_UID (get_last_nonnote_insn ()))
753 - INSN_ADDRESSES (INSN_UID (get_first_nonnote_insn ())));
754 function_size += jump_tables_size;
755 live_seq = sequent_regs_live ();
756 minimize = (TARGET_CALL_PROLOGUES
757 && !interrupt_func_p && !signal_func_p && live_seq);
760 fprintf (file, "/* epilogue: frame size=%d */\n", size);
763 /* Return value from main() is already in the correct registers
764 (r25:r24) as the exit() argument. */
767 fputs ("\t" AS1 (jmp,exit) "\n", file);
772 fputs ("\t" AS1 (rjmp,exit) "\n", file);
776 else if (minimize && (frame_pointer_needed || live_seq > 4))
778 fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
780 if (frame_pointer_needed)
782 epilogue_size += out_adj_frame_ptr (file, -size);
786 fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
787 AS2 (in , r29, __SP_H__) CR_TAB));
793 fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
794 (18 - live_seq) * 2);
799 fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
800 (18 - live_seq) * 2);
808 if (frame_pointer_needed)
813 epilogue_size += out_adj_frame_ptr (file, -size);
815 if (interrupt_func_p || signal_func_p)
817 epilogue_size += out_set_stack_ptr (file, -1, 0);
821 epilogue_size += out_set_stack_ptr (file, -1, -1);
830 epilogue_size += avr_regs_to_save (&set);
831 for (reg = 31; reg >= 0; --reg)
833 if (TEST_HARD_REG_BIT (set, reg))
835 fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
839 if (interrupt_func_p || signal_func_p)
842 AS1 (pop,__tmp_reg__) CR_TAB
843 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
844 AS1 (pop,__tmp_reg__) CR_TAB
845 AS1 (pop,__zero_reg__) "\n");
847 fprintf (file, "\treti\n");
850 fprintf (file, "\tret\n");
854 fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
855 fprintf (file, "/* function %s size %d (%d) */\n", current_function_name,
856 prologue_size + function_size + epilogue_size, function_size);
857 commands_in_file += prologue_size + function_size + epilogue_size;
858 commands_in_prologues += prologue_size;
859 commands_in_epilogues += epilogue_size;
863 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
864 machine for a memory operand of mode MODE. */
867 legitimate_address_p (mode, x, strict)
868 enum machine_mode mode;
872 enum reg_class r = NO_REGS;
874 if (TARGET_ALL_DEBUG)
876 fprintf (stderr, "mode: (%s) %s %s %s %s:",
878 strict ? "(strict)": "",
879 reload_completed ? "(reload_completed)": "",
880 reload_in_progress ? "(reload_in_progress)": "",
881 reg_renumber ? "(reg_renumber)" : "");
882 if (GET_CODE (x) == PLUS
883 && REG_P (XEXP (x, 0))
884 && GET_CODE (XEXP (x, 1)) == CONST_INT
885 && INTVAL (XEXP (x, 1)) >= 0
886 && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
889 fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
890 true_regnum (XEXP (x, 0)));
893 if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
894 : REG_OK_FOR_BASE_NOSTRICT_P (x)))
896 else if (CONSTANT_ADDRESS_P (x))
898 else if (GET_CODE (x) == PLUS
899 && REG_P (XEXP (x, 0))
900 && GET_CODE (XEXP (x, 1)) == CONST_INT
901 && INTVAL (XEXP (x, 1)) >= 0)
903 int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
907 || REGNO (XEXP (x,0)) == REG_Y
908 || REGNO (XEXP (x,0)) == REG_Z)
909 r = BASE_POINTER_REGS;
910 if (XEXP (x,0) == frame_pointer_rtx
911 || XEXP (x,0) == arg_pointer_rtx)
912 r = BASE_POINTER_REGS;
914 else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
917 else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
918 && REG_P (XEXP (x, 0))
919 && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
920 : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
924 if (TARGET_ALL_DEBUG)
926 fprintf (stderr, " ret = %c\n", r);
928 return r == NO_REGS ? 0 : (int)r;
931 /* Attempts to replace X with a valid
932 memory address for an operand of mode MODE */
935 legitimize_address (x, oldx, mode)
938 enum machine_mode mode;
941 if (TARGET_ALL_DEBUG)
943 fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
947 if (GET_CODE (oldx) == PLUS
948 && REG_P (XEXP (oldx,0)))
950 if (REG_P (XEXP (oldx,1)))
951 x = force_reg (GET_MODE (oldx), oldx);
952 else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
954 int offs = INTVAL (XEXP (oldx,1));
955 if (frame_pointer_rtx != XEXP (oldx,0))
956 if (offs > MAX_LD_OFFSET (mode))
958 if (TARGET_ALL_DEBUG)
959 fprintf (stderr, "force_reg (big offset)\n");
960 x = force_reg (GET_MODE (oldx), oldx);
968 /* Return a pointer register name as a string */
971 ptrreg_to_str (regno)
976 case REG_X: return "X";
977 case REG_Y: return "Y";
978 case REG_Z: return "Z";
985 /* Return the condition name as a string.
986 Used in conditional jump constructing */
999 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1004 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1017 /* Output ADDR to FILE as address */
1020 print_operand_address (file, addr)
1024 switch (GET_CODE (addr))
1027 fprintf (file, ptrreg_to_str (REGNO (addr)));
1031 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1035 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1039 if (CONSTANT_ADDRESS_P (addr)
1040 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
1041 || GET_CODE (addr) == LABEL_REF))
1043 fprintf (file, "pm(");
1044 output_addr_const (file,addr);
1045 fprintf (file ,")");
1048 output_addr_const (file, addr);
1053 /* Output X as assembler operand to file FILE */
1056 print_operand (file, x, code)
1063 if (code >= 'A' && code <= 'D')
1073 if (x == zero_reg_rtx)
1074 fprintf (file, "__zero_reg__");
1076 fprintf (file, reg_names[true_regnum (x) + abcd]);
1078 else if (GET_CODE (x) == CONST_INT)
1079 fprintf (file, "%d", INTVAL (x) + abcd);
1080 else if (GET_CODE (x) == MEM)
1082 rtx addr = XEXP (x,0);
1084 if (CONSTANT_P (addr) && abcd)
1087 output_address (addr);
1088 fprintf (file, ")+%d", abcd);
1090 else if (code == 'o')
1092 if (GET_CODE (addr) != PLUS)
1093 fatal_insn ("bad address, not (reg+disp):", addr);
1095 print_operand (file, XEXP (addr, 1), 0);
1097 else if (GET_CODE (addr) == PLUS)
1099 print_operand_address (file, XEXP (addr,0));
1100 if (REGNO (XEXP (addr, 0)) == REG_X)
1101 fatal_insn ("internal compiler error. Bad address:"
1104 print_operand (file, XEXP (addr,1), code);
1107 print_operand_address (file, addr);
1109 else if (GET_CODE (x) == CONST_DOUBLE)
1113 if (GET_MODE (x) != SFmode)
1114 fatal_insn ("internal compiler error. Unknown mode:", x);
1115 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1116 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1117 asm_fprintf (file, "0x%lx", val);
1119 else if (code == 'j')
1120 asm_fprintf (file, cond_string (GET_CODE (x)));
1121 else if (code == 'k')
1122 asm_fprintf (file, cond_string (reverse_condition (GET_CODE (x))));
1124 print_operand_address (file, x);
1127 /* Recognize operand OP of mode MODE used in call instructions */
1130 call_insn_operand (op, mode)
1132 enum machine_mode mode ATTRIBUTE_UNUSED;
1134 if (GET_CODE (op) == MEM)
1136 rtx inside = XEXP (op, 0);
1137 if (register_operand (inside, Pmode))
1139 if (CONSTANT_ADDRESS_P (inside))
1145 /* Update the condition code in the INSN. */
1148 notice_update_cc (body, insn)
1149 rtx body ATTRIBUTE_UNUSED;
1154 switch (get_attr_cc (insn))
1157 /* Insn does not affect CC at all. */
1165 set = single_set (insn);
1169 cc_status.flags |= CC_NO_OVERFLOW;
1170 cc_status.value1 = SET_DEST (set);
1175 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1176 The V flag may or may not be known but that's ok because
1177 alter_cond will change tests to use EQ/NE. */
1178 set = single_set (insn);
1182 cc_status.value1 = SET_DEST (set);
1183 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1188 set = single_set (insn);
1191 cc_status.value1 = SET_SRC (set);
1195 /* Insn doesn't leave CC in a usable state. */
1198 /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1199 set = single_set (insn);
1202 rtx src = SET_SRC (set);
1204 if (GET_CODE (src) == ASHIFTRT
1205 && GET_MODE (src) == QImode)
1207 rtx x = XEXP (src, 1);
1209 if (GET_CODE (x) == CONST_INT
1212 cc_status.value1 = SET_DEST (set);
1213 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1221 /* Return maximum number of consecutive registers of
1222 class CLASS needed to hold a value of mode MODE. */
1225 class_max_nregs (class, mode)
1226 enum reg_class class ATTRIBUTE_UNUSED;
1227 enum machine_mode mode;
1229 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1232 /* Choose mode for jump insn:
1233 1 - relative jump in range -63 <= x <= 62 ;
1234 2 - relative jump in range -2046 <= x <= 2045 ;
1235 3 - absolute jump (only for ATmega[16]03). */
1238 avr_jump_mode (x, insn)
1239 rtx x; /* jump operand */
1240 rtx insn; /* jump insn */
1242 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1243 ? XEXP (x, 0) : x));
1244 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1245 int jump_distance = cur_addr - dest_addr;
1247 if (-63 <= jump_distance && jump_distance <= 62)
1249 else if (-2046 <= jump_distance && jump_distance <= 2045)
1257 /* return an AVR condition jump commands.
1258 X is a comparison RTX.
1259 LEN is a number returned by avr_jump_mode function.
1260 if REVERSE nonzero then condition code in X must be reversed. */
1263 ret_cond_branch (x, len, reverse)
1268 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1273 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1274 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1276 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1277 AS1 (brmi,_PC_+2) CR_TAB
1279 (AS1 (breq,_PC_+6) CR_TAB
1280 AS1 (brmi,_PC_+4) CR_TAB
1284 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1286 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1287 AS1 (brlt,_PC_+2) CR_TAB
1289 (AS1 (breq,_PC_+6) CR_TAB
1290 AS1 (brlt,_PC_+4) CR_TAB
1293 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1295 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1296 AS1 (brlo,_PC_+2) CR_TAB
1298 (AS1 (breq,_PC_+6) CR_TAB
1299 AS1 (brlo,_PC_+4) CR_TAB
1302 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1303 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1305 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1306 AS1 (brpl,_PC_+2) CR_TAB
1308 (AS1 (breq,_PC_+2) CR_TAB
1309 AS1 (brpl,_PC_+4) CR_TAB
1312 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1314 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1315 AS1 (brge,_PC_+2) CR_TAB
1317 (AS1 (breq,_PC_+2) CR_TAB
1318 AS1 (brge,_PC_+4) CR_TAB
1321 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1323 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1324 AS1 (brsh,_PC_+2) CR_TAB
1326 (AS1 (breq,_PC_+2) CR_TAB
1327 AS1 (brsh,_PC_+4) CR_TAB
1335 return AS1 (br%k1,%0);
1337 return (AS1 (br%j1,_PC_+2) CR_TAB
1340 return (AS1 (br%j1,_PC_+4) CR_TAB
1349 return AS1 (br%j1,%0);
1351 return (AS1 (br%k1,_PC_+2) CR_TAB
1354 return (AS1 (br%k1,_PC_+4) CR_TAB
1362 /* Predicate function for immediate operand which fits to byte (8bit) */
1365 byte_immediate_operand (op, mode)
1367 enum machine_mode mode ATTRIBUTE_UNUSED;
1369 return (GET_CODE (op) == CONST_INT
1370 && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1373 /* Output all insn addresses and their sizes into the assembly language
1374 output file. This is helpful for debugging whether the length attributes
1375 in the md file are correct.
1376 Output insn cost for next insn. */
1379 final_prescan_insn (insn, operand, num_operands)
1380 rtx insn, *operand ATTRIBUTE_UNUSED;
1381 int num_operands ATTRIBUTE_UNUSED;
1383 int uid = INSN_UID (insn);
1385 if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1387 fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1388 INSN_ADDRESSES (uid),
1389 INSN_ADDRESSES (uid) - last_insn_address,
1390 rtx_cost (PATTERN (insn), INSN));
1392 last_insn_address = INSN_ADDRESSES (uid);
1394 if (TARGET_RTL_DUMP)
1396 fprintf (asm_out_file, "/*****************\n");
1397 print_rtl_single (asm_out_file, insn);
1398 fprintf (asm_out_file, "*****************/\n");
1402 /* Return 0 if undefined, 1 if always true or always false. */
1405 avr_simplify_comparision_p (mode, operator, x)
1406 enum machine_mode mode;
1410 unsigned int max = (mode == QImode ? 0xff :
1411 mode == HImode ? 0xffff :
1412 mode == SImode ? 0xffffffff : 0);
1413 if (max && operator && GET_CODE (x) == CONST_INT)
1415 if (unsigned_condition (operator) != operator)
1418 if (max != (INTVAL (x) & max)
1419 && INTVAL (x) != 0xff)
1426 /* Returns nonzero if REGNO is the number of a hard
1427 register in which function arguments are sometimes passed. */
1430 function_arg_regno_p(r)
1433 return (r >= 8 && r <= 25);
1436 /* Initializing the variable cum for the state at the beginning
1437 of the argument list. */
1440 init_cumulative_args (cum, fntype, libname, indirect)
1441 CUMULATIVE_ARGS *cum;
1444 int indirect ATTRIBUTE_UNUSED;
1447 cum->regno = FIRST_CUM_REG;
1450 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1451 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1452 != void_type_node));
1458 /* Returns the number of registers to allocate for a function argument. */
1461 avr_num_arg_regs (mode, type)
1462 enum machine_mode mode;
1467 if (mode == BLKmode)
1468 size = int_size_in_bytes (type);
1470 size = GET_MODE_SIZE (mode);
1472 /* Align all function arguments to start in even-numbered registers.
1473 Odd-sized arguments leave holes above them. */
1475 return (size + 1) & ~1;
1478 /* Controls whether a function argument is passed
1479 in a register, and which register. */
1482 function_arg (cum, mode, type, named)
1483 CUMULATIVE_ARGS *cum;
1484 enum machine_mode mode;
1486 int named ATTRIBUTE_UNUSED;
1488 int bytes = avr_num_arg_regs (mode, type);
1490 if (cum->nregs && bytes <= cum->nregs)
1491 return gen_rtx (REG, mode, cum->regno - bytes);
1496 /* Update the summarizer variable CUM to advance past an argument
1497 in the argument list. */
1500 function_arg_advance (cum, mode, type, named)
1501 CUMULATIVE_ARGS *cum; /* current arg information */
1502 enum machine_mode mode; /* current arg mode */
1503 tree type; /* type of the argument or 0 if lib support */
1504 int named ATTRIBUTE_UNUSED; /* whether or not the argument was named */
1506 int bytes = avr_num_arg_regs (mode, type);
1508 cum->nregs -= bytes;
1509 cum->regno -= bytes;
1511 if (cum->nregs <= 0)
1514 cum->regno = FIRST_CUM_REG;
1518 /***********************************************************************
1519 Functions for outputting various mov's for a various modes
1520 ************************************************************************/
1522 output_movqi (insn, operands, l)
1528 rtx dest = operands[0];
1529 rtx src = operands[1];
1537 if (register_operand (dest, QImode))
1539 if (register_operand (src, QImode)) /* mov r,r */
1541 if (test_hard_reg_class (STACK_REG, dest))
1542 return AS2 (out,%0,%1);
1543 else if (test_hard_reg_class (STACK_REG, src))
1544 return AS2 (in,%0,%1);
1546 return AS2 (mov,%0,%1);
1548 else if (CONSTANT_P (src))
1550 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1551 return AS2 (ldi,%0,lo8(%1));
1553 if (GET_CODE (src) == CONST_INT)
1555 if (src == const0_rtx) /* mov r,L */
1556 return AS1 (clr,%0);
1557 else if (src == const1_rtx)
1559 if (reg_was_0 (insn, dest))
1560 return AS1 (inc,%0 ; reg_was_0);
1563 return (AS1 (clr,%0) CR_TAB
1566 else if (src == constm1_rtx)
1568 /* Immediate constants -1 to any register */
1569 if (reg_was_0 (insn, dest))
1570 return AS1 (dec,%0 ; reg_was_0);
1573 return (AS1 (clr,%0) CR_TAB
1578 int bit_nr = exact_log2 (INTVAL (src));
1582 if (reg_was_0 (insn, dest))
1586 output_asm_insn ("set ; reg_was_0", operands);
1592 output_asm_insn ((AS1 (clr,%0) CR_TAB
1596 avr_output_bld (operands, bit_nr);
1603 /* Last resort, larger than loading from memory. */
1605 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1606 AS2 (ldi,r31,lo8(%1)) CR_TAB
1607 AS2 (mov,%0,r31) CR_TAB
1608 AS2 (mov,r31,__tmp_reg__));
1610 else if (GET_CODE (src) == MEM)
1611 return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1613 else if (GET_CODE (dest) == MEM)
1615 const char *template;
1617 if (src == const0_rtx)
1618 operands[1] = zero_reg_rtx;
1620 template = out_movqi_mr_r (insn, operands, real_l);
1623 output_asm_insn (template, operands);
1632 output_movhi (insn, operands, l)
1638 rtx dest = operands[0];
1639 rtx src = operands[1];
1645 if (register_operand (dest, HImode))
1647 if (register_operand (src, HImode)) /* mov r,r */
1649 if (test_hard_reg_class (STACK_REG, dest))
1651 if (TARGET_TINY_STACK)
1654 return AS2 (out,__SP_L__,%A1);
1656 else if (TARGET_NO_INTERRUPTS)
1659 return (AS2 (out,__SP_H__,%B1) CR_TAB
1660 AS2 (out,__SP_L__,%A1));
1664 return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB
1666 AS2 (out,__SP_H__,%B1) CR_TAB
1667 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1668 AS2 (out,__SP_L__,%A1));
1670 else if (test_hard_reg_class (STACK_REG, src))
1673 return (AS2 (in,%A0,__SP_L__) CR_TAB
1674 AS2 (in,%B0,__SP_H__));
1680 return (AS2 (movw,%0,%1));
1683 if (true_regnum (dest) > true_regnum (src))
1686 return (AS2 (mov,%B0,%B1) CR_TAB
1692 return (AS2 (mov,%A0,%A1) CR_TAB
1696 else if (CONSTANT_P (src))
1698 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1700 if (byte_immediate_operand (src, HImode)
1701 && reg_was_0 (insn, dest))
1704 return (AS2 (ldi,%A0,lo8(%1) ; reg_was_0));
1708 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1709 AS2 (ldi,%B0,hi8(%1)));
1712 if (GET_CODE (src) == CONST_INT)
1714 if (src == const0_rtx) /* mov r,L */
1717 return (AS1 (clr,%A0) CR_TAB
1720 else if (src == const1_rtx)
1722 if (reg_was_0 (insn, dest))
1725 return AS1 (inc,%0 ; reg_was_0);
1729 return (AS1 (clr,%A0) CR_TAB
1730 AS1 (clr,%B0) CR_TAB
1733 else if (src == constm1_rtx)
1735 /* Immediate constants -1 to any register */
1736 if (reg_was_0 (insn, dest))
1739 return (AS1 (dec,%A0 ; reg_was_0) CR_TAB
1744 return (AS1 (clr,%0) CR_TAB
1745 AS1 (dec,%A0) CR_TAB
1750 int bit_nr = exact_log2 (INTVAL (src));
1754 if (reg_was_0 (insn, dest))
1758 output_asm_insn ("set ; reg_was_0", operands);
1764 output_asm_insn ((AS1 (clr,%A0) CR_TAB
1765 AS1 (clr,%B0) CR_TAB
1769 avr_output_bld (operands, bit_nr);
1775 if ((INTVAL (src) & 0xff) == 0)
1778 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1779 AS1 (clr,%A0) CR_TAB
1780 AS2 (ldi,r31,hi8(%1)) CR_TAB
1781 AS2 (mov,%B0,r31) CR_TAB
1782 AS2 (mov,r31,__tmp_reg__));
1784 else if ((INTVAL (src) & 0xff00) == 0)
1787 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1788 AS2 (ldi,r31,lo8(%1)) CR_TAB
1789 AS2 (mov,%A0,r31) CR_TAB
1790 AS1 (clr,%B0) CR_TAB
1791 AS2 (mov,r31,__tmp_reg__));
1795 /* Last resort, equal to loading from memory. */
1797 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1798 AS2 (ldi,r31,lo8(%1)) CR_TAB
1799 AS2 (mov,%A0,r31) CR_TAB
1800 AS2 (ldi,r31,hi8(%1)) CR_TAB
1801 AS2 (mov,%B0,r31) CR_TAB
1802 AS2 (mov,r31,__tmp_reg__));
1804 else if (GET_CODE (src) == MEM)
1805 return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1807 else if (GET_CODE (dest) == MEM)
1809 const char *template;
1811 if (src == const0_rtx)
1812 operands[1] = zero_reg_rtx;
1814 template = out_movhi_mr_r (insn, operands, real_l);
1817 output_asm_insn (template, operands);
1822 fatal_insn ("invalid insn:", insn);
1827 out_movqi_r_mr (insn, op, l)
1830 int *l; /* instruction length */
1834 rtx x = XEXP (src, 0);
1840 if (CONSTANT_ADDRESS_P (x))
1842 if (avr_io_address_p (x, 1))
1845 return AS2 (in,%0,%1-0x20);
1848 return AS2 (lds,%0,%1);
1850 /* memory access by reg+disp */
1851 else if (GET_CODE (x) == PLUS
1852 && REG_P (XEXP (x,0))
1853 && GET_CODE (XEXP (x,1)) == CONST_INT)
1855 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1857 int disp = INTVAL (XEXP (x,1));
1858 if (REGNO (XEXP (x,0)) != REG_Y)
1859 fatal_insn ("incorrect insn:",insn);
1861 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1862 return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
1863 AS2 (ldd,%0,Y+63) CR_TAB
1864 AS2 (sbiw,r28,%o1-63));
1866 return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1867 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1868 AS2 (ld,%0,Y) CR_TAB
1869 AS2 (subi,r28,lo8(%o1)) CR_TAB
1870 AS2 (sbci,r29,hi8(%o1)));
1872 else if (REGNO (XEXP (x,0)) == REG_X)
1874 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1875 it but I have this situation with extremal optimizing options. */
1876 if (reg_overlap_mentioned_p (dest, XEXP (x,0))
1877 || reg_unused_after (insn, XEXP (x,0)))
1878 return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
1881 return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
1882 AS2 (ld,%0,X) CR_TAB
1883 AS2 (sbiw,r26,%o1));
1886 return AS2 (ldd,%0,%1);
1889 return AS2 (ld,%0,%1);
1893 out_movhi_r_mr (insn, op, l)
1896 int *l; /* instruction length */
1900 rtx base = XEXP (src, 0);
1901 int reg_dest = true_regnum (dest);
1902 int reg_base = true_regnum (base);
1910 if (reg_dest == reg_base) /* R = (R) */
1913 return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1914 AS2 (ld,%B0,%1) CR_TAB
1915 AS2 (mov,%A0,__tmp_reg__));
1917 else if (reg_base == REG_X) /* (R26) */
1919 if (reg_unused_after (insn, base))
1922 return (AS2 (ld,%A0,X+) CR_TAB
1926 return (AS2 (ld,%A0,X+) CR_TAB
1927 AS2 (ld,%B0,X) CR_TAB
1933 return (AS2 (ld,%A0,%1) CR_TAB
1934 AS2 (ldd,%B0,%1+1));
1937 else if (GET_CODE (base) == PLUS) /* (R + i) */
1939 int disp = INTVAL (XEXP (base, 1));
1940 int reg_base = true_regnum (XEXP (base, 0));
1942 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
1944 if (REGNO (XEXP (base, 0)) != REG_Y)
1945 fatal_insn ("incorrect insn:",insn);
1947 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1948 return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
1949 AS2 (ldd,%A0,Y+62) CR_TAB
1950 AS2 (ldd,%B0,Y+63) CR_TAB
1951 AS2 (sbiw,r28,%o1-62));
1953 return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1954 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1955 AS2 (ld,%A0,Y) CR_TAB
1956 AS2 (ldd,%B0,Y+1) CR_TAB
1957 AS2 (subi,r28,lo8(%o1)) CR_TAB
1958 AS2 (sbci,r29,hi8(%o1)));
1960 if (reg_base == REG_X)
1962 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1963 it but I have this situation with extremal
1964 optimization options. */
1967 if (reg_base == reg_dest)
1968 return (AS2 (adiw,r26,%o1) CR_TAB
1969 AS2 (ld,__tmp_reg__,X+) CR_TAB
1970 AS2 (ld,%B0,X) CR_TAB
1971 AS2 (mov,%A0,__tmp_reg__));
1973 return (AS2 (adiw,r26,%o1) CR_TAB
1974 AS2 (ld,%A0,X+) CR_TAB
1975 AS2 (ld,%B0,X) CR_TAB
1976 AS2 (sbiw,r26,%o1+1));
1979 if (reg_base == reg_dest)
1982 return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
1983 AS2 (ldd,%B0,%B1) CR_TAB
1984 AS2 (mov,%A0,__tmp_reg__));
1988 return (AS2 (ldd,%A0,%A1) CR_TAB
1991 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
1993 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1994 fatal_insn ("incorrect insn:", insn);
1997 return (AS2 (ld,%B0,%1) CR_TAB
2000 else if (GET_CODE (base) == POST_INC) /* (R++) */
2002 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
2003 fatal_insn ("incorrect insn:", insn);
2006 return (AS2 (ld,%A0,%1) CR_TAB
2009 else if (CONSTANT_ADDRESS_P (base))
2011 if (avr_io_address_p (base, 2))
2014 return (AS2 (in,%A0,%A1-0x20) CR_TAB
2015 AS2 (in,%B0,%B1-0x20));
2018 return (AS2 (lds,%A0,%A1) CR_TAB
2022 fatal_insn ("unknown move insn:",insn);
2027 out_movsi_r_mr (insn, op, l)
2030 int *l; /* instruction length */
2034 rtx base = XEXP (src, 0);
2035 int reg_dest = true_regnum (dest);
2036 int reg_base = true_regnum (base);
2044 if (reg_base == REG_X) /* (R26) */
2046 if (reg_dest == REG_X)
2047 /* "ld r26,-X" is undefined */
2048 return *l=7, (AS2 (adiw,r26,3) CR_TAB
2049 AS2 (ld,r29,X) CR_TAB
2050 AS2 (ld,r28,-X) CR_TAB
2051 AS2 (ld,__tmp_reg__,-X) CR_TAB
2052 AS2 (sbiw,r26,1) CR_TAB
2053 AS2 (ld,r26,X) CR_TAB
2054 AS2 (mov,r27,__tmp_reg__));
2055 else if (reg_dest == REG_X - 2)
2056 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2057 AS2 (ld,%B0,X+) CR_TAB
2058 AS2 (ld,__tmp_reg__,X+) CR_TAB
2059 AS2 (ld,%D0,X) CR_TAB
2060 AS2 (mov,%C0,__tmp_reg__));
2061 else if (reg_unused_after (insn, base))
2062 return *l=4, (AS2 (ld,%A0,X+) CR_TAB
2063 AS2 (ld,%B0,X+) CR_TAB
2064 AS2 (ld,%C0,X+) CR_TAB
2067 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2068 AS2 (ld,%B0,X+) CR_TAB
2069 AS2 (ld,%C0,X+) CR_TAB
2070 AS2 (ld,%D0,X) CR_TAB
2075 if (reg_dest == reg_base)
2076 return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
2077 AS2 (ldd,%C0,%1+2) CR_TAB
2078 AS2 (ldd,__tmp_reg__,%1+1) CR_TAB
2079 AS2 (ld,%A0,%1) CR_TAB
2080 AS2 (mov,%B0,__tmp_reg__));
2081 else if (reg_base == reg_dest + 2)
2082 return *l=5, (AS2 (ld ,%A0,%1) CR_TAB
2083 AS2 (ldd,%B0,%1+1) CR_TAB
2084 AS2 (ldd,__tmp_reg__,%1+2) CR_TAB
2085 AS2 (ldd,%D0,%1+3) CR_TAB
2086 AS2 (mov,%C0,__tmp_reg__));
2088 return *l=4, (AS2 (ld ,%A0,%1) CR_TAB
2089 AS2 (ldd,%B0,%1+1) CR_TAB
2090 AS2 (ldd,%C0,%1+2) CR_TAB
2091 AS2 (ldd,%D0,%1+3));
2094 else if (GET_CODE (base) == PLUS) /* (R + i) */
2096 int disp = INTVAL (XEXP (base, 1));
2098 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2100 if (REGNO (XEXP (base, 0)) != REG_Y)
2101 fatal_insn ("incorrect insn:",insn);
2103 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2104 return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2105 AS2 (ldd,%A0,Y+60) CR_TAB
2106 AS2 (ldd,%B0,Y+61) CR_TAB
2107 AS2 (ldd,%C0,Y+62) CR_TAB
2108 AS2 (ldd,%D0,Y+63) CR_TAB
2109 AS2 (sbiw,r28,%o1-60));
2111 return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2112 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2113 AS2 (ld,%A0,Y) CR_TAB
2114 AS2 (ldd,%B0,Y+1) CR_TAB
2115 AS2 (ldd,%C0,Y+2) CR_TAB
2116 AS2 (ldd,%D0,Y+3) CR_TAB
2117 AS2 (subi,r28,lo8(%o1)) CR_TAB
2118 AS2 (sbci,r29,hi8(%o1)));
2121 reg_base = true_regnum (XEXP (base, 0));
2122 if (reg_base == REG_X)
2125 if (reg_dest == REG_X)
2128 /* "ld r26,-X" is undefined */
2129 return (AS2 (adiw,r26,%o1+3) CR_TAB
2130 AS2 (ld,r29,X) CR_TAB
2131 AS2 (ld,r28,-X) CR_TAB
2132 AS2 (ld,__tmp_reg__,-X) CR_TAB
2133 AS2 (sbiw,r26,1) CR_TAB
2134 AS2 (ld,r26,X) CR_TAB
2135 AS2 (mov,r27,__tmp_reg__));
2138 if (reg_dest == REG_X - 2)
2139 return (AS2 (adiw,r26,%o1) CR_TAB
2140 AS2 (ld,r24,X+) CR_TAB
2141 AS2 (ld,r25,X+) CR_TAB
2142 AS2 (ld,__tmp_reg__,X+) CR_TAB
2143 AS2 (ld,r27,X) CR_TAB
2144 AS2 (mov,r26,__tmp_reg__));
2146 return (AS2 (adiw,r26,%o1) CR_TAB
2147 AS2 (ld,%A0,X+) CR_TAB
2148 AS2 (ld,%B0,X+) CR_TAB
2149 AS2 (ld,%C0,X+) CR_TAB
2150 AS2 (ld,%D0,X) CR_TAB
2151 AS2 (sbiw,r26,%o1+3));
2153 if (reg_dest == reg_base)
2154 return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2155 AS2 (ldd,%C0,%C1) CR_TAB
2156 AS2 (ldd,__tmp_reg__,%B1) CR_TAB
2157 AS2 (ldd,%A0,%A1) CR_TAB
2158 AS2 (mov,%B0,__tmp_reg__));
2159 else if (reg_dest == reg_base - 2)
2160 return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2161 AS2 (ldd,%B0,%B1) CR_TAB
2162 AS2 (ldd,__tmp_reg__,%C1) CR_TAB
2163 AS2 (ldd,%D0,%D1) CR_TAB
2164 AS2 (mov,%C0,__tmp_reg__));
2165 return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2166 AS2 (ldd,%B0,%B1) CR_TAB
2167 AS2 (ldd,%C0,%C1) CR_TAB
2170 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2171 return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2172 AS2 (ld,%C0,%1) CR_TAB
2173 AS2 (ld,%B0,%1) CR_TAB
2175 else if (GET_CODE (base) == POST_INC) /* (R++) */
2176 return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2177 AS2 (ld,%B0,%1) CR_TAB
2178 AS2 (ld,%C0,%1) CR_TAB
2180 else if (CONSTANT_ADDRESS_P (base))
2181 return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2182 AS2 (lds,%B0,%B1) CR_TAB
2183 AS2 (lds,%C0,%C1) CR_TAB
2186 fatal_insn ("unknown move insn:",insn);
2191 out_movsi_mr_r (insn, op, l)
2198 rtx base = XEXP (dest, 0);
2199 int reg_base = true_regnum (base);
2200 int reg_src = true_regnum (src);
2206 if (CONSTANT_ADDRESS_P (base))
2207 return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2208 AS2 (sts,%B0,%B1) CR_TAB
2209 AS2 (sts,%C0,%C1) CR_TAB
2211 if (reg_base > 0) /* (r) */
2213 if (reg_base == REG_X) /* (R26) */
2215 if (reg_src == REG_X)
2217 /* "st X+,r26" is undefined */
2218 if (reg_unused_after (insn, base))
2219 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2220 AS2 (st,X,r26) CR_TAB
2221 AS2 (adiw,r26,1) CR_TAB
2222 AS2 (st,X+,__tmp_reg__) CR_TAB
2223 AS2 (st,X+,r28) CR_TAB
2226 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2227 AS2 (st,X,r26) CR_TAB
2228 AS2 (adiw,r26,1) CR_TAB
2229 AS2 (st,X+,__tmp_reg__) CR_TAB
2230 AS2 (st,X+,r28) CR_TAB
2231 AS2 (st,X,r29) CR_TAB
2234 else if (reg_base == reg_src + 2)
2236 if (reg_unused_after (insn, base))
2237 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2238 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2239 AS2 (st,%0+,%A1) CR_TAB
2240 AS2 (st,%0+,%B1) CR_TAB
2241 AS2 (st,%0+,__zero_reg__) CR_TAB
2242 AS2 (st,%0,__tmp_reg__) CR_TAB
2243 AS1 (clr,__zero_reg__));
2245 return *l=8, (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__) CR_TAB
2254 return *l=5, (AS2 (st,%0+,%A1) CR_TAB
2255 AS2 (st,%0+,%B1) CR_TAB
2256 AS2 (st,%0+,%C1) CR_TAB
2257 AS2 (st,%0,%D1) CR_TAB
2261 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2262 AS2 (std,%0+1,%B1) CR_TAB
2263 AS2 (std,%0+2,%C1) CR_TAB
2264 AS2 (std,%0+3,%D1));
2266 else if (GET_CODE (base) == PLUS) /* (R + i) */
2268 int disp = INTVAL (XEXP (base, 1));
2269 reg_base = REGNO (XEXP (base, 0));
2270 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2272 if (reg_base != REG_Y)
2273 fatal_insn ("incorrect insn:",insn);
2275 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2276 return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2277 AS2 (std,Y+60,%A1) CR_TAB
2278 AS2 (std,Y+61,%B1) CR_TAB
2279 AS2 (std,Y+62,%C1) CR_TAB
2280 AS2 (std,Y+63,%D1) CR_TAB
2281 AS2 (sbiw,r28,%o0-60));
2283 return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2284 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2285 AS2 (st,Y,%A1) CR_TAB
2286 AS2 (std,Y+1,%B1) CR_TAB
2287 AS2 (std,Y+2,%C1) CR_TAB
2288 AS2 (std,Y+3,%D1) CR_TAB
2289 AS2 (subi,r28,lo8(%o0)) CR_TAB
2290 AS2 (sbci,r29,hi8(%o0)));
2292 if (reg_base == REG_X)
2295 if (reg_src == REG_X)
2298 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2299 AS2 (mov,__zero_reg__,r27) CR_TAB
2300 AS2 (adiw,r26,%o0) CR_TAB
2301 AS2 (st,X+,__tmp_reg__) CR_TAB
2302 AS2 (st,X+,__zero_reg__) CR_TAB
2303 AS2 (st,X+,r28) CR_TAB
2304 AS2 (st,X,r29) CR_TAB
2305 AS1 (clr,__zero_reg__) CR_TAB
2306 AS2 (sbiw,r26,%o0+3));
2308 else if (reg_src == REG_X - 2)
2311 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2312 AS2 (mov,__zero_reg__,r27) CR_TAB
2313 AS2 (adiw,r26,%o0) CR_TAB
2314 AS2 (st,X+,r24) CR_TAB
2315 AS2 (st,X+,r25) CR_TAB
2316 AS2 (st,X+,__tmp_reg__) CR_TAB
2317 AS2 (st,X,__zero_reg__) CR_TAB
2318 AS1 (clr,__zero_reg__) CR_TAB
2319 AS2 (sbiw,r26,%o0+3));
2322 return (AS2 (adiw,r26,%o0) CR_TAB
2323 AS2 (st,X+,%A1) CR_TAB
2324 AS2 (st,X+,%B1) CR_TAB
2325 AS2 (st,X+,%C1) CR_TAB
2326 AS2 (st,X,%D1) CR_TAB
2327 AS2 (sbiw,r26,%o0+3));
2329 return *l=4, (AS2 (std,%A0,%A1) CR_TAB
2330 AS2 (std,%B0,%B1) CR_TAB
2331 AS2 (std,%C0,%C1) CR_TAB
2334 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2335 return *l=4, (AS2 (st,%0,%D1) CR_TAB
2336 AS2 (st,%0,%C1) CR_TAB
2337 AS2 (st,%0,%B1) CR_TAB
2339 else if (GET_CODE (base) == POST_INC) /* (R++) */
2340 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2341 AS2 (st,%0,%B1) CR_TAB
2342 AS2 (st,%0,%C1) CR_TAB
2344 fatal_insn ("unknown move insn:",insn);
2349 output_movsisf(insn, operands, l)
2355 rtx dest = operands[0];
2356 rtx src = operands[1];
2362 if (register_operand (dest, VOIDmode))
2364 if (register_operand (src, VOIDmode)) /* mov r,r */
2366 if (true_regnum (dest) > true_regnum (src))
2371 return (AS2 (movw,%C0,%C1) CR_TAB
2372 AS2 (movw,%A0,%A1));
2375 return (AS2 (mov,%D0,%D1) CR_TAB
2376 AS2 (mov,%C0,%C1) CR_TAB
2377 AS2 (mov,%B0,%B1) CR_TAB
2385 return (AS2 (movw,%A0,%A1) CR_TAB
2386 AS2 (movw,%C0,%C1));
2389 return (AS2 (mov,%A0,%A1) CR_TAB
2390 AS2 (mov,%B0,%B1) CR_TAB
2391 AS2 (mov,%C0,%C1) CR_TAB
2395 else if (CONSTANT_P (src))
2397 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2399 if (byte_immediate_operand (src, SImode)
2400 && reg_was_0 (insn, dest))
2403 return (AS2 (ldi,%A0,lo8(%1) ; reg_was_0));
2407 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
2408 AS2 (ldi,%B0,hi8(%1)) CR_TAB
2409 AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2410 AS2 (ldi,%D0,hhi8(%1)));
2413 if (GET_CODE (src) == CONST_INT)
2415 const char *const clr_op0 =
2416 AVR_ENHANCED ? (AS1 (clr,%A0) CR_TAB
2417 AS1 (clr,%B0) CR_TAB
2419 : (AS1 (clr,%A0) CR_TAB
2420 AS1 (clr,%B0) CR_TAB
2421 AS1 (clr,%C0) CR_TAB
2424 if (src == const0_rtx) /* mov r,L */
2426 *l = AVR_ENHANCED ? 3 : 4;
2429 else if (src == const1_rtx)
2431 if (reg_was_0 (insn, dest))
2434 return AS1 (inc,%A0 ; reg_was_0);
2437 output_asm_insn (clr_op0, operands);
2438 *l = AVR_ENHANCED ? 4 : 5;
2439 return AS1 (inc,%A0);
2441 else if (src == constm1_rtx)
2443 /* Immediate constants -1 to any register */
2444 if (reg_was_0 (insn, dest))
2449 return (AS1 (dec,%A0) CR_TAB
2450 AS1 (dec,%B0) CR_TAB
2451 AS2 (movw,%C0,%A0));
2454 return (AS1 (dec,%D0 ; reg_was_0) CR_TAB
2455 AS1 (dec,%C0) CR_TAB
2456 AS1 (dec,%B0) CR_TAB
2462 return (AS1 (clr,%A0) CR_TAB
2463 AS1 (dec,%A0) CR_TAB
2464 AS2 (mov,%B0,%A0) CR_TAB
2465 AS2 (movw,%C0,%A0));
2468 return (AS1 (clr,%A0) CR_TAB
2469 AS1 (dec,%A0) CR_TAB
2470 AS2 (mov,%B0,%A0) CR_TAB
2471 AS2 (mov,%C0,%A0) CR_TAB
2476 int bit_nr = exact_log2 (INTVAL (src));
2480 if (reg_was_0 (insn, dest))
2484 output_asm_insn ("set ; reg_was_0", operands);
2488 *l = AVR_ENHANCED ? 5 : 6;
2491 output_asm_insn (clr_op0, operands);
2492 output_asm_insn ("set", operands);
2496 avr_output_bld (operands, bit_nr);
2503 /* Last resort, better than loading from memory. */
2505 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2506 AS2 (ldi,r31,lo8(%1)) CR_TAB
2507 AS2 (mov,%A0,r31) CR_TAB
2508 AS2 (ldi,r31,hi8(%1)) CR_TAB
2509 AS2 (mov,%B0,r31) CR_TAB
2510 AS2 (ldi,r31,hlo8(%1)) CR_TAB
2511 AS2 (mov,%C0,r31) CR_TAB
2512 AS2 (ldi,r31,hhi8(%1)) CR_TAB
2513 AS2 (mov,%D0,r31) CR_TAB
2514 AS2 (mov,r31,__tmp_reg__));
2516 else if (GET_CODE (src) == MEM)
2517 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2519 else if (GET_CODE (dest) == MEM)
2521 const char *template;
2523 if (src == const0_rtx)
2524 operands[1] = zero_reg_rtx;
2526 template = out_movsi_mr_r (insn, operands, real_l);
2529 output_asm_insn (template, operands);
2534 fatal_insn ("invalid insn:", insn);
2539 out_movqi_mr_r (insn, op, l)
2542 int *l; /* instruction length */
2546 rtx x = XEXP (dest, 0);
2552 if (CONSTANT_ADDRESS_P (x))
2554 if (avr_io_address_p (x, 1))
2557 return AS2 (out,%0-0x20,%1);
2560 return AS2 (sts,%0,%1);
2562 /* memory access by reg+disp */
2563 else if (GET_CODE (x) == PLUS
2564 && REG_P (XEXP (x,0))
2565 && GET_CODE (XEXP (x,1)) == CONST_INT)
2567 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2569 int disp = INTVAL (XEXP (x,1));
2570 if (REGNO (XEXP (x,0)) != REG_Y)
2571 fatal_insn ("incorrect insn:",insn);
2573 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2574 return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2575 AS2 (std,Y+63,%1) CR_TAB
2576 AS2 (sbiw,r28,%o0-63));
2578 return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2579 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2580 AS2 (st,Y,%1) CR_TAB
2581 AS2 (subi,r28,lo8(%o0)) CR_TAB
2582 AS2 (sbci,r29,hi8(%o0)));
2584 else if (REGNO (XEXP (x,0)) == REG_X)
2586 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2588 if (reg_unused_after (insn, XEXP (x,0)))
2589 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2590 AS2 (adiw,r26,%o0) CR_TAB
2591 AS2 (st,X,__tmp_reg__));
2593 return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2594 AS2 (adiw,r26,%o0) CR_TAB
2595 AS2 (st,X,__tmp_reg__) CR_TAB
2596 AS2 (sbiw,r26,%o0));
2600 if (reg_unused_after (insn, XEXP (x,0)))
2601 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2604 return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2605 AS2 (st,X,%1) CR_TAB
2606 AS2 (sbiw,r26,%o0));
2610 return AS2 (std,%0,%1);
2613 return AS2 (st,%0,%1);
2617 out_movhi_mr_r (insn, op, l)
2624 rtx base = XEXP (dest, 0);
2625 int reg_base = true_regnum (base);
2626 int reg_src = true_regnum (src);
2630 if (CONSTANT_ADDRESS_P (base))
2632 if (avr_io_address_p (base, 2))
2635 return (AS2 (out,%B0-0x20,%B1) CR_TAB
2636 AS2 (out,%A0-0x20,%A1));
2638 return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2643 if (reg_base == REG_X)
2645 if (reg_src == REG_X)
2647 /* "st X+,r26" is undefined */
2648 if (reg_unused_after (insn, src))
2649 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2650 AS2 (st,X,r26) CR_TAB
2651 AS2 (adiw,r26,1) CR_TAB
2652 AS2 (st,X,__tmp_reg__));
2654 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2655 AS2 (st,X,r26) CR_TAB
2656 AS2 (adiw,r26,1) CR_TAB
2657 AS2 (st,X,__tmp_reg__) CR_TAB
2662 if (reg_unused_after (insn, base))
2663 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2666 return *l=3, (AS2 (st ,X+,%A1) CR_TAB
2667 AS2 (st ,X,%B1) CR_TAB
2672 return *l=2, (AS2 (st ,%0,%A1) CR_TAB
2673 AS2 (std,%0+1,%B1));
2675 else if (GET_CODE (base) == PLUS)
2677 int disp = INTVAL (XEXP (base, 1));
2678 reg_base = REGNO (XEXP (base, 0));
2679 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2681 if (reg_base != REG_Y)
2682 fatal_insn ("incorrect insn:",insn);
2684 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2685 return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2686 AS2 (std,Y+62,%A1) CR_TAB
2687 AS2 (std,Y+63,%B1) CR_TAB
2688 AS2 (sbiw,r28,%o0-62));
2690 return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2691 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2692 AS2 (st,Y,%A1) CR_TAB
2693 AS2 (std,Y+1,%B1) CR_TAB
2694 AS2 (subi,r28,lo8(%o0)) CR_TAB
2695 AS2 (sbci,r29,hi8(%o0)));
2697 if (reg_base == REG_X)
2700 if (reg_src == REG_X)
2703 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2704 AS2 (mov,__zero_reg__,r27) CR_TAB
2705 AS2 (adiw,r26,%o0) CR_TAB
2706 AS2 (st,X+,__tmp_reg__) CR_TAB
2707 AS2 (st,X,__zero_reg__) CR_TAB
2708 AS1 (clr,__zero_reg__) CR_TAB
2709 AS2 (sbiw,r26,%o0+1));
2712 return (AS2 (adiw,r26,%o0) CR_TAB
2713 AS2 (st,X+,%A1) CR_TAB
2714 AS2 (st,X,%B1) CR_TAB
2715 AS2 (sbiw,r26,%o0+1));
2717 return *l=2, (AS2 (std,%A0,%A1) CR_TAB
2720 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2721 return *l=2, (AS2 (st,%0,%B1) CR_TAB
2723 else if (GET_CODE (base) == POST_INC) /* (R++) */
2724 return *l=2, (AS2 (st,%0,%A1) CR_TAB
2726 fatal_insn ("unknown move insn:",insn);
2730 /* Return 1 if frame pointer for current function required */
2733 frame_pointer_required_p ()
2735 return (current_function_calls_alloca
2736 || current_function_args_info.nregs == 0
2737 || current_function_varargs
2738 || get_frame_size () > 0);
2741 /* Returns the condition of compare insn INSN, or UNKNOWN. */
2744 compare_condition (insn)
2747 rtx next = next_real_insn (insn);
2748 RTX_CODE cond = UNKNOWN;
2749 if (next && GET_CODE (next) == JUMP_INSN)
2751 rtx pat = PATTERN (next);
2752 rtx src = SET_SRC (pat);
2753 rtx t = XEXP (src, 0);
2754 cond = GET_CODE (t);
2759 /* Returns nonzero if INSN is a tst insn that only tests the sign. */
2762 compare_sign_p (insn)
2765 RTX_CODE cond = compare_condition (insn);
2766 return (cond == GE || cond == LT);
2769 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
2770 that needs to be swapped (GT, GTU, LE, LEU). */
2773 compare_diff_p (insn)
2776 RTX_CODE cond = compare_condition (insn);
2777 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2780 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition. */
2786 RTX_CODE cond = compare_condition (insn);
2787 return (cond == EQ || cond == NE);
2791 /* Output test instruction for HImode */
2798 if (compare_sign_p (insn))
2801 return AS1 (tst,%B0);
2803 if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
2804 && compare_eq_p (insn))
2806 /* faster than sbiw if we can clobber the operand */
2808 return AS2 (or,%A0,%B0);
2810 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2813 return AS2 (sbiw,%0,0);
2816 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2817 AS2 (cpc,%B0,__zero_reg__));
2821 /* Output test instruction for SImode */
2828 if (compare_sign_p (insn))
2831 return AS1 (tst,%D0);
2833 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2836 return (AS2 (sbiw,%A0,0) CR_TAB
2837 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2838 AS2 (cpc,%D0,__zero_reg__));
2841 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2842 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2843 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2844 AS2 (cpc,%D0,__zero_reg__));
2848 /* Generate asm equivalent for various shifts.
2849 Shift count is a CONST_INT, MEM or REG.
2850 This only handles cases that are not already
2851 carefully hand-optimized in ?sh??i3_out. */
2854 out_shift_with_cnt (template, insn, operands, len, t_len)
2855 const char *template;
2859 int t_len; /* Length of template. */
2863 int second_label = 1;
2864 int saved_in_tmp = 0;
2865 int use_zero_reg = 0;
2867 op[0] = operands[0];
2868 op[1] = operands[1];
2869 op[2] = operands[2];
2870 op[3] = operands[3];
2876 if (GET_CODE (operands[2]) == CONST_INT)
2878 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2879 int count = INTVAL (operands[2]);
2880 int max_len = 10; /* If larger than this, always use a loop. */
2882 if (count < 8 && !scratch)
2886 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
2888 if (t_len * count <= max_len)
2890 /* Output shifts inline with no loop - faster. */
2892 *len = t_len * count;
2896 output_asm_insn (template, op);
2905 strcat (str, AS2 (ldi,%3,%2));
2907 else if (use_zero_reg)
2909 /* Hack to save one word: use __zero_reg__ as loop counter.
2910 Set one bit, then shift in a loop until it is 0 again. */
2912 op[3] = zero_reg_rtx;
2916 strcat (str, ("set" CR_TAB
2917 AS2 (bld,%3,%2-1)));
2921 /* No scratch register available, use one from LD_REGS (saved in
2922 __tmp_reg__) that doesn't overlap with registers to shift. */
2924 op[3] = gen_rtx (REG, QImode,
2925 ((true_regnum (operands[0]) - 1) & 15) + 16);
2926 op[4] = tmp_reg_rtx;
2930 *len = 3; /* Includes "mov %3,%4" after the loop. */
2932 strcat (str, (AS2 (mov,%4,%3) CR_TAB
2938 else if (GET_CODE (operands[2]) == MEM)
2942 op[3] = op_mov[0] = tmp_reg_rtx;
2946 out_movqi_r_mr (insn, op_mov, len);
2948 output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2950 else if (register_operand (operands[2], QImode))
2952 if (reg_unused_after (insn, operands[2]))
2956 op[3] = tmp_reg_rtx;
2958 strcat (str, (AS2 (mov,%3,%2) CR_TAB));
2962 fatal_insn ("bad shift insn:", insn);
2969 strcat (str, AS1 (rjmp,2f));
2973 *len += t_len + 2; /* template + dec + brXX */
2976 strcat (str, "\n1:\t");
2977 strcat (str, template);
2978 strcat (str, second_label ? "\n2:\t" : "\n\t");
2979 strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
2980 strcat (str, CR_TAB);
2981 strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
2983 strcat (str, (CR_TAB AS2 (mov,%3,%4)));
2984 output_asm_insn (str, op);
2989 /* 8bit shift left ((char)x << i) */
2992 ashlqi3_out (insn, operands, len)
2995 int *len; /* insn length (may be NULL) */
2997 if (GET_CODE (operands[2]) == CONST_INT)
3004 switch (INTVAL (operands[2]))
3008 return AS1 (clr,%0);
3012 return AS1 (lsl,%0);
3016 return (AS1 (lsl,%0) CR_TAB
3021 return (AS1 (lsl,%0) CR_TAB
3026 if (test_hard_reg_class (LD_REGS, operands[0]))
3029 return (AS1 (swap,%0) CR_TAB
3030 AS2 (andi,%0,0xf0));
3033 return (AS1 (lsl,%0) CR_TAB
3039 if (test_hard_reg_class (LD_REGS, operands[0]))
3042 return (AS1 (swap,%0) CR_TAB
3044 AS2 (andi,%0,0xe0));
3047 return (AS1 (lsl,%0) CR_TAB
3054 if (test_hard_reg_class (LD_REGS, operands[0]))
3057 return (AS1 (swap,%0) CR_TAB
3060 AS2 (andi,%0,0xc0));
3063 return (AS1 (lsl,%0) CR_TAB
3072 return (AS1 (ror,%0) CR_TAB
3077 else if (CONSTANT_P (operands[2]))
3078 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3080 out_shift_with_cnt (AS1 (lsl,%0),
3081 insn, operands, len, 1);
3086 /* 16bit shift left ((short)x << i) */
3089 ashlhi3_out (insn, operands, len)
3094 if (GET_CODE (operands[2]) == CONST_INT)
3096 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3097 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3104 switch (INTVAL (operands[2]))
3107 if (optimize_size && scratch)
3112 return (AS1 (swap,%A0) CR_TAB
3113 AS1 (swap,%B0) CR_TAB
3114 AS2 (andi,%B0,0xf0) CR_TAB
3115 AS2 (eor,%B0,%A0) CR_TAB
3116 AS2 (andi,%A0,0xf0) CR_TAB
3122 return (AS1 (swap,%A0) CR_TAB
3123 AS1 (swap,%B0) CR_TAB
3124 AS2 (ldi,%3,0xf0) CR_TAB
3125 AS2 (and,%B0,%3) CR_TAB
3126 AS2 (eor,%B0,%A0) CR_TAB
3127 AS2 (and,%A0,%3) CR_TAB
3130 break; /* optimize_size ? 6 : 8 */
3134 break; /* scratch ? 5 : 6 */
3138 return (AS1 (lsl,%A0) CR_TAB
3139 AS1 (rol,%B0) CR_TAB
3140 AS1 (swap,%A0) CR_TAB
3141 AS1 (swap,%B0) CR_TAB
3142 AS2 (andi,%B0,0xf0) CR_TAB
3143 AS2 (eor,%B0,%A0) CR_TAB
3144 AS2 (andi,%A0,0xf0) CR_TAB
3150 return (AS1 (lsl,%A0) CR_TAB
3151 AS1 (rol,%B0) CR_TAB
3152 AS1 (swap,%A0) CR_TAB
3153 AS1 (swap,%B0) CR_TAB
3154 AS2 (ldi,%3,0xf0) CR_TAB
3155 AS2 (and,%B0,%3) CR_TAB
3156 AS2 (eor,%B0,%A0) CR_TAB
3157 AS2 (and,%A0,%3) CR_TAB
3164 break; /* scratch ? 5 : 6 */
3166 return (AS1 (clr,__tmp_reg__) CR_TAB
3167 AS1 (lsr,%B0) CR_TAB
3168 AS1 (ror,%A0) CR_TAB
3169 AS1 (ror,__tmp_reg__) CR_TAB
3170 AS1 (lsr,%B0) CR_TAB
3171 AS1 (ror,%A0) CR_TAB
3172 AS1 (ror,__tmp_reg__) CR_TAB
3173 AS2 (mov,%B0,%A0) CR_TAB
3174 AS2 (mov,%A0,__tmp_reg__));
3178 return (AS1 (lsr,%B0) CR_TAB
3179 AS2 (mov,%B0,%A0) CR_TAB
3180 AS1 (clr,%A0) CR_TAB
3181 AS1 (ror,%B0) CR_TAB
3185 if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
3186 return *len = 1, AS1 (clr,%A0);
3188 return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3193 return (AS2 (mov,%B0,%A0) CR_TAB
3194 AS1 (clr,%A0) CR_TAB
3199 return (AS2 (mov,%B0,%A0) CR_TAB
3200 AS1 (clr,%A0) CR_TAB
3201 AS1 (lsl,%B0) CR_TAB
3206 return (AS2 (mov,%B0,%A0) CR_TAB
3207 AS1 (clr,%A0) CR_TAB
3208 AS1 (lsl,%B0) CR_TAB
3209 AS1 (lsl,%B0) CR_TAB
3216 return (AS2 (mov,%B0,%A0) CR_TAB
3217 AS1 (clr,%A0) CR_TAB
3218 AS1 (swap,%B0) CR_TAB
3219 AS2 (andi,%B0,0xf0));
3224 return (AS2 (mov,%B0,%A0) CR_TAB
3225 AS1 (clr,%A0) CR_TAB
3226 AS1 (swap,%B0) CR_TAB
3227 AS2 (ldi,%3,0xf0) CR_TAB
3231 return (AS2 (mov,%B0,%A0) CR_TAB
3232 AS1 (clr,%A0) CR_TAB
3233 AS1 (lsl,%B0) CR_TAB
3234 AS1 (lsl,%B0) CR_TAB
3235 AS1 (lsl,%B0) CR_TAB
3242 return (AS2 (mov,%B0,%A0) CR_TAB
3243 AS1 (clr,%A0) CR_TAB
3244 AS1 (swap,%B0) CR_TAB
3245 AS1 (lsl,%B0) CR_TAB
3246 AS2 (andi,%B0,0xe0));
3248 if (AVR_ENHANCED && scratch)
3251 return (AS2 (ldi,%3,0x20) CR_TAB
3252 AS2 (mul,%A0,%3) CR_TAB
3253 AS2 (mov,%B0,r0) CR_TAB
3254 AS1 (clr,%A0) CR_TAB
3255 AS1 (clr,__zero_reg__));
3257 if (optimize_size && scratch)
3262 return (AS2 (mov,%B0,%A0) CR_TAB
3263 AS1 (clr,%A0) CR_TAB
3264 AS1 (swap,%B0) CR_TAB
3265 AS1 (lsl,%B0) CR_TAB
3266 AS2 (ldi,%3,0xe0) CR_TAB
3272 return ("set" CR_TAB
3273 AS2 (bld,r1,5) CR_TAB
3274 AS2 (mul,%A0,r1) CR_TAB
3275 AS2 (mov,%B0,r0) CR_TAB
3276 AS1 (clr,%A0) CR_TAB
3277 AS1 (clr,__zero_reg__));
3280 return (AS2 (mov,%B0,%A0) CR_TAB
3281 AS1 (clr,%A0) CR_TAB
3282 AS1 (lsl,%B0) CR_TAB
3283 AS1 (lsl,%B0) CR_TAB
3284 AS1 (lsl,%B0) CR_TAB
3285 AS1 (lsl,%B0) CR_TAB
3289 if (AVR_ENHANCED && ldi_ok)
3292 return (AS2 (ldi,%B0,0x40) CR_TAB
3293 AS2 (mul,%A0,%B0) CR_TAB
3294 AS2 (mov,%B0,r0) CR_TAB
3295 AS1 (clr,%A0) CR_TAB
3296 AS1 (clr,__zero_reg__));
3298 if (AVR_ENHANCED && scratch)
3301 return (AS2 (ldi,%3,0x40) CR_TAB
3302 AS2 (mul,%A0,%3) CR_TAB
3303 AS2 (mov,%B0,r0) CR_TAB
3304 AS1 (clr,%A0) CR_TAB
3305 AS1 (clr,__zero_reg__));
3307 if (optimize_size && ldi_ok)
3310 return (AS2 (mov,%B0,%A0) CR_TAB
3311 AS2 (ldi,%A0,6) "\n1:\t"
3312 AS1 (lsl,%B0) CR_TAB
3313 AS1 (dec,%A0) CR_TAB
3316 if (optimize_size && scratch)
3319 return (AS1 (clr,%B0) CR_TAB
3320 AS1 (lsr,%A0) CR_TAB
3321 AS1 (ror,%B0) CR_TAB
3322 AS1 (lsr,%A0) CR_TAB
3323 AS1 (ror,%B0) CR_TAB
3328 return (AS1 (clr,%B0) CR_TAB
3329 AS1 (lsr,%A0) CR_TAB
3330 AS1 (ror,%B0) CR_TAB
3335 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3337 insn, operands, len, 2);
3342 /* 32bit shift left ((long)x << i) */
3345 ashlsi3_out (insn, operands, len)
3350 if (GET_CODE (operands[2]) == CONST_INT)
3358 switch (INTVAL (operands[2]))
3362 int reg0 = true_regnum (operands[0]);
3363 int reg1 = true_regnum (operands[1]);
3366 return (AS2 (mov,%D0,%C1) CR_TAB
3367 AS2 (mov,%C0,%B1) CR_TAB
3368 AS2 (mov,%B0,%A1) CR_TAB
3370 else if (reg0 + 1 == reg1)
3373 return AS1 (clr,%A0);
3376 return (AS1 (clr,%A0) CR_TAB
3377 AS2 (mov,%B0,%A1) CR_TAB
3378 AS2 (mov,%C0,%B1) CR_TAB
3384 int reg0 = true_regnum (operands[0]);
3385 int reg1 = true_regnum (operands[1]);
3387 if (AVR_ENHANCED && (reg0 + 2 != reg1))
3390 return (AS2 (movw,%C0,%A1) CR_TAB
3391 AS1 (clr,%B0) CR_TAB
3394 if (reg0 + 1 >= reg1)
3395 return (AS2 (mov,%D0,%B1) CR_TAB
3396 AS2 (mov,%C0,%A1) CR_TAB
3397 AS1 (clr,%B0) CR_TAB
3399 if (reg0 + 2 == reg1)
3402 return (AS1 (clr,%B0) CR_TAB
3406 return (AS2 (mov,%C0,%A1) CR_TAB
3407 AS2 (mov,%D0,%B1) CR_TAB
3408 AS1 (clr,%B0) CR_TAB
3414 if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
3415 return (AS2 (mov,%D0,%A1) CR_TAB
3416 AS1 (clr,%C0) CR_TAB
3417 AS1 (clr,%B0) CR_TAB
3422 return (AS1 (clr,%C0) CR_TAB
3423 AS1 (clr,%B0) CR_TAB
3429 return (AS1 (clr,%D0) CR_TAB
3430 AS1 (lsr,%A0) CR_TAB
3431 AS1 (ror,%D0) CR_TAB
3432 AS1 (clr,%C0) CR_TAB
3433 AS1 (clr,%B0) CR_TAB
3438 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3439 AS1 (rol,%B0) CR_TAB
3440 AS1 (rol,%C0) CR_TAB
3442 insn, operands, len, 4);
3446 /* 8bit arithmetic shift right ((signed char)x >> i) */
3449 ashrqi3_out (insn, operands, len)
3452 int *len; /* insn length */
3454 if (GET_CODE (operands[2]) == CONST_INT)
3461 switch (INTVAL (operands[2]))
3465 return AS1 (asr,%0);
3469 return (AS1 (asr,%0) CR_TAB
3474 return (AS1 (asr,%0) CR_TAB
3480 return (AS1 (asr,%0) CR_TAB
3487 return (AS1 (asr,%0) CR_TAB
3495 return (AS2 (bst,%0,6) CR_TAB
3497 AS2 (sbc,%0,%0) CR_TAB
3503 return (AS1 (lsl,%0) CR_TAB
3507 else if (CONSTANT_P (operands[2]))
3508 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3510 out_shift_with_cnt (AS1 (asr,%0),
3511 insn, operands, len, 1);
3516 /* 16bit arithmetic shift right ((signed short)x >> i) */
3519 ashrhi3_out (insn, operands, len)
3524 if (GET_CODE (operands[2]) == CONST_INT)
3526 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3527 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3534 switch (INTVAL (operands[2]))
3538 /* XXX try to optimize this too? */
3543 break; /* scratch ? 5 : 6 */
3545 return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3546 AS2 (mov,%A0,%B0) CR_TAB
3547 AS1 (lsl,__tmp_reg__) CR_TAB
3548 AS1 (rol,%A0) CR_TAB
3549 AS2 (sbc,%B0,%B0) CR_TAB
3550 AS1 (lsl,__tmp_reg__) CR_TAB
3551 AS1 (rol,%A0) CR_TAB
3556 return (AS1 (lsl,%A0) CR_TAB
3557 AS2 (mov,%A0,%B0) CR_TAB
3558 AS1 (rol,%A0) CR_TAB
3563 int reg0 = true_regnum (operands[0]);
3564 int reg1 = true_regnum (operands[1]);
3567 return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3568 AS1 (lsl,%B0) CR_TAB
3570 else if (reg0 == reg1 + 1)
3571 return *len = 3, (AS1 (clr,%B0) CR_TAB
3572 AS2 (sbrc,%A0,7) CR_TAB
3575 return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3576 AS1 (clr,%B0) CR_TAB
3577 AS2 (sbrc,%A0,7) CR_TAB
3583 return (AS2 (mov,%A0,%B0) CR_TAB
3584 AS1 (lsl,%B0) CR_TAB
3585 AS2 (sbc,%B0,%B0) CR_TAB
3590 return (AS2 (mov,%A0,%B0) CR_TAB
3591 AS1 (lsl,%B0) CR_TAB
3592 AS2 (sbc,%B0,%B0) CR_TAB
3593 AS1 (asr,%A0) CR_TAB
3597 if (AVR_ENHANCED && ldi_ok)
3600 return (AS2 (ldi,%A0,0x20) CR_TAB
3601 AS2 (muls,%B0,%A0) CR_TAB
3602 AS2 (mov,%A0,r1) CR_TAB
3603 AS2 (sbc,%B0,%B0) CR_TAB
3604 AS1 (clr,__zero_reg__));
3606 if (optimize_size && scratch)
3609 return (AS2 (mov,%A0,%B0) CR_TAB
3610 AS1 (lsl,%B0) CR_TAB
3611 AS2 (sbc,%B0,%B0) CR_TAB
3612 AS1 (asr,%A0) CR_TAB
3613 AS1 (asr,%A0) CR_TAB
3617 if (AVR_ENHANCED && ldi_ok)
3620 return (AS2 (ldi,%A0,0x10) CR_TAB
3621 AS2 (muls,%B0,%A0) CR_TAB
3622 AS2 (mov,%A0,r1) CR_TAB
3623 AS2 (sbc,%B0,%B0) CR_TAB
3624 AS1 (clr,__zero_reg__));
3626 if (optimize_size && scratch)
3629 return (AS2 (mov,%A0,%B0) CR_TAB
3630 AS1 (lsl,%B0) CR_TAB
3631 AS2 (sbc,%B0,%B0) CR_TAB
3632 AS1 (asr,%A0) CR_TAB
3633 AS1 (asr,%A0) CR_TAB
3634 AS1 (asr,%A0) CR_TAB
3638 if (AVR_ENHANCED && ldi_ok)
3641 return (AS2 (ldi,%A0,0x08) CR_TAB
3642 AS2 (muls,%B0,%A0) CR_TAB
3643 AS2 (mov,%A0,r1) CR_TAB
3644 AS2 (sbc,%B0,%B0) CR_TAB
3645 AS1 (clr,__zero_reg__));
3648 break; /* scratch ? 5 : 7 */
3650 return (AS2 (mov,%A0,%B0) CR_TAB
3651 AS1 (lsl,%B0) CR_TAB
3652 AS2 (sbc,%B0,%B0) CR_TAB
3653 AS1 (asr,%A0) CR_TAB
3654 AS1 (asr,%A0) CR_TAB
3655 AS1 (asr,%A0) CR_TAB
3656 AS1 (asr,%A0) CR_TAB
3661 return (AS1 (lsl,%B0) CR_TAB
3662 AS2 (sbc,%A0,%A0) CR_TAB
3663 AS1 (lsl,%B0) CR_TAB
3664 AS2 (mov,%B0,%A0) CR_TAB
3668 return *len = 3, (AS1 (lsl,%B0) CR_TAB
3669 AS2 (sbc,%A0,%A0) CR_TAB
3674 out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3676 insn, operands, len, 2);
3681 /* 32bit arithmetic shift right ((signed long)x >> i) */
3684 ashrsi3_out (insn, operands, len)
3689 if (GET_CODE (operands[2]) == CONST_INT)
3697 switch (INTVAL (operands[2]))
3701 int reg0 = true_regnum (operands[0]);
3702 int reg1 = true_regnum (operands[1]);
3705 return (AS2 (mov,%A0,%B1) CR_TAB
3706 AS2 (mov,%B0,%C1) CR_TAB
3707 AS2 (mov,%C0,%D1) CR_TAB
3708 AS1 (clr,%D0) CR_TAB
3709 AS2 (sbrc,%C0,7) CR_TAB
3711 else if (reg0 == reg1 + 1)
3714 return (AS1 (clr,%D0) CR_TAB
3715 AS2 (sbrc,%C0,7) CR_TAB
3719 return (AS1 (clr,%D0) CR_TAB
3720 AS2 (sbrc,%D1,7) CR_TAB
3721 AS1 (dec,%D0) CR_TAB
3722 AS2 (mov,%C0,%D1) CR_TAB
3723 AS2 (mov,%B0,%C1) CR_TAB
3729 int reg0 = true_regnum (operands[0]);
3730 int reg1 = true_regnum (operands[1]);
3732 if (AVR_ENHANCED && (reg0 != reg1 + 2))
3735 return (AS2 (movw,%A0,%C1) CR_TAB
3736 AS1 (clr,%D0) CR_TAB
3737 AS2 (sbrc,%B0,7) CR_TAB
3738 AS1 (com,%D0) CR_TAB
3741 if (reg0 <= reg1 + 1)
3742 return (AS2 (mov,%A0,%C1) CR_TAB
3743 AS2 (mov,%B0,%D1) CR_TAB
3744 AS1 (clr,%D0) CR_TAB
3745 AS2 (sbrc,%B0,7) CR_TAB
3746 AS1 (com,%D0) CR_TAB
3748 else if (reg0 == reg1 + 2)
3749 return *len = 4, (AS1 (clr,%D0) CR_TAB
3750 AS2 (sbrc,%B0,7) CR_TAB
3751 AS1 (com,%D0) CR_TAB
3754 return (AS2 (mov,%B0,%D1) CR_TAB
3755 AS2 (mov,%A0,%C1) CR_TAB
3756 AS1 (clr,%D0) CR_TAB
3757 AS2 (sbrc,%B0,7) CR_TAB
3758 AS1 (com,%D0) CR_TAB
3763 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3764 return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3765 AS1 (clr,%D0) CR_TAB
3766 AS2 (sbrc,%A0,7) CR_TAB
3767 AS1 (com,%D0) CR_TAB
3768 AS2 (mov,%B0,%D0) CR_TAB
3771 return *len = 5, (AS1 (clr,%D0) CR_TAB
3772 AS2 (sbrc,%A0,7) CR_TAB
3773 AS1 (com,%D0) CR_TAB
3774 AS2 (mov,%B0,%D0) CR_TAB
3779 return *len = 4, (AS1 (lsl,%D0) CR_TAB
3780 AS2 (sbc,%A0,%A0) CR_TAB
3781 AS2 (mov,%B0,%A0) CR_TAB
3782 AS2 (movw,%C0,%A0));
3784 return *len = 5, (AS1 (lsl,%D0) CR_TAB
3785 AS2 (sbc,%A0,%A0) CR_TAB
3786 AS2 (mov,%B0,%A0) CR_TAB
3787 AS2 (mov,%C0,%A0) CR_TAB
3792 out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
3793 AS1 (ror,%C0) CR_TAB
3794 AS1 (ror,%B0) CR_TAB
3796 insn, operands, len, 4);
3800 /* 8bit logic shift right ((unsigned char)x >> i) */
3803 lshrqi3_out (insn, operands, len)
3808 if (GET_CODE (operands[2]) == CONST_INT)
3815 switch (INTVAL (operands[2]))
3819 return AS1 (clr,%0);
3823 return AS1 (lsr,%0);
3827 return (AS1 (lsr,%0) CR_TAB
3831 return (AS1 (lsr,%0) CR_TAB
3836 if (test_hard_reg_class (LD_REGS, operands[0]))
3839 return (AS1 (swap,%0) CR_TAB
3840 AS2 (andi,%0,0x0f));
3843 return (AS1 (lsr,%0) CR_TAB
3849 if (test_hard_reg_class (LD_REGS, operands[0]))
3852 return (AS1 (swap,%0) CR_TAB
3857 return (AS1 (lsr,%0) CR_TAB
3864 if (test_hard_reg_class (LD_REGS, operands[0]))
3867 return (AS1 (swap,%0) CR_TAB
3873 return (AS1 (lsr,%0) CR_TAB
3882 return (AS1 (rol,%0) CR_TAB
3887 else if (CONSTANT_P (operands[2]))
3888 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3890 out_shift_with_cnt (AS1 (lsr,%0),
3891 insn, operands, len, 1);
3895 /* 16bit logic shift right ((unsigned short)x >> i) */
3898 lshrhi3_out (insn, operands, len)
3903 if (GET_CODE (operands[2]) == CONST_INT)
3905 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3906 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3913 switch (INTVAL (operands[2]))
3916 if (optimize_size && scratch)
3921 return (AS1 (swap,%B0) CR_TAB
3922 AS1 (swap,%A0) CR_TAB
3923 AS2 (andi,%A0,0x0f) CR_TAB
3924 AS2 (eor,%A0,%B0) CR_TAB
3925 AS2 (andi,%B0,0x0f) CR_TAB
3931 return (AS1 (swap,%B0) CR_TAB
3932 AS1 (swap,%A0) CR_TAB
3933 AS2 (ldi,%3,0x0f) CR_TAB
3934 AS2 (and,%A0,%3) CR_TAB
3935 AS2 (eor,%A0,%B0) CR_TAB
3936 AS2 (and,%B0,%3) CR_TAB
3939 break; /* optimize_size ? 6 : 8 */
3943 break; /* scratch ? 5 : 6 */
3947 return (AS1 (lsr,%B0) CR_TAB
3948 AS1 (ror,%A0) CR_TAB
3949 AS1 (swap,%B0) CR_TAB
3950 AS1 (swap,%A0) CR_TAB
3951 AS2 (andi,%A0,0x0f) CR_TAB
3952 AS2 (eor,%A0,%B0) CR_TAB
3953 AS2 (andi,%B0,0x0f) CR_TAB
3959 return (AS1 (lsr,%B0) CR_TAB
3960 AS1 (ror,%A0) CR_TAB
3961 AS1 (swap,%B0) CR_TAB
3962 AS1 (swap,%A0) CR_TAB
3963 AS2 (ldi,%3,0x0f) CR_TAB
3964 AS2 (and,%A0,%3) CR_TAB
3965 AS2 (eor,%A0,%B0) CR_TAB
3966 AS2 (and,%B0,%3) CR_TAB
3973 break; /* scratch ? 5 : 6 */
3975 return (AS1 (clr,__tmp_reg__) CR_TAB
3976 AS1 (lsl,%A0) CR_TAB
3977 AS1 (rol,%B0) CR_TAB
3978 AS1 (rol,__tmp_reg__) CR_TAB
3979 AS1 (lsl,%A0) CR_TAB
3980 AS1 (rol,%B0) CR_TAB
3981 AS1 (rol,__tmp_reg__) CR_TAB
3982 AS2 (mov,%A0,%B0) CR_TAB
3983 AS2 (mov,%B0,__tmp_reg__));
3987 return (AS1 (lsl,%A0) CR_TAB
3988 AS2 (mov,%A0,%B0) CR_TAB
3989 AS1 (rol,%A0) CR_TAB
3990 AS2 (sbc,%B0,%B0) CR_TAB
3994 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
3995 return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
3998 return *len = 1, AS1 (clr,%B0);
4002 return (AS2 (mov,%A0,%B0) CR_TAB
4003 AS1 (clr,%B0) CR_TAB
4008 return (AS2 (mov,%A0,%B0) CR_TAB
4009 AS1 (clr,%B0) CR_TAB
4010 AS1 (lsr,%A0) CR_TAB
4015 return (AS2 (mov,%A0,%B0) CR_TAB
4016 AS1 (clr,%B0) CR_TAB
4017 AS1 (lsr,%A0) CR_TAB
4018 AS1 (lsr,%A0) CR_TAB
4025 return (AS2 (mov,%A0,%B0) CR_TAB
4026 AS1 (clr,%B0) CR_TAB
4027 AS1 (swap,%A0) CR_TAB
4028 AS2 (andi,%A0,0x0f));
4033 return (AS2 (mov,%A0,%B0) CR_TAB
4034 AS1 (clr,%B0) CR_TAB
4035 AS1 (swap,%A0) CR_TAB
4036 AS2 (ldi,%3,0x0f) CR_TAB
4040 return (AS2 (mov,%A0,%B0) CR_TAB
4041 AS1 (clr,%B0) CR_TAB
4042 AS1 (lsr,%A0) CR_TAB
4043 AS1 (lsr,%A0) CR_TAB
4044 AS1 (lsr,%A0) CR_TAB
4051 return (AS2 (mov,%A0,%B0) CR_TAB
4052 AS1 (clr,%B0) CR_TAB
4053 AS1 (swap,%A0) CR_TAB
4054 AS1 (lsr,%A0) CR_TAB
4055 AS2 (andi,%A0,0x07));
4057 if (AVR_ENHANCED && scratch)
4060 return (AS2 (ldi,%3,0x08) CR_TAB
4061 AS2 (mul,%B0,%3) CR_TAB
4062 AS2 (mov,%A0,r1) CR_TAB
4063 AS1 (clr,%B0) CR_TAB
4064 AS1 (clr,__zero_reg__));
4066 if (optimize_size && scratch)
4071 return (AS2 (mov,%A0,%B0) CR_TAB
4072 AS1 (clr,%B0) CR_TAB
4073 AS1 (swap,%A0) CR_TAB
4074 AS1 (lsr,%A0) CR_TAB
4075 AS2 (ldi,%3,0x07) CR_TAB
4081 return ("set" CR_TAB
4082 AS2 (bld,r1,3) CR_TAB
4083 AS2 (mul,%B0,r1) CR_TAB
4084 AS2 (mov,%A0,r1) CR_TAB
4085 AS1 (clr,%B0) CR_TAB
4086 AS1 (clr,__zero_reg__));
4089 return (AS2 (mov,%A0,%B0) CR_TAB
4090 AS1 (clr,%B0) CR_TAB
4091 AS1 (lsr,%A0) CR_TAB
4092 AS1 (lsr,%A0) CR_TAB
4093 AS1 (lsr,%A0) CR_TAB
4094 AS1 (lsr,%A0) CR_TAB
4098 if (AVR_ENHANCED && ldi_ok)
4101 return (AS2 (ldi,%A0,0x04) CR_TAB
4102 AS2 (mul,%B0,%A0) CR_TAB
4103 AS2 (mov,%A0,r1) CR_TAB
4104 AS1 (clr,%B0) CR_TAB
4105 AS1 (clr,__zero_reg__));
4107 if (AVR_ENHANCED && scratch)
4110 return (AS2 (ldi,%3,0x04) CR_TAB
4111 AS2 (mul,%B0,%3) CR_TAB
4112 AS2 (mov,%A0,r1) CR_TAB
4113 AS1 (clr,%B0) CR_TAB
4114 AS1 (clr,__zero_reg__));
4116 if (optimize_size && ldi_ok)
4119 return (AS2 (mov,%A0,%B0) CR_TAB
4120 AS2 (ldi,%B0,6) "\n1:\t"
4121 AS1 (lsr,%A0) CR_TAB
4122 AS1 (dec,%B0) CR_TAB
4125 if (optimize_size && scratch)
4128 return (AS1 (clr,%A0) CR_TAB
4129 AS1 (lsl,%B0) CR_TAB
4130 AS1 (rol,%A0) CR_TAB
4131 AS1 (lsl,%B0) CR_TAB
4132 AS1 (rol,%A0) CR_TAB
4137 return (AS1 (clr,%A0) CR_TAB
4138 AS1 (lsl,%B0) CR_TAB
4139 AS1 (rol,%A0) CR_TAB
4144 out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
4146 insn, operands, len, 2);
4150 /* 32bit logic shift right ((unsigned int)x >> i) */
4153 lshrsi3_out (insn, operands, len)
4158 if (GET_CODE (operands[2]) == CONST_INT)
4166 switch (INTVAL (operands[2]))
4170 int reg0 = true_regnum (operands[0]);
4171 int reg1 = true_regnum (operands[1]);
4174 return (AS2 (mov,%A0,%B1) CR_TAB
4175 AS2 (mov,%B0,%C1) CR_TAB
4176 AS2 (mov,%C0,%D1) CR_TAB
4178 else if (reg0 == reg1 + 1)
4179 return *len = 1, AS1 (clr,%D0);
4181 return (AS1 (clr,%D0) CR_TAB
4182 AS2 (mov,%C0,%D1) CR_TAB
4183 AS2 (mov,%B0,%C1) CR_TAB
4189 int reg0 = true_regnum (operands[0]);
4190 int reg1 = true_regnum (operands[1]);
4192 if (AVR_ENHANCED && (reg0 != reg1 + 2))
4195 return (AS2 (movw,%A0,%C1) CR_TAB
4196 AS1 (clr,%C0) CR_TAB
4199 if (reg0 <= reg1 + 1)
4200 return (AS2 (mov,%A0,%C1) CR_TAB
4201 AS2 (mov,%B0,%D1) CR_TAB
4202 AS1 (clr,%C0) CR_TAB
4204 else if (reg0 == reg1 + 2)
4205 return *len = 2, (AS1 (clr,%C0) CR_TAB
4208 return (AS2 (mov,%B0,%D1) CR_TAB
4209 AS2 (mov,%A0,%C1) CR_TAB
4210 AS1 (clr,%C0) CR_TAB
4215 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
4216 return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4217 AS1 (clr,%B0) CR_TAB
4218 AS1 (clr,%C0) CR_TAB
4221 return *len = 3, (AS1 (clr,%B0) CR_TAB
4222 AS1 (clr,%C0) CR_TAB
4227 return (AS1 (clr,%A0) CR_TAB
4228 AS2 (sbrc,%D0,7) CR_TAB
4229 AS1 (inc,%A0) CR_TAB
4230 AS1 (clr,%B0) CR_TAB
4231 AS1 (clr,%C0) CR_TAB
4236 out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4237 AS1 (ror,%C0) CR_TAB
4238 AS1 (ror,%B0) CR_TAB
4240 insn, operands, len, 4);
4244 /* Modifies the length assigned to instruction INSN
4245 LEN is the initially computed length of the insn. */
4248 adjust_insn_length (insn, len)
4252 rtx patt = PATTERN (insn);
4255 if (GET_CODE (patt) == SET)
4258 op[1] = SET_SRC (patt);
4259 op[0] = SET_DEST (patt);
4260 if (general_operand (op[1], VOIDmode)
4261 && general_operand (op[0], VOIDmode))
4263 switch (GET_MODE (op[0]))
4266 output_movqi (insn, op, &len);
4269 output_movhi (insn, op, &len);
4273 output_movsisf (insn, op, &len);
4279 else if (op[0] == cc0_rtx && REG_P (op[1]))
4281 switch (GET_MODE (op[1]))
4283 case HImode: out_tsthi (insn,&len); break;
4284 case SImode: out_tstsi (insn,&len); break;
4288 else if (GET_CODE (op[1]) == AND)
4290 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4292 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4293 if (GET_MODE (op[1]) == SImode)
4294 len = (((mask & 0xff) != 0xff)
4295 + ((mask & 0xff00) != 0xff00)
4296 + ((mask & 0xff0000L) != 0xff0000L)
4297 + ((mask & 0xff000000L) != 0xff000000L));
4298 else if (GET_MODE (op[1]) == HImode)
4299 len = (((mask & 0xff) != 0xff)
4300 + ((mask & 0xff00) != 0xff00));
4303 else if (GET_CODE (op[1]) == IOR)
4305 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4307 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4308 if (GET_MODE (op[1]) == SImode)
4309 len = (((mask & 0xff) != 0)
4310 + ((mask & 0xff00) != 0)
4311 + ((mask & 0xff0000L) != 0)
4312 + ((mask & 0xff000000L) != 0));
4313 else if (GET_MODE (op[1]) == HImode)
4314 len = (((mask & 0xff) != 0)
4315 + ((mask & 0xff00) != 0));
4319 set = single_set (insn);
4324 op[1] = SET_SRC (set);
4325 op[0] = SET_DEST (set);
4327 if (GET_CODE (patt) == PARALLEL
4328 && general_operand (op[1], VOIDmode)
4329 && general_operand (op[0], VOIDmode))
4331 if (XVECLEN (patt, 0) == 2)
4332 op[2] = XVECEXP (patt, 0, 1);
4334 switch (GET_MODE (op[0]))
4340 output_reload_inhi (insn, op, &len);
4344 output_reload_insisf (insn, op, &len);
4350 else if (GET_CODE (op[1]) == ASHIFT
4351 || GET_CODE (op[1]) == ASHIFTRT
4352 || GET_CODE (op[1]) == LSHIFTRT)
4356 ops[1] = XEXP (op[1],0);
4357 ops[2] = XEXP (op[1],1);
4358 switch (GET_CODE (op[1]))
4361 switch (GET_MODE (op[0]))
4363 case QImode: ashlqi3_out (insn,ops,&len); break;
4364 case HImode: ashlhi3_out (insn,ops,&len); break;
4365 case SImode: ashlsi3_out (insn,ops,&len); break;
4370 switch (GET_MODE (op[0]))
4372 case QImode: ashrqi3_out (insn,ops,&len); break;
4373 case HImode: ashrhi3_out (insn,ops,&len); break;
4374 case SImode: ashrsi3_out (insn,ops,&len); break;
4379 switch (GET_MODE (op[0]))
4381 case QImode: lshrqi3_out (insn,ops,&len); break;
4382 case HImode: lshrhi3_out (insn,ops,&len); break;
4383 case SImode: lshrsi3_out (insn,ops,&len); break;
4395 /* Return non-zero if register REG dead after INSN */
4398 reg_unused_after (insn, reg)
4402 return (dead_or_set_p (insn, reg)
4403 || (REG_P(reg) && _reg_unused_after (insn, reg)));
4406 /* Return non-zero if REG is not used after INSN.
4407 We assume REG is a reload reg, and therefore does
4408 not live past labels. It may live past calls or jumps though. */
4411 _reg_unused_after (insn, reg)
4418 /* If the reg is set by this instruction, then it is safe for our
4419 case. Disregard the case where this is a store to memory, since
4420 we are checking a register used in the store address. */
4421 set = single_set (insn);
4422 if (set && GET_CODE (SET_DEST (set)) != MEM
4423 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4426 while ((insn = NEXT_INSN (insn)))
4428 code = GET_CODE (insn);
4431 /* If this is a label that existed before reload, then the register
4432 if dead here. However, if this is a label added by reorg, then
4433 the register may still be live here. We can't tell the difference,
4434 so we just ignore labels completely. */
4435 if (code == CODE_LABEL)
4440 if (code == JUMP_INSN)
4443 /* If this is a sequence, we must handle them all at once.
4444 We could have for instance a call that sets the target register,
4445 and an insn in a delay slot that uses the register. In this case,
4446 we must return 0. */
4447 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
4452 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
4454 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
4455 rtx set = single_set (this_insn);
4457 if (GET_CODE (this_insn) == CALL_INSN)
4459 else if (GET_CODE (this_insn) == JUMP_INSN)
4461 if (INSN_ANNULLED_BRANCH_P (this_insn))
4466 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4468 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4470 if (GET_CODE (SET_DEST (set)) != MEM)
4476 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
4481 else if (code == JUMP_INSN)
4485 if (code == CALL_INSN)
4488 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4489 if (GET_CODE (XEXP (tem, 0)) == USE
4490 && REG_P (XEXP (XEXP (tem, 0), 0))
4491 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
4493 if (call_used_regs[REGNO (reg)])
4497 if (GET_RTX_CLASS (code) == 'i')
4499 rtx set = single_set (insn);
4501 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4503 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4504 return GET_CODE (SET_DEST (set)) != MEM;
4505 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
4512 /* Target hook for assembling integer objects. The AVR version needs
4513 special handling for references to certain labels. */
4516 avr_assemble_integer (x, size, aligned_p)
4521 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
4522 && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FLAG (x))
4523 || GET_CODE (x) == LABEL_REF))
4525 fputs ("\t.word\tpm(", asm_out_file);
4526 output_addr_const (asm_out_file, x);
4527 fputs (")\n", asm_out_file);
4530 return default_assemble_integer (x, size, aligned_p);
4533 /* Sets section name for declaration DECL */
4536 avr_unique_section (decl, reloc)
4538 int reloc ATTRIBUTE_UNUSED;
4541 const char *name, *prefix;
4544 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
4545 name = (* targetm.strip_name_encoding) (name);
4547 if (TREE_CODE (decl) == FUNCTION_DECL)
4549 if (flag_function_sections)
4557 if (flag_function_sections)
4559 len = strlen (name) + strlen (prefix);
4560 string = alloca (len + 1);
4561 sprintf (string, "%s%s", prefix, name);
4562 DECL_SECTION_NAME (decl) = build_string (len, string);
4567 /* The routine used to output NUL terminated strings. We use a special
4568 version of this for most svr4 targets because doing so makes the
4569 generated assembly code more compact (and thus faster to assemble)
4570 as well as more readable, especially for targets like the i386
4571 (where the only alternative is to output character sequences as
4572 comma separated lists of numbers). */
4575 gas_output_limited_string(file, str)
4579 const unsigned char *_limited_str = (unsigned char *) str;
4581 fprintf (file, "%s\"", STRING_ASM_OP);
4582 for (; (ch = *_limited_str); _limited_str++)
4585 switch (escape = ESCAPES[ch])
4591 fprintf (file, "\\%03o", ch);
4595 putc (escape, file);
4599 fprintf (file, "\"\n");
4602 /* The routine used to output sequences of byte values. We use a special
4603 version of this for most svr4 targets because doing so makes the
4604 generated assembly code more compact (and thus faster to assemble)
4605 as well as more readable. Note that if we find subparts of the
4606 character sequence which end with NUL (and which are shorter than
4607 STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
4610 gas_output_ascii(file, str, length)
4615 const unsigned char *_ascii_bytes = (const unsigned char *) str;
4616 const unsigned char *limit = _ascii_bytes + length;
4617 unsigned bytes_in_chunk = 0;
4618 for (; _ascii_bytes < limit; _ascii_bytes++)
4620 const unsigned char *p;
4621 if (bytes_in_chunk >= 60)
4623 fprintf (file, "\"\n");
4626 for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
4628 if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
4630 if (bytes_in_chunk > 0)
4632 fprintf (file, "\"\n");
4635 gas_output_limited_string (file, (char*)_ascii_bytes);
4642 if (bytes_in_chunk == 0)
4643 fprintf (file, "\t.ascii\t\"");
4644 switch (escape = ESCAPES[ch = *_ascii_bytes])
4651 fprintf (file, "\\%03o", ch);
4652 bytes_in_chunk += 4;
4656 putc (escape, file);
4657 bytes_in_chunk += 2;
4662 if (bytes_in_chunk > 0)
4663 fprintf (file, "\"\n");
4666 /* Return value is nonzero if pseudos that have been
4667 assigned to registers of class CLASS would likely be spilled
4668 because registers of CLASS are needed for spill registers. */
4671 class_likely_spilled_p (c)
4674 return (c != ALL_REGS && c != ADDW_REGS);
4677 /* Valid attributes:
4678 progmem - put data to program memory;
4679 signal - make a function to be hardware interrupt. After function
4680 prologue interrupts are disabled;
4681 interrupt - make a function to be hardware interrupt. After function
4682 prologue interrupts are enabled;
4683 naked - don't generate function prologue/epilogue and `ret' command.
4685 Only `progmem' attribute valid for type. */
4687 const struct attribute_spec avr_attribute_table[] =
4689 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
4690 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute },
4691 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4692 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4693 { "naked", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4694 { NULL, 0, 0, false, false, false, NULL }
4697 /* Handle a "progmem" attribute; arguments as in
4698 struct attribute_spec.handler. */
4700 avr_handle_progmem_attribute (node, name, args, flags, no_add_attrs)
4703 tree args ATTRIBUTE_UNUSED;
4704 int flags ATTRIBUTE_UNUSED;
4709 if (TREE_CODE (*node) == TYPE_DECL)
4711 /* This is really a decl attribute, not a type attribute,
4712 but try to handle it for GCC 3.0 backwards compatibility. */
4714 tree type = TREE_TYPE (*node);
4715 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
4716 tree newtype = build_type_attribute_variant (type, attr);
4718 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
4719 TREE_TYPE (*node) = newtype;
4720 *no_add_attrs = true;
4722 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
4724 if (DECL_INITIAL (*node) == NULL_TREE && !DECL_EXTERNAL (*node))
4726 warning ("only initialized variables can be placed into "
4727 "program memory area");
4728 *no_add_attrs = true;
4733 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
4734 *no_add_attrs = true;
4741 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
4742 struct attribute_spec.handler. */
4744 avr_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
4747 tree args ATTRIBUTE_UNUSED;
4748 int flags ATTRIBUTE_UNUSED;
4751 if (TREE_CODE (*node) != FUNCTION_DECL)
4753 warning ("`%s' attribute only applies to functions",
4754 IDENTIFIER_POINTER (name));
4755 *no_add_attrs = true;
4761 /* Look for attribute `progmem' in DECL
4762 if found return 1, otherwise 0. */
4765 avr_progmem_p (decl)
4770 if (TREE_CODE (decl) != VAR_DECL)
4774 != lookup_attribute ("progmem", DECL_ATTRIBUTES (decl)))
4780 while (TREE_CODE (a) == ARRAY_TYPE);
4782 if (a == error_mark_node)
4785 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
4791 /* Encode section information about tree DECL. */
4794 avr_encode_section_info (decl, first)
4798 if (TREE_CODE (decl) == FUNCTION_DECL)
4799 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
4801 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
4802 && TREE_CODE (decl) == VAR_DECL
4803 && avr_progmem_p (decl))
4805 static const char *const dsec = ".progmem.data";
4806 DECL_SECTION_NAME (decl) = build_string (strlen (dsec), dsec);
4807 TREE_READONLY (decl) = 1;
4811 /* Outputs to the stdio stream FILE some
4812 appropriate text to go at the start of an assembler file. */
4815 asm_file_start (file)
4819 error ("MCU `%s' supported for assembler only", avr_mcu_name);
4821 output_file_directive (file, main_input_filename);
4822 fprintf (file, "\t.arch %s\n", avr_mcu_name);
4823 fputs ("__SREG__ = 0x3f\n"
4825 "__SP_L__ = 0x3d\n", file);
4827 fputs ("__tmp_reg__ = 0\n"
4828 "__zero_reg__ = 1\n"
4829 "_PC_ = 2\n", file);
4831 /* FIXME: output these only if there is anything in the .data / .bss
4832 sections - some code size could be saved by not linking in the
4833 initialization code from libgcc if one or both sections are empty. */
4834 fputs ("\t.global __do_copy_data\n", file);
4835 fputs ("\t.global __do_clear_bss\n", file);
4837 commands_in_file = 0;
4838 commands_in_prologues = 0;
4839 commands_in_epilogues = 0;
4842 /* Outputs to the stdio stream FILE some
4843 appropriate text to go at the end of an assembler file. */
4849 fputs ("/* File ", file);
4850 output_quoted_string (file, main_input_filename);
4852 ": code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
4855 commands_in_file - commands_in_prologues - commands_in_epilogues,
4856 commands_in_prologues, commands_in_epilogues);
4859 /* Choose the order in which to allocate hard registers for
4860 pseudo-registers local to a basic block.
4862 Store the desired register order in the array `reg_alloc_order'.
4863 Element 0 should be the register to allocate first; element 1, the
4864 next register; and so on. */
4867 order_regs_for_local_alloc ()
4870 static const int order_0[] = {
4878 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4882 static const int order_1[] = {
4890 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4894 static const int order_2[] = {
4903 15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4908 const int *order = (TARGET_ORDER_1 ? order_1 :
4909 TARGET_ORDER_2 ? order_2 :
4911 for (i=0; i < ARRAY_SIZE (order_0); ++i)
4912 reg_alloc_order[i] = order[i];
4915 /* Calculate the cost of X code of the expression in which it is contained,
4916 found in OUTER_CODE */
4919 default_rtx_costs (X, code, outer_code)
4922 enum rtx_code outer_code;
4929 cost = 2 * GET_MODE_SIZE (GET_MODE (X));
4932 if (outer_code != SET)
4934 if (GET_CODE (XEXP (X,0)) == SYMBOL_REF)
4935 cost += 2 * GET_MODE_SIZE (GET_MODE (X));
4937 cost += GET_MODE_SIZE (GET_MODE (X));
4943 if (outer_code == SET)
4944 cost = GET_MODE_SIZE (GET_MODE (X));
4946 cost = -GET_MODE_SIZE (GET_MODE (X));
4949 if (outer_code == SET)
4950 cost = GET_MODE_SIZE (GET_MODE (X));
4956 if (outer_code == SET)
4958 if (X == stack_pointer_rtx)
4960 else if (GET_CODE (XEXP (X,1)) == CONST_INT)
4961 cost = (INTVAL (XEXP (X,1)) <= 63 ? 1 :
4962 GET_MODE_SIZE (GET_MODE (X)));
4964 cost = GET_MODE_SIZE (GET_MODE (X));
4968 if (GET_CODE (XEXP (X,1)) == CONST_INT)
4969 cost = GET_MODE_SIZE (GET_MODE (XEXP (X,0)));
4977 /* Calculate the cost of a memory address */
4980 avr_address_cost (x)
4983 if (GET_CODE (x) == PLUS
4984 && GET_CODE (XEXP (x,1)) == CONST_INT
4985 && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
4986 && INTVAL (XEXP (x,1)) >= 61)
4988 if (CONSTANT_ADDRESS_P (x))
4990 if (avr_io_address_p (x, 1))
4997 /* EXTRA_CONSTRAINT helper */
5000 extra_constraint (x, c)
5005 && GET_CODE (x) == MEM
5006 && GET_CODE (XEXP (x,0)) == PLUS)
5008 if (TARGET_ALL_DEBUG)
5010 fprintf (stderr, ("extra_constraint:\n"
5011 "reload_completed: %d\n"
5012 "reload_in_progress: %d\n"),
5013 reload_completed, reload_in_progress);
5016 if (GET_CODE (x) == MEM
5017 && GET_CODE (XEXP (x,0)) == PLUS
5018 && REG_P (XEXP (XEXP (x,0), 0))
5019 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
5020 && (INTVAL (XEXP (XEXP (x,0), 1))
5021 <= MAX_LD_OFFSET (GET_MODE (x))))
5023 rtx xx = XEXP (XEXP (x,0), 0);
5024 int regno = REGNO (xx);
5025 if (TARGET_ALL_DEBUG)
5027 fprintf (stderr, ("extra_constraint:\n"
5028 "reload_completed: %d\n"
5029 "reload_in_progress: %d\n"),
5030 reload_completed, reload_in_progress);
5033 if (regno >= FIRST_PSEUDO_REGISTER)
5034 return 1; /* allocate pseudos */
5035 else if (regno == REG_Z || regno == REG_Y)
5036 return 1; /* strictly check */
5037 else if (xx == frame_pointer_rtx
5038 || xx == arg_pointer_rtx)
5039 return 1; /* XXX frame & arg pointer checks */
5045 /* Convert condition code CONDITION to the valid AVR condition code */
5048 avr_normalize_condition (condition)
5066 /* This fnction optimizes conditional jumps */
5069 machine_dependent_reorg (first_insn)
5074 for (insn = first_insn; insn; insn = NEXT_INSN (insn))
5076 if (! (GET_CODE (insn) == INSN
5077 || GET_CODE (insn) == CALL_INSN
5078 || GET_CODE (insn) == JUMP_INSN)
5079 || !single_set (insn))
5082 pattern = PATTERN (insn);
5084 if (GET_CODE (pattern) == PARALLEL)
5085 pattern = XVECEXP (pattern, 0, 0);
5086 if (GET_CODE (pattern) == SET
5087 && SET_DEST (pattern) == cc0_rtx
5088 && compare_diff_p (insn))
5090 if (GET_CODE (SET_SRC (pattern)) == COMPARE)
5092 /* Now we work under compare insn */
5094 pattern = SET_SRC (pattern);
5095 if (true_regnum (XEXP (pattern,0)) >= 0
5096 && true_regnum (XEXP (pattern,1)) >= 0 )
5098 rtx x = XEXP (pattern,0);
5099 rtx next = next_real_insn (insn);
5100 rtx pat = PATTERN (next);
5101 rtx src = SET_SRC (pat);
5102 rtx t = XEXP (src,0);
5103 PUT_CODE (t, swap_condition (GET_CODE (t)));
5104 XEXP (pattern,0) = XEXP (pattern,1);
5105 XEXP (pattern,1) = x;
5106 INSN_CODE (next) = -1;
5108 else if (true_regnum (XEXP (pattern,0)) >= 0
5109 && GET_CODE (XEXP (pattern,1)) == CONST_INT)
5111 rtx x = XEXP (pattern,1);
5112 rtx next = next_real_insn (insn);
5113 rtx pat = PATTERN (next);
5114 rtx src = SET_SRC (pat);
5115 rtx t = XEXP (src,0);
5116 enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
5118 if (avr_simplify_comparision_p (mode, GET_CODE (t), x))
5120 XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
5121 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
5122 INSN_CODE (next) = -1;
5123 INSN_CODE (insn) = -1;
5127 else if (true_regnum (SET_SRC (pattern)) >= 0)
5129 /* This is a tst insn */
5130 rtx next = next_real_insn (insn);
5131 rtx pat = PATTERN (next);
5132 rtx src = SET_SRC (pat);
5133 rtx t = XEXP (src,0);
5135 PUT_CODE (t, swap_condition (GET_CODE (t)));
5136 SET_SRC (pattern) = gen_rtx (NEG,
5137 GET_MODE (SET_SRC (pattern)),
5139 INSN_CODE (next) = -1;
5140 INSN_CODE (insn) = -1;
5146 /* Returns register number for function return value.*/
5154 /* Ceate an RTX representing the place where a
5155 library function returns a value of mode MODE. */
5158 avr_libcall_value (mode)
5159 enum machine_mode mode;
5161 int offs = GET_MODE_SIZE (mode);
5164 return gen_rtx (REG, mode, RET_REGISTER + 2 - offs);
5167 /* Create an RTX representing the place where a
5168 function returns a value of data type VALTYPE. */
5171 avr_function_value (type, func)
5173 tree func ATTRIBUTE_UNUSED;
5177 if (TYPE_MODE (type) != BLKmode)
5178 return avr_libcall_value (TYPE_MODE (type));
5180 offs = int_size_in_bytes (type);
5183 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
5184 offs = GET_MODE_SIZE (SImode);
5185 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
5186 offs = GET_MODE_SIZE (DImode);
5188 return gen_rtx (REG, BLKmode, RET_REGISTER + 2 - offs);
5191 /* Returns non-zero if the number MASK has only one bit set. */
5194 mask_one_bit_p (mask)
5198 unsigned HOST_WIDE_INT n=mask;
5199 for (i = 0; i < 32; ++i)
5201 if (n & 0x80000000L)
5203 if (n & 0x7fffffffL)
5214 /* Places additional restrictions on the register class to
5215 use when it is necessary to copy value X into a register
5219 preferred_reload_class (x, class)
5220 rtx x ATTRIBUTE_UNUSED;
5221 enum reg_class class;
5227 test_hard_reg_class (class, x)
5228 enum reg_class class;
5231 int regno = true_regnum (x);
5234 return TEST_HARD_REG_CLASS (class, regno);
5238 debug_hard_reg_set (set)
5242 for (i=0; i < FIRST_PSEUDO_REGISTER; ++i)
5244 if (TEST_HARD_REG_BIT (set, i))
5246 fprintf (stderr, "r%-2d ", i);
5249 fprintf (stderr, "\n");
5253 jump_over_one_insn_p (insn, dest)
5257 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
5260 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
5261 int dest_addr = INSN_ADDRESSES (uid);
5262 return dest_addr - jump_addr == get_attr_length (insn) + 1;
5265 /* Returns 1 if a value of mode MODE can be stored starting with hard
5266 register number REGNO. On the enhanced core, anything larger than
5267 1 byte must start in even numbered register for "movw" to work
5268 (this way we don't have to check for odd registers everywhere). */
5271 avr_hard_regno_mode_ok (regno, mode)
5273 enum machine_mode mode;
5275 /* Bug workaround: recog.c (peep2_find_free_register) and probably
5276 a few other places assume that the frame pointer is a single hard
5277 register, so r29 may be allocated and overwrite the high byte of
5278 the frame pointer. Do not allow any value to start in r29. */
5279 if (regno == REG_Y + 1)
5284 /* if (regno < 24 && !AVR_ENHANCED)
5286 return !(regno & 1);
5289 /* Returns 1 if we know register operand OP was 0 before INSN. */
5292 reg_was_0 (insn, op)
5297 return (optimize > 0 && insn && op && REG_P (op)
5298 && (link = find_reg_note (insn, REG_WAS_0, 0))
5299 /* Make sure the insn that stored the 0 is still present. */
5300 && ! INSN_DELETED_P (XEXP (link, 0))
5301 && GET_CODE (XEXP (link, 0)) != NOTE
5302 /* Make sure cross jumping didn't happen here. */
5303 && no_labels_between_p (XEXP (link, 0), insn)
5304 /* Make sure the reg hasn't been clobbered. */
5305 && ! reg_set_between_p (op, XEXP (link, 0), insn));
5308 /* Returns 1 if X is a valid address for an I/O register of size SIZE
5309 (1 or 2). Used for lds/sts -> in/out optimization. Add 0x20 to SIZE
5310 to check for the lower half of I/O space (for cbi/sbi/sbic/sbis). */
5313 avr_io_address_p (x, size)
5317 return (optimize > 0 && GET_CODE (x) == CONST_INT
5318 && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size);
5321 /* Returns nonzero (bit number + 1) if X, or -X, is a constant power of 2. */
5324 const_int_pow2_p (x)
5327 if (GET_CODE (x) == CONST_INT)
5329 HOST_WIDE_INT d = INTVAL (x);
5330 HOST_WIDE_INT abs_d = (d >= 0) ? d : -d;
5331 return exact_log2 (abs_d) + 1;
5337 output_reload_inhi (insn, operands, len)
5338 rtx insn ATTRIBUTE_UNUSED;
5346 if (GET_CODE (operands[1]) == CONST_INT)
5348 int val = INTVAL (operands[1]);
5349 if ((val & 0xff) == 0)
5352 return (AS2 (mov,%A0,__zero_reg__) CR_TAB
5353 AS2 (ldi,%2,hi8(%1)) CR_TAB
5356 else if ((val & 0xff00) == 0)
5359 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5360 AS2 (mov,%A0,%2) CR_TAB
5361 AS2 (mov,%B0,__zero_reg__));
5363 else if ((val & 0xff) == ((val & 0xff00) >> 8))
5366 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5367 AS2 (mov,%A0,%2) CR_TAB
5372 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5373 AS2 (mov,%A0,%2) CR_TAB
5374 AS2 (ldi,%2,hi8(%1)) CR_TAB
5380 output_reload_insisf (insn, operands, len)
5381 rtx insn ATTRIBUTE_UNUSED;
5385 rtx src = operands[1];
5386 int cnst = (GET_CODE (src) == CONST_INT);
5391 *len = 4 + ((INTVAL (src) & 0xff) != 0)
5392 + ((INTVAL (src) & 0xff00) != 0)
5393 + ((INTVAL (src) & 0xff0000) != 0)
5394 + ((INTVAL (src) & 0xff000000) != 0);
5401 if (cnst && ((INTVAL (src) & 0xff) == 0))
5402 output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
5405 output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
5406 output_asm_insn (AS2 (mov, %A0, %2), operands);
5408 if (cnst && ((INTVAL (src) & 0xff00) == 0))
5409 output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
5412 output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
5413 output_asm_insn (AS2 (mov, %B0, %2), operands);
5415 if (cnst && ((INTVAL (src) & 0xff0000) == 0))
5416 output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
5419 output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
5420 output_asm_insn (AS2 (mov, %C0, %2), operands);
5422 if (cnst && ((INTVAL (src) & 0xff000000) == 0))
5423 output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
5426 output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
5427 output_asm_insn (AS2 (mov, %D0, %2), operands);
5433 avr_output_bld (operands, bit_nr)
5437 static char s[] = "bld %A0,0";
5439 s[5] = 'A' + (bit_nr >> 3);
5440 s[8] = '0' + (bit_nr & 7);
5441 output_asm_insn (s, operands);
5445 avr_output_addr_vec_elt (stream, value)
5450 fprintf (stream, "\t.word pm(.L%d)\n", value);
5452 fprintf (stream, "\trjmp .L%d\n", value);
5457 /* Returns 1 if SCRATCH are safe to be allocated as a scratch
5458 registers (for a define_peephole2) in the current function. */
5461 avr_peep2_scratch_safe (scratch)
5464 if ((interrupt_function_p (current_function_decl)
5465 || signal_function_p (current_function_decl))
5466 && leaf_function_p ())
5468 int first_reg = true_regnum (scratch);
5469 int last_reg = first_reg + GET_MODE_SIZE (GET_MODE (scratch)) - 1;
5472 for (reg = first_reg; reg <= last_reg; reg++)
5474 if (!regs_ever_live[reg])
5481 /* Output a branch that tests a single bit of a register (QI, HI or SImode)
5482 or memory location in the I/O space (QImode only).
5484 Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
5485 Operand 1: register operand to test, or CONST_INT memory address.
5486 Operand 2: bit number (for QImode operand) or mask (HImode, SImode).
5487 Operand 3: label to jump to if the test is true. */
5490 avr_out_sbxx_branch (insn, operands)
5494 enum rtx_code comp = GET_CODE (operands[0]);
5495 int long_jump = (get_attr_length (insn) >= 4);
5496 int reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
5500 else if (comp == LT)
5504 comp = reverse_condition (comp);
5506 if (GET_CODE (operands[1]) == CONST_INT)
5508 if (INTVAL (operands[1]) < 0x40)
5511 output_asm_insn (AS2 (sbis,%1-0x20,%2), operands);
5513 output_asm_insn (AS2 (sbic,%1-0x20,%2), operands);
5517 output_asm_insn (AS2 (in,__tmp_reg__,%1-0x20), operands);
5519 output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands);
5521 output_asm_insn (AS2 (sbrc,__tmp_reg__,%2), operands);
5524 else /* GET_CODE (operands[1]) == REG */
5526 if (GET_MODE (operands[1]) == QImode)
5529 output_asm_insn (AS2 (sbrs,%1,%2), operands);
5531 output_asm_insn (AS2 (sbrc,%1,%2), operands);
5533 else /* HImode or SImode */
5535 static char buf[] = "sbrc %A1,0";
5536 int bit_nr = exact_log2 (INTVAL (operands[2])
5537 & GET_MODE_MASK (GET_MODE (operands[1])));
5539 buf[3] = (comp == EQ) ? 's' : 'c';
5540 buf[6] = 'A' + (bit_nr >> 3);
5541 buf[9] = '0' + (bit_nr & 7);
5542 output_asm_insn (buf, operands);
5547 return (AS1 (rjmp,_PC_+4) CR_TAB
5550 return AS1 (rjmp,%3);
5555 avr_asm_out_ctor (symbol, priority)
5559 fputs ("\t.global __do_global_ctors\n", asm_out_file);
5560 default_ctor_section_asm_out_constructor (symbol, priority);
5564 avr_asm_out_dtor (symbol, priority)
5568 fputs ("\t.global __do_global_dtors\n", asm_out_file);
5569 default_dtor_section_asm_out_destructor (symbol, priority);