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 /* Allocate registers from r25 to r8 for parameters for function calls */
71 #define FIRST_CUM_REG 26
73 /* Temporary register RTX (gen_rtx (REG,QImode,TMP_REGNO)) */
76 /* Zeroed register RTX (gen_rtx (REG,QImode,ZERO_REGNO)) */
79 /* RTX for register which will be used for loading immediate values to
83 /* AVR register names {"r0", "r1", ..., "r31"} */
84 static const char *const avr_regnames[] = REGISTER_NAMES;
86 /* This holds the last insn address. */
87 static int last_insn_address = 0;
89 /* Commands count in the compiled file */
90 static int commands_in_file;
92 /* Commands in the functions prologues in the compiled file */
93 static int commands_in_prologues;
95 /* Commands in the functions epilogues in the compiled file */
96 static int commands_in_epilogues;
98 /* Prologue/Epilogue size in words */
99 static int prologue_size;
100 static int epilogue_size;
102 /* Size of all jump tables in the current function, in words. */
103 static int jump_tables_size;
105 /* Initial stack value specified by the `-minit-stack=' option */
106 const char *avr_init_stack = "__stack";
108 /* Default MCU name */
109 const char *avr_mcu_name = "avr2";
111 /* Preprocessor macros to define depending on MCU type. */
112 const char *avr_base_arch_macro;
113 const char *avr_extra_arch_macro;
115 /* More than 8K of program memory: use "call" and "jmp". */
118 /* Enhanced core: use "movw", "mul", ... */
119 int avr_enhanced_p = 0;
121 /* Assembler only. */
122 int avr_asm_only_p = 0;
128 const char *const macro;
131 static const struct base_arch_s avr_arch_types[] = {
132 { 1, 0, 0, NULL }, /* unknown device specified */
133 { 1, 0, 0, "__AVR_ARCH__=1" },
134 { 0, 0, 0, "__AVR_ARCH__=2" },
135 { 0, 0, 1, "__AVR_ARCH__=3" },
136 { 0, 1, 0, "__AVR_ARCH__=4" },
137 { 0, 1, 1, "__AVR_ARCH__=5" }
141 const char *const name;
142 int arch; /* index in avr_arch_types[] */
143 /* Must lie outside user's namespace. NULL == no macro. */
144 const char *const macro;
147 /* List of all known AVR MCU types - if updated, it has to be kept
148 in sync in several places (FIXME: is there a better way?):
150 - avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
151 - t-avr (MULTILIB_MATCHES)
152 - gas/config/tc-avr.c
155 static const struct mcu_type_s avr_mcu_types[] = {
156 /* Classic, <= 8K. */
158 { "at90s2313", 2, "__AVR_AT90S2313__" },
159 { "at90s2323", 2, "__AVR_AT90S2323__" },
160 { "at90s2333", 2, "__AVR_AT90S2333__" },
161 { "at90s2343", 2, "__AVR_AT90S2343__" },
162 { "attiny22", 2, "__AVR_ATtiny22__" },
163 { "attiny26", 2, "__AVR_ATtiny26__" },
164 { "at90s4414", 2, "__AVR_AT90S4414__" },
165 { "at90s4433", 2, "__AVR_AT90S4433__" },
166 { "at90s4434", 2, "__AVR_AT90S4434__" },
167 { "at90s8515", 2, "__AVR_AT90S8515__" },
168 { "at90c8534", 2, "__AVR_AT90C8534__" },
169 { "at90s8535", 2, "__AVR_AT90S8535__" },
172 { "atmega103", 3, "__AVR_ATmega603__" },
173 { "atmega603", 3, "__AVR_ATmega103__" },
174 { "at43usb320", 3, "__AVR_AT43USB320__" },
175 { "at43usb355", 3, "__AVR_AT43USB355__" },
176 { "at76c711", 3, "__AVR_AT76C711__" },
177 /* Enhanced, <= 8K. */
179 { "atmega8", 4, "__AVR_ATmega8__" },
180 { "atmega83", 4, "__AVR_ATmega83__" },
181 { "atmega85", 4, "__AVR_ATmega85__" },
182 { "atmega8515", 4, "__AVR_ATmega8515__" },
183 /* Enhanced, > 8K. */
185 { "atmega16", 5, "__AVR_ATmega16__" },
186 { "atmega161", 5, "__AVR_ATmega161__" },
187 { "atmega162", 5, "__AVR_ATmega162__" },
188 { "atmega163", 5, "__AVR_ATmega163__" },
189 { "atmega32", 5, "__AVR_ATmega32__" },
190 { "atmega323", 5, "__AVR_ATmega323__" },
191 { "atmega64", 5, "__AVR_ATmega64__" },
192 { "atmega128", 5, "__AVR_ATmega128__" },
193 { "at94k", 5, "__AVR_AT94K__" },
194 /* Assembler only. */
196 { "at90s1200", 1, "__AVR_AT90S1200__" },
197 { "attiny10", 1, "__AVR_ATtiny11__" }, /* Yes, tiny11. */
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_insn ()))
753 - INSN_ADDRESSES (INSN_UID (get_insns ())));
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 fprintf (file, "__stop_progIi__:\n\trjmp __stop_progIi__\n");
766 else if (minimize && (frame_pointer_needed || live_seq > 4))
768 fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
770 if (frame_pointer_needed)
772 epilogue_size += out_adj_frame_ptr (file, -size);
776 fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
777 AS2 (in , r29, __SP_H__) CR_TAB));
783 fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
784 (18 - live_seq) * 2);
789 fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
790 (18 - live_seq) * 2);
798 if (frame_pointer_needed)
803 epilogue_size += out_adj_frame_ptr (file, -size);
805 if (interrupt_func_p || signal_func_p)
807 epilogue_size += out_set_stack_ptr (file, -1, 0);
811 epilogue_size += out_set_stack_ptr (file, -1, -1);
820 epilogue_size += avr_regs_to_save (&set);
821 for (reg = 31; reg >= 0; --reg)
823 if (TEST_HARD_REG_BIT (set, reg))
825 fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
829 if (interrupt_func_p || signal_func_p)
832 AS1 (pop,__tmp_reg__) CR_TAB
833 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
834 AS1 (pop,__tmp_reg__) CR_TAB
835 AS1 (pop,__zero_reg__) "\n");
837 fprintf (file, "\treti\n");
840 fprintf (file, "\tret\n");
844 fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
845 fprintf (file, "/* function %s size %d (%d) */\n", current_function_name,
846 prologue_size + function_size + epilogue_size, function_size);
847 commands_in_file += prologue_size + function_size + epilogue_size;
848 commands_in_prologues += prologue_size;
849 commands_in_epilogues += epilogue_size;
853 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
854 machine for a memory operand of mode MODE. */
857 legitimate_address_p (mode, x, strict)
858 enum machine_mode mode;
862 enum reg_class r = NO_REGS;
864 if (TARGET_ALL_DEBUG)
866 fprintf (stderr, "mode: (%s) %s %s %s %s:",
868 strict ? "(strict)": "",
869 reload_completed ? "(reload_completed)": "",
870 reload_in_progress ? "(reload_in_progress)": "",
871 reg_renumber ? "(reg_renumber)" : "");
872 if (GET_CODE (x) == PLUS
873 && REG_P (XEXP (x, 0))
874 && GET_CODE (XEXP (x, 1)) == CONST_INT
875 && INTVAL (XEXP (x, 1)) >= 0
876 && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
879 fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
880 true_regnum (XEXP (x, 0)));
883 if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
884 : REG_OK_FOR_BASE_NOSTRICT_P (x)))
886 else if (CONSTANT_ADDRESS_P (x))
888 else if (GET_CODE (x) == PLUS
889 && REG_P (XEXP (x, 0))
890 && GET_CODE (XEXP (x, 1)) == CONST_INT
891 && INTVAL (XEXP (x, 1)) >= 0)
893 int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
897 || REGNO (XEXP (x,0)) == REG_Y
898 || REGNO (XEXP (x,0)) == REG_Z)
899 r = BASE_POINTER_REGS;
900 if (XEXP (x,0) == frame_pointer_rtx
901 || XEXP (x,0) == arg_pointer_rtx)
902 r = BASE_POINTER_REGS;
904 else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
907 else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
908 && REG_P (XEXP (x, 0))
909 && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
910 : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
914 if (TARGET_ALL_DEBUG)
916 fprintf (stderr, " ret = %c\n", r);
918 return r == NO_REGS ? 0 : (int)r;
921 /* Attempts to replace X with a valid
922 memory address for an operand of mode MODE */
925 legitimize_address (x, oldx, mode)
928 enum machine_mode mode;
931 if (TARGET_ALL_DEBUG)
933 fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
937 if (GET_CODE (oldx) == PLUS
938 && REG_P (XEXP (oldx,0)))
940 if (REG_P (XEXP (oldx,1)))
941 x = force_reg (GET_MODE (oldx), oldx);
942 else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
944 int offs = INTVAL (XEXP (oldx,1));
945 if (frame_pointer_rtx != XEXP (oldx,0))
946 if (offs > MAX_LD_OFFSET (mode))
948 if (TARGET_ALL_DEBUG)
949 fprintf (stderr, "force_reg (big offset)\n");
950 x = force_reg (GET_MODE (oldx), oldx);
958 /* Return a pointer register name as a string */
961 ptrreg_to_str (regno)
966 case REG_X: return "X";
967 case REG_Y: return "Y";
968 case REG_Z: return "Z";
975 /* Return the condition name as a string.
976 Used in conditional jump constructing */
989 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
994 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1007 /* Output ADDR to FILE as address */
1010 print_operand_address (file, addr)
1014 switch (GET_CODE (addr))
1017 fprintf (file, ptrreg_to_str (REGNO (addr)));
1021 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1025 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1029 if (CONSTANT_ADDRESS_P (addr)
1030 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
1031 || GET_CODE (addr) == LABEL_REF))
1033 fprintf (file, "pm(");
1034 output_addr_const (file,addr);
1035 fprintf (file ,")");
1038 output_addr_const (file, addr);
1043 /* Output X as assembler operand to file FILE */
1046 print_operand (file, x, code)
1053 if (code >= 'A' && code <= 'D')
1063 if (x == zero_reg_rtx)
1064 fprintf (file, "__zero_reg__");
1066 fprintf (file, reg_names[true_regnum (x) + abcd]);
1068 else if (GET_CODE (x) == CONST_INT)
1069 fprintf (file, "%d", INTVAL (x) + abcd);
1070 else if (GET_CODE (x) == MEM)
1072 rtx addr = XEXP (x,0);
1074 if (CONSTANT_P (addr) && abcd)
1077 output_address (addr);
1078 fprintf (file, ")+%d", abcd);
1080 else if (code == 'o')
1082 if (GET_CODE (addr) != PLUS)
1083 fatal_insn ("bad address, not (reg+disp):", addr);
1085 print_operand (file, XEXP (addr, 1), 0);
1087 else if (GET_CODE (addr) == PLUS)
1089 print_operand_address (file, XEXP (addr,0));
1090 if (REGNO (XEXP (addr, 0)) == REG_X)
1091 fatal_insn ("internal compiler error. Bad address:"
1094 print_operand (file, XEXP (addr,1), code);
1097 print_operand_address (file, addr);
1099 else if (GET_CODE (x) == CONST_DOUBLE)
1103 if (GET_MODE (x) != SFmode)
1104 fatal_insn ("internal compiler error. Unknown mode:", x);
1105 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1106 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1107 asm_fprintf (file, "0x%lx", val);
1109 else if (code == 'j')
1110 asm_fprintf (file, cond_string (GET_CODE (x)));
1111 else if (code == 'k')
1112 asm_fprintf (file, cond_string (reverse_condition (GET_CODE (x))));
1114 print_operand_address (file, x);
1117 /* Recognize operand OP of mode MODE used in call instructions */
1120 call_insn_operand (op, mode)
1122 enum machine_mode mode ATTRIBUTE_UNUSED;
1124 if (GET_CODE (op) == MEM)
1126 rtx inside = XEXP (op, 0);
1127 if (register_operand (inside, Pmode))
1129 if (CONSTANT_ADDRESS_P (inside))
1135 /* Update the condition code in the INSN. */
1138 notice_update_cc (body, insn)
1139 rtx body ATTRIBUTE_UNUSED;
1144 switch (get_attr_cc (insn))
1147 /* Insn does not affect CC at all. */
1155 set = single_set (insn);
1159 cc_status.flags |= CC_NO_OVERFLOW;
1160 cc_status.value1 = SET_DEST (set);
1165 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1166 The V flag may or may not be known but that's ok because
1167 alter_cond will change tests to use EQ/NE. */
1168 set = single_set (insn);
1172 cc_status.value1 = SET_DEST (set);
1173 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1178 set = single_set (insn);
1181 cc_status.value1 = SET_SRC (set);
1185 /* Insn doesn't leave CC in a usable state. */
1188 /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1189 set = single_set (insn);
1192 rtx src = SET_SRC (set);
1194 if (GET_CODE (src) == ASHIFTRT
1195 && GET_MODE (src) == QImode)
1197 rtx x = XEXP (src, 1);
1199 if (GET_CODE (x) == CONST_INT
1202 cc_status.value1 = SET_DEST (set);
1203 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1211 /* Return maximum number of consecutive registers of
1212 class CLASS needed to hold a value of mode MODE. */
1215 class_max_nregs (class, mode)
1216 enum reg_class class ATTRIBUTE_UNUSED;
1217 enum machine_mode mode;
1219 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1222 /* Choose mode for jump insn:
1223 1 - relative jump in range -63 <= x <= 62 ;
1224 2 - relative jump in range -2046 <= x <= 2045 ;
1225 3 - absolute jump (only for ATmega[16]03). */
1228 avr_jump_mode (x, insn)
1229 rtx x; /* jump operand */
1230 rtx insn; /* jump insn */
1232 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1233 ? XEXP (x, 0) : x));
1234 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1235 int jump_distance = cur_addr - dest_addr;
1237 if (-63 <= jump_distance && jump_distance <= 62)
1239 else if (-2046 <= jump_distance && jump_distance <= 2045)
1247 /* return an AVR condition jump commands.
1248 X is a comparison RTX.
1249 LEN is a number returned by avr_jump_mode function.
1250 if REVERSE nonzero then condition code in X must be reversed. */
1253 ret_cond_branch (x, len, reverse)
1258 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1263 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1264 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1266 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1267 AS1 (brmi,_PC_+2) CR_TAB
1269 (AS1 (breq,_PC_+6) CR_TAB
1270 AS1 (brmi,_PC_+4) CR_TAB
1274 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1276 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1277 AS1 (brlt,_PC_+2) CR_TAB
1279 (AS1 (breq,_PC_+6) CR_TAB
1280 AS1 (brlt,_PC_+4) CR_TAB
1283 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1285 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1286 AS1 (brlo,_PC_+2) CR_TAB
1288 (AS1 (breq,_PC_+6) CR_TAB
1289 AS1 (brlo,_PC_+4) CR_TAB
1292 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1293 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1295 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1296 AS1 (brpl,_PC_+2) CR_TAB
1298 (AS1 (breq,_PC_+2) CR_TAB
1299 AS1 (brpl,_PC_+4) CR_TAB
1302 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1304 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1305 AS1 (brge,_PC_+2) CR_TAB
1307 (AS1 (breq,_PC_+2) CR_TAB
1308 AS1 (brge,_PC_+4) CR_TAB
1311 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1313 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1314 AS1 (brsh,_PC_+2) CR_TAB
1316 (AS1 (breq,_PC_+2) CR_TAB
1317 AS1 (brsh,_PC_+4) CR_TAB
1325 return AS1 (br%k1,%0);
1327 return (AS1 (br%j1,_PC_+2) CR_TAB
1330 return (AS1 (br%j1,_PC_+4) CR_TAB
1339 return AS1 (br%j1,%0);
1341 return (AS1 (br%k1,_PC_+2) CR_TAB
1344 return (AS1 (br%k1,_PC_+4) CR_TAB
1352 /* Predicate function for immediate operand which fits to byte (8bit) */
1355 byte_immediate_operand (op, mode)
1357 enum machine_mode mode ATTRIBUTE_UNUSED;
1359 return (GET_CODE (op) == CONST_INT
1360 && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1363 /* Output all insn addresses and their sizes into the assembly language
1364 output file. This is helpful for debugging whether the length attributes
1365 in the md file are correct.
1366 Output insn cost for next insn. */
1369 final_prescan_insn (insn, operand, num_operands)
1370 rtx insn, *operand ATTRIBUTE_UNUSED;
1371 int num_operands ATTRIBUTE_UNUSED;
1373 int uid = INSN_UID (insn);
1375 if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1377 fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1378 INSN_ADDRESSES (uid),
1379 INSN_ADDRESSES (uid) - last_insn_address,
1380 rtx_cost (PATTERN (insn), INSN));
1382 last_insn_address = INSN_ADDRESSES (uid);
1384 if (TARGET_RTL_DUMP)
1386 fprintf (asm_out_file, "/*****************\n");
1387 print_rtl_single (asm_out_file, insn);
1388 fprintf (asm_out_file, "*****************/\n");
1392 /* Return 0 if undefined, 1 if always true or always false. */
1395 avr_simplify_comparision_p (mode, operator, x)
1396 enum machine_mode mode;
1400 unsigned int max = (mode == QImode ? 0xff :
1401 mode == HImode ? 0xffff :
1402 mode == SImode ? 0xffffffff : 0);
1403 if (max && operator && GET_CODE (x) == CONST_INT)
1405 if (unsigned_condition (operator) != operator)
1408 if (max != (INTVAL (x) & max)
1409 && INTVAL (x) != 0xff)
1416 /* Returns nonzero if REGNO is the number of a hard
1417 register in which function arguments are sometimes passed. */
1420 function_arg_regno_p(r)
1423 return (r >= 8 && r <= 25);
1426 /* Initializing the variable cum for the state at the beginning
1427 of the argument list. */
1430 init_cumulative_args (cum, fntype, libname, indirect)
1431 CUMULATIVE_ARGS *cum;
1434 int indirect ATTRIBUTE_UNUSED;
1437 cum->regno = FIRST_CUM_REG;
1440 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1441 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1442 != void_type_node));
1448 /* Returns the number of registers to allocate for a function argument. */
1451 avr_num_arg_regs (mode, type)
1452 enum machine_mode mode;
1457 if (mode == BLKmode)
1458 size = int_size_in_bytes (type);
1460 size = GET_MODE_SIZE (mode);
1462 /* Align all function arguments to start in even-numbered registers.
1463 Odd-sized arguments leave holes above them. */
1465 return (size + 1) & ~1;
1468 /* Controls whether a function argument is passed
1469 in a register, and which register. */
1472 function_arg (cum, mode, type, named)
1473 CUMULATIVE_ARGS *cum;
1474 enum machine_mode mode;
1476 int named ATTRIBUTE_UNUSED;
1478 int bytes = avr_num_arg_regs (mode, type);
1480 if (cum->nregs && bytes <= cum->nregs)
1481 return gen_rtx (REG, mode, cum->regno - bytes);
1486 /* Update the summarizer variable CUM to advance past an argument
1487 in the argument list. */
1490 function_arg_advance (cum, mode, type, named)
1491 CUMULATIVE_ARGS *cum; /* current arg information */
1492 enum machine_mode mode; /* current arg mode */
1493 tree type; /* type of the argument or 0 if lib support */
1494 int named ATTRIBUTE_UNUSED; /* whether or not the argument was named */
1496 int bytes = avr_num_arg_regs (mode, type);
1498 cum->nregs -= bytes;
1499 cum->regno -= bytes;
1501 if (cum->nregs <= 0)
1504 cum->regno = FIRST_CUM_REG;
1508 /***********************************************************************
1509 Functions for outputting various mov's for a various modes
1510 ************************************************************************/
1512 output_movqi (insn, operands, l)
1518 rtx dest = operands[0];
1519 rtx src = operands[1];
1527 if (register_operand (dest, QImode))
1529 if (register_operand (src, QImode)) /* mov r,r */
1531 if (test_hard_reg_class (STACK_REG, dest))
1532 return AS2 (out,%0,%1);
1533 else if (test_hard_reg_class (STACK_REG, src))
1534 return AS2 (in,%0,%1);
1536 return AS2 (mov,%0,%1);
1538 else if (CONSTANT_P (src))
1540 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1541 return AS2 (ldi,%0,lo8(%1));
1543 if (GET_CODE (src) == CONST_INT)
1545 if (src == const0_rtx) /* mov r,L */
1546 return AS1 (clr,%0);
1547 else if (src == const1_rtx)
1549 if (reg_was_0 (insn, dest))
1550 return AS1 (inc,%0 ; reg_was_0);
1553 return (AS1 (clr,%0) CR_TAB
1556 else if (src == constm1_rtx)
1558 /* Immediate constants -1 to any register */
1559 if (reg_was_0 (insn, dest))
1560 return AS1 (dec,%0 ; reg_was_0);
1563 return (AS1 (clr,%0) CR_TAB
1568 int bit_nr = exact_log2 (INTVAL (src));
1572 if (reg_was_0 (insn, dest))
1576 output_asm_insn ("set ; reg_was_0", operands);
1582 output_asm_insn ((AS1 (clr,%0) CR_TAB
1586 avr_output_bld (operands, bit_nr);
1593 /* Last resort, larger than loading from memory. */
1595 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1596 AS2 (ldi,r31,lo8(%1)) CR_TAB
1597 AS2 (mov,%0,r31) CR_TAB
1598 AS2 (mov,r31,__tmp_reg__));
1600 else if (GET_CODE (src) == MEM)
1601 return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1603 else if (GET_CODE (dest) == MEM)
1605 const char *template;
1607 if (src == const0_rtx)
1608 operands[1] = zero_reg_rtx;
1610 template = out_movqi_mr_r (insn, operands, real_l);
1613 output_asm_insn (template, operands);
1622 output_movhi (insn, operands, l)
1628 rtx dest = operands[0];
1629 rtx src = operands[1];
1635 if (register_operand (dest, HImode))
1637 if (register_operand (src, HImode)) /* mov r,r */
1639 if (test_hard_reg_class (STACK_REG, dest))
1641 if (TARGET_TINY_STACK)
1644 return AS2 (out,__SP_L__,%A1);
1646 else if (TARGET_NO_INTERRUPTS)
1649 return (AS2 (out,__SP_H__,%B1) CR_TAB
1650 AS2 (out,__SP_L__,%A1));
1654 return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB
1656 AS2 (out,__SP_H__,%B1) CR_TAB
1657 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1658 AS2 (out,__SP_L__,%A1));
1660 else if (test_hard_reg_class (STACK_REG, src))
1663 return (AS2 (in,%A0,__SP_L__) CR_TAB
1664 AS2 (in,%B0,__SP_H__));
1670 return (AS2 (movw,%0,%1));
1673 if (true_regnum (dest) > true_regnum (src))
1676 return (AS2 (mov,%B0,%B1) CR_TAB
1682 return (AS2 (mov,%A0,%A1) CR_TAB
1686 else if (CONSTANT_P (src))
1688 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1690 if (byte_immediate_operand (src, HImode)
1691 && reg_was_0 (insn, dest))
1694 return (AS2 (ldi,%A0,lo8(%1) ; reg_was_0));
1698 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1699 AS2 (ldi,%B0,hi8(%1)));
1702 if (GET_CODE (src) == CONST_INT)
1704 if (src == const0_rtx) /* mov r,L */
1707 return (AS1 (clr,%A0) CR_TAB
1710 else if (src == const1_rtx)
1712 if (reg_was_0 (insn, dest))
1715 return AS1 (inc,%0 ; reg_was_0);
1719 return (AS1 (clr,%A0) CR_TAB
1720 AS1 (clr,%B0) CR_TAB
1723 else if (src == constm1_rtx)
1725 /* Immediate constants -1 to any register */
1726 if (reg_was_0 (insn, dest))
1729 return (AS1 (dec,%A0 ; reg_was_0) CR_TAB
1734 return (AS1 (clr,%0) CR_TAB
1735 AS1 (dec,%A0) CR_TAB
1740 int bit_nr = exact_log2 (INTVAL (src));
1744 if (reg_was_0 (insn, dest))
1748 output_asm_insn ("set ; reg_was_0", operands);
1754 output_asm_insn ((AS1 (clr,%A0) CR_TAB
1755 AS1 (clr,%B0) CR_TAB
1759 avr_output_bld (operands, bit_nr);
1765 if ((INTVAL (src) & 0xff) == 0)
1768 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1769 AS1 (clr,%A0) CR_TAB
1770 AS2 (ldi,r31,hi8(%1)) CR_TAB
1771 AS2 (mov,%B0,r31) CR_TAB
1772 AS2 (mov,r31,__tmp_reg__));
1774 else if ((INTVAL (src) & 0xff00) == 0)
1777 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1778 AS2 (ldi,r31,lo8(%1)) CR_TAB
1779 AS2 (mov,%A0,r31) CR_TAB
1780 AS1 (clr,%B0) CR_TAB
1781 AS2 (mov,r31,__tmp_reg__));
1785 /* Last resort, equal to loading from memory. */
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 AS2 (ldi,r31,hi8(%1)) CR_TAB
1791 AS2 (mov,%B0,r31) CR_TAB
1792 AS2 (mov,r31,__tmp_reg__));
1794 else if (GET_CODE (src) == MEM)
1795 return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1797 else if (GET_CODE (dest) == MEM)
1799 const char *template;
1801 if (src == const0_rtx)
1802 operands[1] = zero_reg_rtx;
1804 template = out_movhi_mr_r (insn, operands, real_l);
1807 output_asm_insn (template, operands);
1812 fatal_insn ("invalid insn:", insn);
1817 out_movqi_r_mr (insn, op, l)
1820 int *l; /* instruction length */
1824 rtx x = XEXP (src, 0);
1830 if (CONSTANT_ADDRESS_P (x))
1832 if (avr_io_address_p (x, 1))
1835 return AS2 (in,%0,%1-0x20);
1838 return AS2 (lds,%0,%1);
1840 /* memory access by reg+disp */
1841 else if (GET_CODE (x) == PLUS
1842 && REG_P (XEXP (x,0))
1843 && GET_CODE (XEXP (x,1)) == CONST_INT)
1845 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1847 int disp = INTVAL (XEXP (x,1));
1848 if (REGNO (XEXP (x,0)) != REG_Y)
1849 fatal_insn ("incorrect insn:",insn);
1851 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1852 return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
1853 AS2 (ldd,%0,Y+63) CR_TAB
1854 AS2 (sbiw,r28,%o1-63));
1856 return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1857 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1858 AS2 (ld,%0,Y) CR_TAB
1859 AS2 (subi,r28,lo8(%o1)) CR_TAB
1860 AS2 (sbci,r29,hi8(%o1)));
1862 else if (REGNO (XEXP (x,0)) == REG_X)
1864 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1865 it but I have this situation with extremal optimizing options. */
1866 if (reg_overlap_mentioned_p (dest, XEXP (x,0))
1867 || reg_unused_after (insn, XEXP (x,0)))
1868 return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
1871 return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
1872 AS2 (ld,%0,X) CR_TAB
1873 AS2 (sbiw,r26,%o1));
1876 return AS2 (ldd,%0,%1);
1879 return AS2 (ld,%0,%1);
1883 out_movhi_r_mr (insn, op, l)
1886 int *l; /* instruction length */
1890 rtx base = XEXP (src, 0);
1891 int reg_dest = true_regnum (dest);
1892 int reg_base = true_regnum (base);
1900 if (reg_dest == reg_base) /* R = (R) */
1903 return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1904 AS2 (ld,%B0,%1) CR_TAB
1905 AS2 (mov,%A0,__tmp_reg__));
1907 else if (reg_base == REG_X) /* (R26) */
1909 if (reg_unused_after (insn, base))
1912 return (AS2 (ld,%A0,X+) CR_TAB
1916 return (AS2 (ld,%A0,X+) CR_TAB
1917 AS2 (ld,%B0,X) CR_TAB
1923 return (AS2 (ld,%A0,%1) CR_TAB
1924 AS2 (ldd,%B0,%1+1));
1927 else if (GET_CODE (base) == PLUS) /* (R + i) */
1929 int disp = INTVAL (XEXP (base, 1));
1930 int reg_base = true_regnum (XEXP (base, 0));
1932 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
1934 if (REGNO (XEXP (base, 0)) != REG_Y)
1935 fatal_insn ("incorrect insn:",insn);
1937 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1938 return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
1939 AS2 (ldd,%A0,Y+62) CR_TAB
1940 AS2 (ldd,%B0,Y+63) CR_TAB
1941 AS2 (sbiw,r28,%o1-62));
1943 return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1944 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1945 AS2 (ld,%A0,Y) CR_TAB
1946 AS2 (ldd,%B0,Y+1) CR_TAB
1947 AS2 (subi,r28,lo8(%o1)) CR_TAB
1948 AS2 (sbci,r29,hi8(%o1)));
1950 if (reg_base == REG_X)
1952 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1953 it but I have this situation with extremal
1954 optimization options. */
1957 if (reg_base == reg_dest)
1958 return (AS2 (adiw,r26,%o1) CR_TAB
1959 AS2 (ld,__tmp_reg__,X+) CR_TAB
1960 AS2 (ld,%B0,X) CR_TAB
1961 AS2 (mov,%A0,__tmp_reg__));
1963 return (AS2 (adiw,r26,%o1) CR_TAB
1964 AS2 (ld,%A0,X+) CR_TAB
1965 AS2 (ld,%B0,X) CR_TAB
1966 AS2 (sbiw,r26,%o1+1));
1969 if (reg_base == reg_dest)
1972 return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
1973 AS2 (ldd,%B0,%B1) CR_TAB
1974 AS2 (mov,%A0,__tmp_reg__));
1978 return (AS2 (ldd,%A0,%A1) CR_TAB
1981 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
1983 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1984 fatal_insn ("incorrect insn:", insn);
1987 return (AS2 (ld,%B0,%1) CR_TAB
1990 else if (GET_CODE (base) == POST_INC) /* (R++) */
1992 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1993 fatal_insn ("incorrect insn:", insn);
1996 return (AS2 (ld,%A0,%1) CR_TAB
1999 else if (CONSTANT_ADDRESS_P (base))
2001 if (avr_io_address_p (base, 2))
2004 return (AS2 (in,%A0,%A1-0x20) CR_TAB
2005 AS2 (in,%B0,%B1-0x20));
2008 return (AS2 (lds,%A0,%A1) CR_TAB
2012 fatal_insn ("unknown move insn:",insn);
2017 out_movsi_r_mr (insn, op, l)
2020 int *l; /* instruction length */
2024 rtx base = XEXP (src, 0);
2025 int reg_dest = true_regnum (dest);
2026 int reg_base = true_regnum (base);
2034 if (reg_base == REG_X) /* (R26) */
2036 if (reg_dest == REG_X)
2037 /* "ld r26,-X" is undefined */
2038 return *l=7, (AS2 (adiw,r26,3) CR_TAB
2039 AS2 (ld,r29,X) CR_TAB
2040 AS2 (ld,r28,-X) CR_TAB
2041 AS2 (ld,__tmp_reg__,-X) CR_TAB
2042 AS2 (sbiw,r26,1) CR_TAB
2043 AS2 (ld,r26,X) CR_TAB
2044 AS2 (mov,r27,__tmp_reg__));
2045 else if (reg_dest == REG_X - 2)
2046 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2047 AS2 (ld,%B0,X+) CR_TAB
2048 AS2 (ld,__tmp_reg__,X+) CR_TAB
2049 AS2 (ld,%D0,X) CR_TAB
2050 AS2 (mov,%C0,__tmp_reg__));
2051 else if (reg_unused_after (insn, base))
2052 return *l=4, (AS2 (ld,%A0,X+) CR_TAB
2053 AS2 (ld,%B0,X+) CR_TAB
2054 AS2 (ld,%C0,X+) CR_TAB
2057 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2058 AS2 (ld,%B0,X+) CR_TAB
2059 AS2 (ld,%C0,X+) CR_TAB
2060 AS2 (ld,%D0,X) CR_TAB
2065 if (reg_dest == reg_base)
2066 return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
2067 AS2 (ldd,%C0,%1+2) CR_TAB
2068 AS2 (ldd,__tmp_reg__,%1+1) CR_TAB
2069 AS2 (ld,%A0,%1) CR_TAB
2070 AS2 (mov,%B0,__tmp_reg__));
2071 else if (reg_base == reg_dest + 2)
2072 return *l=5, (AS2 (ld ,%A0,%1) CR_TAB
2073 AS2 (ldd,%B0,%1+1) CR_TAB
2074 AS2 (ldd,__tmp_reg__,%1+2) CR_TAB
2075 AS2 (ldd,%D0,%1+3) CR_TAB
2076 AS2 (mov,%C0,__tmp_reg__));
2078 return *l=4, (AS2 (ld ,%A0,%1) CR_TAB
2079 AS2 (ldd,%B0,%1+1) CR_TAB
2080 AS2 (ldd,%C0,%1+2) CR_TAB
2081 AS2 (ldd,%D0,%1+3));
2084 else if (GET_CODE (base) == PLUS) /* (R + i) */
2086 int disp = INTVAL (XEXP (base, 1));
2088 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2090 if (REGNO (XEXP (base, 0)) != REG_Y)
2091 fatal_insn ("incorrect insn:",insn);
2093 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2094 return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2095 AS2 (ldd,%A0,Y+60) CR_TAB
2096 AS2 (ldd,%B0,Y+61) CR_TAB
2097 AS2 (ldd,%C0,Y+62) CR_TAB
2098 AS2 (ldd,%D0,Y+63) CR_TAB
2099 AS2 (sbiw,r28,%o1-60));
2101 return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2102 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2103 AS2 (ld,%A0,Y) CR_TAB
2104 AS2 (ldd,%B0,Y+1) CR_TAB
2105 AS2 (ldd,%C0,Y+2) CR_TAB
2106 AS2 (ldd,%D0,Y+3) CR_TAB
2107 AS2 (subi,r28,lo8(%o1)) CR_TAB
2108 AS2 (sbci,r29,hi8(%o1)));
2111 reg_base = true_regnum (XEXP (base, 0));
2112 if (reg_base == REG_X)
2115 if (reg_dest == REG_X)
2118 /* "ld r26,-X" is undefined */
2119 return (AS2 (adiw,r26,%o1+3) CR_TAB
2120 AS2 (ld,r29,X) CR_TAB
2121 AS2 (ld,r28,-X) CR_TAB
2122 AS2 (ld,__tmp_reg__,-X) CR_TAB
2123 AS2 (sbiw,r26,1) CR_TAB
2124 AS2 (ld,r26,X) CR_TAB
2125 AS2 (mov,r27,__tmp_reg__));
2128 if (reg_dest == REG_X - 2)
2129 return (AS2 (adiw,r26,%o1) CR_TAB
2130 AS2 (ld,r24,X+) CR_TAB
2131 AS2 (ld,r25,X+) CR_TAB
2132 AS2 (ld,__tmp_reg__,X+) CR_TAB
2133 AS2 (ld,r27,X) CR_TAB
2134 AS2 (mov,r26,__tmp_reg__));
2136 return (AS2 (adiw,r26,%o1) CR_TAB
2137 AS2 (ld,%A0,X+) CR_TAB
2138 AS2 (ld,%B0,X+) CR_TAB
2139 AS2 (ld,%C0,X+) CR_TAB
2140 AS2 (ld,%D0,X) CR_TAB
2141 AS2 (sbiw,r26,%o1+3));
2143 if (reg_dest == reg_base)
2144 return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2145 AS2 (ldd,%C0,%C1) CR_TAB
2146 AS2 (ldd,__tmp_reg__,%B1) CR_TAB
2147 AS2 (ldd,%A0,%A1) CR_TAB
2148 AS2 (mov,%B0,__tmp_reg__));
2149 else if (reg_dest == reg_base - 2)
2150 return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2151 AS2 (ldd,%B0,%B1) CR_TAB
2152 AS2 (ldd,__tmp_reg__,%C1) CR_TAB
2153 AS2 (ldd,%D0,%D1) CR_TAB
2154 AS2 (mov,%C0,__tmp_reg__));
2155 return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2156 AS2 (ldd,%B0,%B1) CR_TAB
2157 AS2 (ldd,%C0,%C1) CR_TAB
2160 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2161 return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2162 AS2 (ld,%C0,%1) CR_TAB
2163 AS2 (ld,%B0,%1) CR_TAB
2165 else if (GET_CODE (base) == POST_INC) /* (R++) */
2166 return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2167 AS2 (ld,%B0,%1) CR_TAB
2168 AS2 (ld,%C0,%1) CR_TAB
2170 else if (CONSTANT_ADDRESS_P (base))
2171 return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2172 AS2 (lds,%B0,%B1) CR_TAB
2173 AS2 (lds,%C0,%C1) CR_TAB
2176 fatal_insn ("unknown move insn:",insn);
2181 out_movsi_mr_r (insn, op, l)
2188 rtx base = XEXP (dest, 0);
2189 int reg_base = true_regnum (base);
2190 int reg_src = true_regnum (src);
2196 if (CONSTANT_ADDRESS_P (base))
2197 return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2198 AS2 (sts,%B0,%B1) CR_TAB
2199 AS2 (sts,%C0,%C1) CR_TAB
2201 if (reg_base > 0) /* (r) */
2203 if (reg_base == REG_X) /* (R26) */
2205 if (reg_src == REG_X)
2207 /* "st X+,r26" is undefined */
2208 if (reg_unused_after (insn, base))
2209 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2210 AS2 (st,X,r26) CR_TAB
2211 AS2 (adiw,r26,1) CR_TAB
2212 AS2 (st,X+,__tmp_reg__) CR_TAB
2213 AS2 (st,X+,r28) CR_TAB
2216 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2217 AS2 (st,X,r26) CR_TAB
2218 AS2 (adiw,r26,1) CR_TAB
2219 AS2 (st,X+,__tmp_reg__) CR_TAB
2220 AS2 (st,X+,r28) CR_TAB
2221 AS2 (st,X,r29) CR_TAB
2224 else if (reg_base == reg_src + 2)
2226 if (reg_unused_after (insn, base))
2227 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2228 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2229 AS2 (st,%0+,%A1) CR_TAB
2230 AS2 (st,%0+,%B1) CR_TAB
2231 AS2 (st,%0+,__zero_reg__) CR_TAB
2232 AS2 (st,%0,__tmp_reg__) CR_TAB
2233 AS1 (clr,__zero_reg__));
2235 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2236 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2237 AS2 (st,%0+,%A1) CR_TAB
2238 AS2 (st,%0+,%B1) CR_TAB
2239 AS2 (st,%0+,__zero_reg__) CR_TAB
2240 AS2 (st,%0,__tmp_reg__) CR_TAB
2241 AS1 (clr,__zero_reg__) CR_TAB
2244 return *l=5, (AS2 (st,%0+,%A1) CR_TAB
2245 AS2 (st,%0+,%B1) CR_TAB
2246 AS2 (st,%0+,%C1) CR_TAB
2247 AS2 (st,%0,%D1) CR_TAB
2251 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2252 AS2 (std,%0+1,%B1) CR_TAB
2253 AS2 (std,%0+2,%C1) CR_TAB
2254 AS2 (std,%0+3,%D1));
2256 else if (GET_CODE (base) == PLUS) /* (R + i) */
2258 int disp = INTVAL (XEXP (base, 1));
2259 reg_base = REGNO (XEXP (base, 0));
2260 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2262 if (reg_base != REG_Y)
2263 fatal_insn ("incorrect insn:",insn);
2265 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2266 return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2267 AS2 (std,Y+60,%A1) CR_TAB
2268 AS2 (std,Y+61,%B1) CR_TAB
2269 AS2 (std,Y+62,%C1) CR_TAB
2270 AS2 (std,Y+63,%D1) CR_TAB
2271 AS2 (sbiw,r28,%o0-60));
2273 return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2274 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2275 AS2 (st,Y,%A1) CR_TAB
2276 AS2 (std,Y+1,%B1) CR_TAB
2277 AS2 (std,Y+2,%C1) CR_TAB
2278 AS2 (std,Y+3,%D1) CR_TAB
2279 AS2 (subi,r28,lo8(%o0)) CR_TAB
2280 AS2 (sbci,r29,hi8(%o0)));
2282 if (reg_base == REG_X)
2285 if (reg_src == REG_X)
2288 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2289 AS2 (mov,__zero_reg__,r27) CR_TAB
2290 AS2 (adiw,r26,%o0) CR_TAB
2291 AS2 (st,X+,__tmp_reg__) CR_TAB
2292 AS2 (st,X+,__zero_reg__) CR_TAB
2293 AS2 (st,X+,r28) CR_TAB
2294 AS2 (st,X,r29) CR_TAB
2295 AS1 (clr,__zero_reg__) CR_TAB
2296 AS2 (sbiw,r26,%o0+3));
2298 else if (reg_src == REG_X - 2)
2301 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2302 AS2 (mov,__zero_reg__,r27) CR_TAB
2303 AS2 (adiw,r26,%o0) CR_TAB
2304 AS2 (st,X+,r24) CR_TAB
2305 AS2 (st,X+,r25) CR_TAB
2306 AS2 (st,X+,__tmp_reg__) CR_TAB
2307 AS2 (st,X,__zero_reg__) CR_TAB
2308 AS1 (clr,__zero_reg__) CR_TAB
2309 AS2 (sbiw,r26,%o0+3));
2312 return (AS2 (adiw,r26,%o0) CR_TAB
2313 AS2 (st,X+,%A1) CR_TAB
2314 AS2 (st,X+,%B1) CR_TAB
2315 AS2 (st,X+,%C1) CR_TAB
2316 AS2 (st,X,%D1) CR_TAB
2317 AS2 (sbiw,r26,%o0+3));
2319 return *l=4, (AS2 (std,%A0,%A1) CR_TAB
2320 AS2 (std,%B0,%B1) CR_TAB
2321 AS2 (std,%C0,%C1) CR_TAB
2324 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2325 return *l=4, (AS2 (st,%0,%D1) CR_TAB
2326 AS2 (st,%0,%C1) CR_TAB
2327 AS2 (st,%0,%B1) CR_TAB
2329 else if (GET_CODE (base) == POST_INC) /* (R++) */
2330 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2331 AS2 (st,%0,%B1) CR_TAB
2332 AS2 (st,%0,%C1) CR_TAB
2334 fatal_insn ("unknown move insn:",insn);
2339 output_movsisf(insn, operands, l)
2345 rtx dest = operands[0];
2346 rtx src = operands[1];
2352 if (register_operand (dest, VOIDmode))
2354 if (register_operand (src, VOIDmode)) /* mov r,r */
2356 if (true_regnum (dest) > true_regnum (src))
2361 return (AS2 (movw,%C0,%C1) CR_TAB
2362 AS2 (movw,%A0,%A1));
2365 return (AS2 (mov,%D0,%D1) CR_TAB
2366 AS2 (mov,%C0,%C1) CR_TAB
2367 AS2 (mov,%B0,%B1) CR_TAB
2375 return (AS2 (movw,%A0,%A1) CR_TAB
2376 AS2 (movw,%C0,%C1));
2379 return (AS2 (mov,%A0,%A1) CR_TAB
2380 AS2 (mov,%B0,%B1) CR_TAB
2381 AS2 (mov,%C0,%C1) CR_TAB
2385 else if (CONSTANT_P (src))
2387 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2389 if (byte_immediate_operand (src, SImode)
2390 && reg_was_0 (insn, dest))
2393 return (AS2 (ldi,%A0,lo8(%1) ; reg_was_0));
2397 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
2398 AS2 (ldi,%B0,hi8(%1)) CR_TAB
2399 AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2400 AS2 (ldi,%D0,hhi8(%1)));
2403 if (GET_CODE (src) == CONST_INT)
2405 const char *const clr_op0 =
2406 AVR_ENHANCED ? (AS1 (clr,%A0) CR_TAB
2407 AS1 (clr,%B0) CR_TAB
2409 : (AS1 (clr,%A0) CR_TAB
2410 AS1 (clr,%B0) CR_TAB
2411 AS1 (clr,%C0) CR_TAB
2414 if (src == const0_rtx) /* mov r,L */
2416 *l = AVR_ENHANCED ? 3 : 4;
2419 else if (src == const1_rtx)
2421 if (reg_was_0 (insn, dest))
2424 return AS1 (inc,%A0 ; reg_was_0);
2427 output_asm_insn (clr_op0, operands);
2428 *l = AVR_ENHANCED ? 4 : 5;
2429 return AS1 (inc,%A0);
2431 else if (src == constm1_rtx)
2433 /* Immediate constants -1 to any register */
2434 if (reg_was_0 (insn, dest))
2439 return (AS1 (dec,%A0) CR_TAB
2440 AS1 (dec,%B0) CR_TAB
2441 AS2 (movw,%C0,%A0));
2444 return (AS1 (dec,%D0 ; reg_was_0) CR_TAB
2445 AS1 (dec,%C0) CR_TAB
2446 AS1 (dec,%B0) CR_TAB
2452 return (AS1 (clr,%A0) CR_TAB
2453 AS1 (dec,%A0) CR_TAB
2454 AS2 (mov,%B0,%A0) CR_TAB
2455 AS2 (movw,%C0,%A0));
2458 return (AS1 (clr,%A0) CR_TAB
2459 AS1 (dec,%A0) CR_TAB
2460 AS2 (mov,%B0,%A0) CR_TAB
2461 AS2 (mov,%C0,%A0) CR_TAB
2466 int bit_nr = exact_log2 (INTVAL (src));
2470 if (reg_was_0 (insn, dest))
2474 output_asm_insn ("set ; reg_was_0", operands);
2478 *l = AVR_ENHANCED ? 5 : 6;
2481 output_asm_insn (clr_op0, operands);
2482 output_asm_insn ("set", operands);
2486 avr_output_bld (operands, bit_nr);
2493 /* Last resort, better than loading from memory. */
2495 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2496 AS2 (ldi,r31,lo8(%1)) CR_TAB
2497 AS2 (mov,%A0,r31) CR_TAB
2498 AS2 (ldi,r31,hi8(%1)) CR_TAB
2499 AS2 (mov,%B0,r31) CR_TAB
2500 AS2 (ldi,r31,hlo8(%1)) CR_TAB
2501 AS2 (mov,%C0,r31) CR_TAB
2502 AS2 (ldi,r31,hhi8(%1)) CR_TAB
2503 AS2 (mov,%D0,r31) CR_TAB
2504 AS2 (mov,r31,__tmp_reg__));
2506 else if (GET_CODE (src) == MEM)
2507 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2509 else if (GET_CODE (dest) == MEM)
2511 const char *template;
2513 if (src == const0_rtx)
2514 operands[1] = zero_reg_rtx;
2516 template = out_movsi_mr_r (insn, operands, real_l);
2519 output_asm_insn (template, operands);
2524 fatal_insn ("invalid insn:", insn);
2529 out_movqi_mr_r (insn, op, l)
2532 int *l; /* instruction length */
2536 rtx x = XEXP (dest, 0);
2542 if (CONSTANT_ADDRESS_P (x))
2544 if (avr_io_address_p (x, 1))
2547 return AS2 (out,%0-0x20,%1);
2550 return AS2 (sts,%0,%1);
2552 /* memory access by reg+disp */
2553 else if (GET_CODE (x) == PLUS
2554 && REG_P (XEXP (x,0))
2555 && GET_CODE (XEXP (x,1)) == CONST_INT)
2557 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2559 int disp = INTVAL (XEXP (x,1));
2560 if (REGNO (XEXP (x,0)) != REG_Y)
2561 fatal_insn ("incorrect insn:",insn);
2563 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2564 return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2565 AS2 (std,Y+63,%1) CR_TAB
2566 AS2 (sbiw,r28,%o0-63));
2568 return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2569 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2570 AS2 (st,Y,%1) CR_TAB
2571 AS2 (subi,r28,lo8(%o0)) CR_TAB
2572 AS2 (sbci,r29,hi8(%o0)));
2574 else if (REGNO (XEXP (x,0)) == REG_X)
2576 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2578 if (reg_unused_after (insn, XEXP (x,0)))
2579 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2580 AS2 (adiw,r26,%o0) CR_TAB
2581 AS2 (st,X,__tmp_reg__));
2583 return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2584 AS2 (adiw,r26,%o0) CR_TAB
2585 AS2 (st,X,__tmp_reg__) CR_TAB
2586 AS2 (sbiw,r26,%o0));
2590 if (reg_unused_after (insn, XEXP (x,0)))
2591 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2594 return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2595 AS2 (st,X,%1) CR_TAB
2596 AS2 (sbiw,r26,%o0));
2600 return AS2 (std,%0,%1);
2603 return AS2 (st,%0,%1);
2607 out_movhi_mr_r (insn, op, l)
2614 rtx base = XEXP (dest, 0);
2615 int reg_base = true_regnum (base);
2616 int reg_src = true_regnum (src);
2620 if (CONSTANT_ADDRESS_P (base))
2622 if (avr_io_address_p (base, 2))
2625 return (AS2 (out,%B0-0x20,%B1) CR_TAB
2626 AS2 (out,%A0-0x20,%A1));
2628 return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2633 if (reg_base == REG_X)
2635 if (reg_src == REG_X)
2637 /* "st X+,r26" is undefined */
2638 if (reg_unused_after (insn, src))
2639 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2640 AS2 (st,X,r26) CR_TAB
2641 AS2 (adiw,r26,1) CR_TAB
2642 AS2 (st,X,__tmp_reg__));
2644 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2645 AS2 (st,X,r26) CR_TAB
2646 AS2 (adiw,r26,1) CR_TAB
2647 AS2 (st,X,__tmp_reg__) CR_TAB
2652 if (reg_unused_after (insn, base))
2653 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2656 return *l=3, (AS2 (st ,X+,%A1) CR_TAB
2657 AS2 (st ,X,%B1) CR_TAB
2662 return *l=2, (AS2 (st ,%0,%A1) CR_TAB
2663 AS2 (std,%0+1,%B1));
2665 else if (GET_CODE (base) == PLUS)
2667 int disp = INTVAL (XEXP (base, 1));
2668 reg_base = REGNO (XEXP (base, 0));
2669 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2671 if (reg_base != REG_Y)
2672 fatal_insn ("incorrect insn:",insn);
2674 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2675 return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2676 AS2 (std,Y+62,%A1) CR_TAB
2677 AS2 (std,Y+63,%B1) CR_TAB
2678 AS2 (sbiw,r28,%o0-62));
2680 return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2681 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2682 AS2 (st,Y,%A1) CR_TAB
2683 AS2 (std,Y+1,%B1) CR_TAB
2684 AS2 (subi,r28,lo8(%o0)) CR_TAB
2685 AS2 (sbci,r29,hi8(%o0)));
2687 if (reg_base == REG_X)
2690 if (reg_src == REG_X)
2693 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2694 AS2 (mov,__zero_reg__,r27) CR_TAB
2695 AS2 (adiw,r26,%o0) CR_TAB
2696 AS2 (st,X+,__tmp_reg__) CR_TAB
2697 AS2 (st,X,__zero_reg__) CR_TAB
2698 AS1 (clr,__zero_reg__) CR_TAB
2699 AS2 (sbiw,r26,%o0+1));
2702 return (AS2 (adiw,r26,%o0) CR_TAB
2703 AS2 (st,X+,%A1) CR_TAB
2704 AS2 (st,X,%B1) CR_TAB
2705 AS2 (sbiw,r26,%o0+1));
2707 return *l=2, (AS2 (std,%A0,%A1) CR_TAB
2710 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2711 return *l=2, (AS2 (st,%0,%B1) CR_TAB
2713 else if (GET_CODE (base) == POST_INC) /* (R++) */
2714 return *l=2, (AS2 (st,%0,%A1) CR_TAB
2716 fatal_insn ("unknown move insn:",insn);
2720 /* Return 1 if frame pointer for current function required */
2723 frame_pointer_required_p ()
2725 return (current_function_calls_alloca
2726 || current_function_args_info.nregs == 0
2727 || current_function_varargs
2728 || get_frame_size () > 0);
2731 /* Returns the condition of compare insn INSN, or UNKNOWN. */
2734 compare_condition (insn)
2737 rtx next = next_real_insn (insn);
2738 RTX_CODE cond = UNKNOWN;
2739 if (next && GET_CODE (next) == JUMP_INSN)
2741 rtx pat = PATTERN (next);
2742 rtx src = SET_SRC (pat);
2743 rtx t = XEXP (src, 0);
2744 cond = GET_CODE (t);
2749 /* Returns nonzero if INSN is a tst insn that only tests the sign. */
2752 compare_sign_p (insn)
2755 RTX_CODE cond = compare_condition (insn);
2756 return (cond == GE || cond == LT);
2759 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
2760 that needs to be swapped (GT, GTU, LE, LEU). */
2763 compare_diff_p (insn)
2766 RTX_CODE cond = compare_condition (insn);
2767 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2770 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition. */
2776 RTX_CODE cond = compare_condition (insn);
2777 return (cond == EQ || cond == NE);
2781 /* Output test instruction for HImode */
2788 if (compare_sign_p (insn))
2791 return AS1 (tst,%B0);
2793 if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
2794 && compare_eq_p (insn))
2796 /* faster than sbiw if we can clobber the operand */
2798 return AS2 (or,%A0,%B0);
2800 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2803 return AS2 (sbiw,%0,0);
2806 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2807 AS2 (cpc,%B0,__zero_reg__));
2811 /* Output test instruction for SImode */
2818 if (compare_sign_p (insn))
2821 return AS1 (tst,%D0);
2823 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2826 return (AS2 (sbiw,%A0,0) CR_TAB
2827 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2828 AS2 (cpc,%D0,__zero_reg__));
2831 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2832 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2833 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2834 AS2 (cpc,%D0,__zero_reg__));
2838 /* Generate asm equivalent for various shifts.
2839 Shift count is a CONST_INT, MEM or REG.
2840 This only handles cases that are not already
2841 carefully hand-optimized in ?sh??i3_out. */
2844 out_shift_with_cnt (template, insn, operands, len, t_len)
2845 const char *template;
2849 int t_len; /* Length of template. */
2853 int second_label = 1;
2854 int saved_in_tmp = 0;
2855 int use_zero_reg = 0;
2857 op[0] = operands[0];
2858 op[1] = operands[1];
2859 op[2] = operands[2];
2860 op[3] = operands[3];
2866 if (GET_CODE (operands[2]) == CONST_INT)
2868 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2869 int count = INTVAL (operands[2]);
2870 int max_len = 10; /* If larger than this, always use a loop. */
2872 if (count < 8 && !scratch)
2876 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
2878 if (t_len * count <= max_len)
2880 /* Output shifts inline with no loop - faster. */
2882 *len = t_len * count;
2886 output_asm_insn (template, op);
2895 strcat (str, AS2 (ldi,%3,%2));
2897 else if (use_zero_reg)
2899 /* Hack to save one word: use __zero_reg__ as loop counter.
2900 Set one bit, then shift in a loop until it is 0 again. */
2902 op[3] = zero_reg_rtx;
2906 strcat (str, ("set" CR_TAB
2907 AS2 (bld,%3,%2-1)));
2911 /* No scratch register available, use one from LD_REGS (saved in
2912 __tmp_reg__) that doesn't overlap with registers to shift. */
2914 op[3] = gen_rtx (REG, QImode,
2915 ((true_regnum (operands[0]) - 1) & 15) + 16);
2916 op[4] = tmp_reg_rtx;
2920 *len = 3; /* Includes "mov %3,%4" after the loop. */
2922 strcat (str, (AS2 (mov,%4,%3) CR_TAB
2928 else if (GET_CODE (operands[2]) == MEM)
2932 op[3] = op_mov[0] = tmp_reg_rtx;
2936 out_movqi_r_mr (insn, op_mov, len);
2938 output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2940 else if (register_operand (operands[2], QImode))
2942 if (reg_unused_after (insn, operands[2]))
2946 op[3] = tmp_reg_rtx;
2948 strcat (str, (AS2 (mov,%3,%2) CR_TAB));
2952 fatal_insn ("bad shift insn:", insn);
2959 strcat (str, AS1 (rjmp,2f));
2963 *len += t_len + 2; /* template + dec + brXX */
2966 strcat (str, "\n1:\t");
2967 strcat (str, template);
2968 strcat (str, second_label ? "\n2:\t" : "\n\t");
2969 strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
2970 strcat (str, CR_TAB);
2971 strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
2973 strcat (str, (CR_TAB AS2 (mov,%3,%4)));
2974 output_asm_insn (str, op);
2979 /* 8bit shift left ((char)x << i) */
2982 ashlqi3_out (insn, operands, len)
2985 int *len; /* insn length (may be NULL) */
2987 if (GET_CODE (operands[2]) == CONST_INT)
2994 switch (INTVAL (operands[2]))
2998 return AS1 (clr,%0);
3002 return AS1 (lsl,%0);
3006 return (AS1 (lsl,%0) CR_TAB
3011 return (AS1 (lsl,%0) CR_TAB
3016 if (test_hard_reg_class (LD_REGS, operands[0]))
3019 return (AS1 (swap,%0) CR_TAB
3020 AS2 (andi,%0,0xf0));
3023 return (AS1 (lsl,%0) CR_TAB
3029 if (test_hard_reg_class (LD_REGS, operands[0]))
3032 return (AS1 (swap,%0) CR_TAB
3034 AS2 (andi,%0,0xe0));
3037 return (AS1 (lsl,%0) CR_TAB
3044 if (test_hard_reg_class (LD_REGS, operands[0]))
3047 return (AS1 (swap,%0) CR_TAB
3050 AS2 (andi,%0,0xc0));
3053 return (AS1 (lsl,%0) CR_TAB
3062 return (AS1 (ror,%0) CR_TAB
3067 else if (CONSTANT_P (operands[2]))
3068 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3070 out_shift_with_cnt (AS1 (lsl,%0),
3071 insn, operands, len, 1);
3076 /* 16bit shift left ((short)x << i) */
3079 ashlhi3_out (insn, operands, len)
3084 if (GET_CODE (operands[2]) == CONST_INT)
3086 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3087 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3094 switch (INTVAL (operands[2]))
3097 if (optimize_size && scratch)
3102 return (AS1 (swap,%A0) CR_TAB
3103 AS1 (swap,%B0) CR_TAB
3104 AS2 (andi,%B0,0xf0) CR_TAB
3105 AS2 (eor,%B0,%A0) CR_TAB
3106 AS2 (andi,%A0,0xf0) CR_TAB
3112 return (AS1 (swap,%A0) CR_TAB
3113 AS1 (swap,%B0) CR_TAB
3114 AS2 (ldi,%3,0xf0) CR_TAB
3115 AS2 (and,%B0,%3) CR_TAB
3116 AS2 (eor,%B0,%A0) CR_TAB
3117 AS2 (and,%A0,%3) CR_TAB
3120 break; /* optimize_size ? 6 : 8 */
3124 break; /* scratch ? 5 : 6 */
3128 return (AS1 (lsl,%A0) CR_TAB
3129 AS1 (rol,%B0) CR_TAB
3130 AS1 (swap,%A0) CR_TAB
3131 AS1 (swap,%B0) CR_TAB
3132 AS2 (andi,%B0,0xf0) CR_TAB
3133 AS2 (eor,%B0,%A0) CR_TAB
3134 AS2 (andi,%A0,0xf0) CR_TAB
3140 return (AS1 (lsl,%A0) CR_TAB
3141 AS1 (rol,%B0) CR_TAB
3142 AS1 (swap,%A0) CR_TAB
3143 AS1 (swap,%B0) CR_TAB
3144 AS2 (ldi,%3,0xf0) CR_TAB
3145 AS2 (and,%B0,%3) CR_TAB
3146 AS2 (eor,%B0,%A0) CR_TAB
3147 AS2 (and,%A0,%3) CR_TAB
3154 break; /* scratch ? 5 : 6 */
3156 return (AS1 (clr,__tmp_reg__) CR_TAB
3157 AS1 (lsr,%B0) CR_TAB
3158 AS1 (ror,%A0) CR_TAB
3159 AS1 (ror,__tmp_reg__) CR_TAB
3160 AS1 (lsr,%B0) CR_TAB
3161 AS1 (ror,%A0) CR_TAB
3162 AS1 (ror,__tmp_reg__) CR_TAB
3163 AS2 (mov,%B0,%A0) CR_TAB
3164 AS2 (mov,%A0,__tmp_reg__));
3168 return (AS1 (lsr,%B0) CR_TAB
3169 AS2 (mov,%B0,%A0) CR_TAB
3170 AS1 (clr,%A0) CR_TAB
3171 AS1 (ror,%B0) CR_TAB
3175 if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
3176 return *len = 1, AS1 (clr,%A0);
3178 return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3183 return (AS2 (mov,%B0,%A0) CR_TAB
3184 AS1 (clr,%A0) CR_TAB
3189 return (AS2 (mov,%B0,%A0) CR_TAB
3190 AS1 (clr,%A0) CR_TAB
3191 AS1 (lsl,%B0) CR_TAB
3196 return (AS2 (mov,%B0,%A0) CR_TAB
3197 AS1 (clr,%A0) CR_TAB
3198 AS1 (lsl,%B0) CR_TAB
3199 AS1 (lsl,%B0) CR_TAB
3206 return (AS2 (mov,%B0,%A0) CR_TAB
3207 AS1 (clr,%A0) CR_TAB
3208 AS1 (swap,%B0) CR_TAB
3209 AS2 (andi,%B0,0xf0));
3214 return (AS2 (mov,%B0,%A0) CR_TAB
3215 AS1 (clr,%A0) CR_TAB
3216 AS1 (swap,%B0) CR_TAB
3217 AS2 (ldi,%3,0xf0) CR_TAB
3221 return (AS2 (mov,%B0,%A0) CR_TAB
3222 AS1 (clr,%A0) CR_TAB
3223 AS1 (lsl,%B0) CR_TAB
3224 AS1 (lsl,%B0) CR_TAB
3225 AS1 (lsl,%B0) CR_TAB
3232 return (AS2 (mov,%B0,%A0) CR_TAB
3233 AS1 (clr,%A0) CR_TAB
3234 AS1 (swap,%B0) CR_TAB
3235 AS1 (lsl,%B0) CR_TAB
3236 AS2 (andi,%B0,0xe0));
3238 if (AVR_ENHANCED && scratch)
3241 return (AS2 (ldi,%3,0x20) CR_TAB
3242 AS2 (mul,%A0,%3) CR_TAB
3243 AS2 (mov,%B0,r0) CR_TAB
3244 AS1 (clr,%A0) CR_TAB
3245 AS1 (clr,__zero_reg__));
3247 if (optimize_size && scratch)
3252 return (AS2 (mov,%B0,%A0) CR_TAB
3253 AS1 (clr,%A0) CR_TAB
3254 AS1 (swap,%B0) CR_TAB
3255 AS1 (lsl,%B0) CR_TAB
3256 AS2 (ldi,%3,0xe0) CR_TAB
3262 return ("set" CR_TAB
3263 AS2 (bld,r1,5) CR_TAB
3264 AS2 (mul,%A0,r1) CR_TAB
3265 AS2 (mov,%B0,r0) CR_TAB
3266 AS1 (clr,%A0) CR_TAB
3267 AS1 (clr,__zero_reg__));
3270 return (AS2 (mov,%B0,%A0) CR_TAB
3271 AS1 (clr,%A0) CR_TAB
3272 AS1 (lsl,%B0) CR_TAB
3273 AS1 (lsl,%B0) CR_TAB
3274 AS1 (lsl,%B0) CR_TAB
3275 AS1 (lsl,%B0) CR_TAB
3279 if (AVR_ENHANCED && ldi_ok)
3282 return (AS2 (ldi,%B0,0x40) CR_TAB
3283 AS2 (mul,%A0,%B0) CR_TAB
3284 AS2 (mov,%B0,r0) CR_TAB
3285 AS1 (clr,%A0) CR_TAB
3286 AS1 (clr,__zero_reg__));
3288 if (AVR_ENHANCED && scratch)
3291 return (AS2 (ldi,%3,0x40) CR_TAB
3292 AS2 (mul,%A0,%3) CR_TAB
3293 AS2 (mov,%B0,r0) CR_TAB
3294 AS1 (clr,%A0) CR_TAB
3295 AS1 (clr,__zero_reg__));
3297 if (optimize_size && ldi_ok)
3300 return (AS2 (mov,%B0,%A0) CR_TAB
3301 AS2 (ldi,%A0,6) "\n1:\t"
3302 AS1 (lsl,%B0) CR_TAB
3303 AS1 (dec,%A0) CR_TAB
3306 if (optimize_size && scratch)
3309 return (AS1 (clr,%B0) CR_TAB
3310 AS1 (lsr,%A0) CR_TAB
3311 AS1 (ror,%B0) CR_TAB
3312 AS1 (lsr,%A0) CR_TAB
3313 AS1 (ror,%B0) CR_TAB
3318 return (AS1 (clr,%B0) CR_TAB
3319 AS1 (lsr,%A0) CR_TAB
3320 AS1 (ror,%B0) CR_TAB
3325 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3327 insn, operands, len, 2);
3332 /* 32bit shift left ((long)x << i) */
3335 ashlsi3_out (insn, operands, len)
3340 if (GET_CODE (operands[2]) == CONST_INT)
3348 switch (INTVAL (operands[2]))
3352 int reg0 = true_regnum (operands[0]);
3353 int reg1 = true_regnum (operands[1]);
3356 return (AS2 (mov,%D0,%C1) CR_TAB
3357 AS2 (mov,%C0,%B1) CR_TAB
3358 AS2 (mov,%B0,%A1) CR_TAB
3360 else if (reg0 + 1 == reg1)
3363 return AS1 (clr,%A0);
3366 return (AS1 (clr,%A0) CR_TAB
3367 AS2 (mov,%B0,%A1) CR_TAB
3368 AS2 (mov,%C0,%B1) CR_TAB
3374 int reg0 = true_regnum (operands[0]);
3375 int reg1 = true_regnum (operands[1]);
3377 if (AVR_ENHANCED && (reg0 + 2 != reg1))
3380 return (AS2 (movw,%C0,%A1) CR_TAB
3381 AS1 (clr,%B0) CR_TAB
3384 if (reg0 + 1 >= reg1)
3385 return (AS2 (mov,%D0,%B1) CR_TAB
3386 AS2 (mov,%C0,%A1) CR_TAB
3387 AS1 (clr,%B0) CR_TAB
3389 if (reg0 + 2 == reg1)
3392 return (AS1 (clr,%B0) CR_TAB
3396 return (AS2 (mov,%C0,%A1) CR_TAB
3397 AS2 (mov,%D0,%B1) CR_TAB
3398 AS1 (clr,%B0) CR_TAB
3404 if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
3405 return (AS2 (mov,%D0,%A1) CR_TAB
3406 AS1 (clr,%C0) CR_TAB
3407 AS1 (clr,%B0) CR_TAB
3412 return (AS1 (clr,%C0) CR_TAB
3413 AS1 (clr,%B0) CR_TAB
3419 return (AS1 (clr,%D0) CR_TAB
3420 AS1 (lsr,%A0) CR_TAB
3421 AS1 (ror,%D0) CR_TAB
3422 AS1 (clr,%C0) CR_TAB
3423 AS1 (clr,%B0) CR_TAB
3428 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3429 AS1 (rol,%B0) CR_TAB
3430 AS1 (rol,%C0) CR_TAB
3432 insn, operands, len, 4);
3436 /* 8bit arithmetic shift right ((signed char)x >> i) */
3439 ashrqi3_out (insn, operands, len)
3442 int *len; /* insn length */
3444 if (GET_CODE (operands[2]) == CONST_INT)
3451 switch (INTVAL (operands[2]))
3455 return AS1 (asr,%0);
3459 return (AS1 (asr,%0) CR_TAB
3464 return (AS1 (asr,%0) CR_TAB
3470 return (AS1 (asr,%0) CR_TAB
3477 return (AS1 (asr,%0) CR_TAB
3485 return (AS2 (bst,%0,6) CR_TAB
3487 AS2 (sbc,%0,%0) CR_TAB
3493 return (AS1 (lsl,%0) CR_TAB
3497 else if (CONSTANT_P (operands[2]))
3498 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3500 out_shift_with_cnt (AS1 (asr,%0),
3501 insn, operands, len, 1);
3506 /* 16bit arithmetic shift right ((signed short)x >> i) */
3509 ashrhi3_out (insn, operands, len)
3514 if (GET_CODE (operands[2]) == CONST_INT)
3516 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3517 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3524 switch (INTVAL (operands[2]))
3528 /* XXX try to optimize this too? */
3533 break; /* scratch ? 5 : 6 */
3535 return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3536 AS2 (mov,%A0,%B0) CR_TAB
3537 AS1 (lsl,__tmp_reg__) CR_TAB
3538 AS1 (rol,%A0) CR_TAB
3539 AS2 (sbc,%B0,%B0) CR_TAB
3540 AS1 (lsl,__tmp_reg__) CR_TAB
3541 AS1 (rol,%A0) CR_TAB
3546 return (AS1 (lsl,%A0) CR_TAB
3547 AS2 (mov,%A0,%B0) CR_TAB
3548 AS1 (rol,%A0) CR_TAB
3553 int reg0 = true_regnum (operands[0]);
3554 int reg1 = true_regnum (operands[1]);
3557 return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3558 AS1 (lsl,%B0) CR_TAB
3560 else if (reg0 == reg1 + 1)
3561 return *len = 3, (AS1 (clr,%B0) CR_TAB
3562 AS2 (sbrc,%A0,7) CR_TAB
3565 return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3566 AS1 (clr,%B0) CR_TAB
3567 AS2 (sbrc,%A0,7) CR_TAB
3573 return (AS2 (mov,%A0,%B0) CR_TAB
3574 AS1 (lsl,%B0) CR_TAB
3575 AS2 (sbc,%B0,%B0) CR_TAB
3580 return (AS2 (mov,%A0,%B0) CR_TAB
3581 AS1 (lsl,%B0) CR_TAB
3582 AS2 (sbc,%B0,%B0) CR_TAB
3583 AS1 (asr,%A0) CR_TAB
3587 if (AVR_ENHANCED && ldi_ok)
3590 return (AS2 (ldi,%A0,0x20) CR_TAB
3591 AS2 (muls,%B0,%A0) CR_TAB
3592 AS2 (mov,%A0,r1) CR_TAB
3593 AS2 (sbc,%B0,%B0) CR_TAB
3594 AS1 (clr,__zero_reg__));
3596 if (optimize_size && scratch)
3599 return (AS2 (mov,%A0,%B0) CR_TAB
3600 AS1 (lsl,%B0) CR_TAB
3601 AS2 (sbc,%B0,%B0) CR_TAB
3602 AS1 (asr,%A0) CR_TAB
3603 AS1 (asr,%A0) CR_TAB
3607 if (AVR_ENHANCED && ldi_ok)
3610 return (AS2 (ldi,%A0,0x10) CR_TAB
3611 AS2 (muls,%B0,%A0) CR_TAB
3612 AS2 (mov,%A0,r1) CR_TAB
3613 AS2 (sbc,%B0,%B0) CR_TAB
3614 AS1 (clr,__zero_reg__));
3616 if (optimize_size && scratch)
3619 return (AS2 (mov,%A0,%B0) CR_TAB
3620 AS1 (lsl,%B0) CR_TAB
3621 AS2 (sbc,%B0,%B0) CR_TAB
3622 AS1 (asr,%A0) CR_TAB
3623 AS1 (asr,%A0) CR_TAB
3624 AS1 (asr,%A0) CR_TAB
3628 if (AVR_ENHANCED && ldi_ok)
3631 return (AS2 (ldi,%A0,0x08) CR_TAB
3632 AS2 (muls,%B0,%A0) CR_TAB
3633 AS2 (mov,%A0,r1) CR_TAB
3634 AS2 (sbc,%B0,%B0) CR_TAB
3635 AS1 (clr,__zero_reg__));
3638 break; /* scratch ? 5 : 7 */
3640 return (AS2 (mov,%A0,%B0) CR_TAB
3641 AS1 (lsl,%B0) CR_TAB
3642 AS2 (sbc,%B0,%B0) CR_TAB
3643 AS1 (asr,%A0) CR_TAB
3644 AS1 (asr,%A0) CR_TAB
3645 AS1 (asr,%A0) CR_TAB
3646 AS1 (asr,%A0) CR_TAB
3651 return (AS1 (lsl,%B0) CR_TAB
3652 AS2 (sbc,%A0,%A0) CR_TAB
3653 AS1 (lsl,%B0) CR_TAB
3654 AS2 (mov,%B0,%A0) CR_TAB
3658 return *len = 3, (AS1 (lsl,%B0) CR_TAB
3659 AS2 (sbc,%A0,%A0) CR_TAB
3664 out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3666 insn, operands, len, 2);
3671 /* 32bit arithmetic shift right ((signed long)x >> i) */
3674 ashrsi3_out (insn, operands, len)
3679 if (GET_CODE (operands[2]) == CONST_INT)
3687 switch (INTVAL (operands[2]))
3691 int reg0 = true_regnum (operands[0]);
3692 int reg1 = true_regnum (operands[1]);
3695 return (AS2 (mov,%A0,%B1) CR_TAB
3696 AS2 (mov,%B0,%C1) CR_TAB
3697 AS2 (mov,%C0,%D1) CR_TAB
3698 AS1 (clr,%D0) CR_TAB
3699 AS2 (sbrc,%C0,7) CR_TAB
3701 else if (reg0 == reg1 + 1)
3704 return (AS1 (clr,%D0) CR_TAB
3705 AS2 (sbrc,%C0,7) CR_TAB
3709 return (AS1 (clr,%D0) CR_TAB
3710 AS2 (sbrc,%D1,7) CR_TAB
3711 AS1 (dec,%D0) CR_TAB
3712 AS2 (mov,%C0,%D1) CR_TAB
3713 AS2 (mov,%B0,%C1) CR_TAB
3719 int reg0 = true_regnum (operands[0]);
3720 int reg1 = true_regnum (operands[1]);
3722 if (AVR_ENHANCED && (reg0 != reg1 + 2))
3725 return (AS2 (movw,%A0,%C1) CR_TAB
3726 AS1 (clr,%D0) CR_TAB
3727 AS2 (sbrc,%B0,7) CR_TAB
3728 AS1 (com,%D0) CR_TAB
3731 if (reg0 <= reg1 + 1)
3732 return (AS2 (mov,%A0,%C1) CR_TAB
3733 AS2 (mov,%B0,%D1) CR_TAB
3734 AS1 (clr,%D0) CR_TAB
3735 AS2 (sbrc,%B0,7) CR_TAB
3736 AS1 (com,%D0) CR_TAB
3738 else if (reg0 == reg1 + 2)
3739 return *len = 4, (AS1 (clr,%D0) CR_TAB
3740 AS2 (sbrc,%B0,7) CR_TAB
3741 AS1 (com,%D0) CR_TAB
3744 return (AS2 (mov,%B0,%D1) CR_TAB
3745 AS2 (mov,%A0,%C1) CR_TAB
3746 AS1 (clr,%D0) CR_TAB
3747 AS2 (sbrc,%B0,7) CR_TAB
3748 AS1 (com,%D0) CR_TAB
3753 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3754 return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3755 AS1 (clr,%D0) CR_TAB
3756 AS2 (sbrc,%A0,7) CR_TAB
3757 AS1 (com,%D0) CR_TAB
3758 AS2 (mov,%B0,%D0) CR_TAB
3761 return *len = 5, (AS1 (clr,%D0) CR_TAB
3762 AS2 (sbrc,%A0,7) CR_TAB
3763 AS1 (com,%D0) CR_TAB
3764 AS2 (mov,%B0,%D0) CR_TAB
3769 return *len = 4, (AS1 (lsl,%D0) CR_TAB
3770 AS2 (sbc,%A0,%A0) CR_TAB
3771 AS2 (mov,%B0,%A0) CR_TAB
3772 AS2 (movw,%C0,%A0));
3774 return *len = 5, (AS1 (lsl,%D0) CR_TAB
3775 AS2 (sbc,%A0,%A0) CR_TAB
3776 AS2 (mov,%B0,%A0) CR_TAB
3777 AS2 (mov,%C0,%A0) CR_TAB
3782 out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
3783 AS1 (ror,%C0) CR_TAB
3784 AS1 (ror,%B0) CR_TAB
3786 insn, operands, len, 4);
3790 /* 8bit logic shift right ((unsigned char)x >> i) */
3793 lshrqi3_out (insn, operands, len)
3798 if (GET_CODE (operands[2]) == CONST_INT)
3805 switch (INTVAL (operands[2]))
3809 return AS1 (clr,%0);
3813 return AS1 (lsr,%0);
3817 return (AS1 (lsr,%0) CR_TAB
3821 return (AS1 (lsr,%0) CR_TAB
3826 if (test_hard_reg_class (LD_REGS, operands[0]))
3829 return (AS1 (swap,%0) CR_TAB
3830 AS2 (andi,%0,0x0f));
3833 return (AS1 (lsr,%0) CR_TAB
3839 if (test_hard_reg_class (LD_REGS, operands[0]))
3842 return (AS1 (swap,%0) CR_TAB
3847 return (AS1 (lsr,%0) CR_TAB
3854 if (test_hard_reg_class (LD_REGS, operands[0]))
3857 return (AS1 (swap,%0) CR_TAB
3863 return (AS1 (lsr,%0) CR_TAB
3872 return (AS1 (rol,%0) CR_TAB
3877 else if (CONSTANT_P (operands[2]))
3878 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3880 out_shift_with_cnt (AS1 (lsr,%0),
3881 insn, operands, len, 1);
3885 /* 16bit logic shift right ((unsigned short)x >> i) */
3888 lshrhi3_out (insn, operands, len)
3893 if (GET_CODE (operands[2]) == CONST_INT)
3895 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3896 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3903 switch (INTVAL (operands[2]))
3906 if (optimize_size && scratch)
3911 return (AS1 (swap,%B0) CR_TAB
3912 AS1 (swap,%A0) CR_TAB
3913 AS2 (andi,%A0,0x0f) CR_TAB
3914 AS2 (eor,%A0,%B0) CR_TAB
3915 AS2 (andi,%B0,0x0f) CR_TAB
3921 return (AS1 (swap,%B0) CR_TAB
3922 AS1 (swap,%A0) CR_TAB
3923 AS2 (ldi,%3,0x0f) CR_TAB
3924 AS2 (and,%A0,%3) CR_TAB
3925 AS2 (eor,%A0,%B0) CR_TAB
3926 AS2 (and,%B0,%3) CR_TAB
3929 break; /* optimize_size ? 6 : 8 */
3933 break; /* scratch ? 5 : 6 */
3937 return (AS1 (lsr,%B0) CR_TAB
3938 AS1 (ror,%A0) CR_TAB
3939 AS1 (swap,%B0) CR_TAB
3940 AS1 (swap,%A0) CR_TAB
3941 AS2 (andi,%A0,0x0f) CR_TAB
3942 AS2 (eor,%A0,%B0) CR_TAB
3943 AS2 (andi,%B0,0x0f) CR_TAB
3949 return (AS1 (lsr,%B0) CR_TAB
3950 AS1 (ror,%A0) CR_TAB
3951 AS1 (swap,%B0) CR_TAB
3952 AS1 (swap,%A0) CR_TAB
3953 AS2 (ldi,%3,0x0f) CR_TAB
3954 AS2 (and,%A0,%3) CR_TAB
3955 AS2 (eor,%A0,%B0) CR_TAB
3956 AS2 (and,%B0,%3) CR_TAB
3963 break; /* scratch ? 5 : 6 */
3965 return (AS1 (clr,__tmp_reg__) CR_TAB
3966 AS1 (lsl,%A0) CR_TAB
3967 AS1 (rol,%B0) CR_TAB
3968 AS1 (rol,__tmp_reg__) CR_TAB
3969 AS1 (lsl,%A0) CR_TAB
3970 AS1 (rol,%B0) CR_TAB
3971 AS1 (rol,__tmp_reg__) CR_TAB
3972 AS2 (mov,%A0,%B0) CR_TAB
3973 AS2 (mov,%B0,__tmp_reg__));
3977 return (AS1 (lsl,%A0) CR_TAB
3978 AS2 (mov,%A0,%B0) CR_TAB
3979 AS1 (rol,%A0) CR_TAB
3980 AS2 (sbc,%B0,%B0) CR_TAB
3984 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
3985 return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
3988 return *len = 1, AS1 (clr,%B0);
3992 return (AS2 (mov,%A0,%B0) CR_TAB
3993 AS1 (clr,%B0) CR_TAB
3998 return (AS2 (mov,%A0,%B0) CR_TAB
3999 AS1 (clr,%B0) CR_TAB
4000 AS1 (lsr,%A0) CR_TAB
4005 return (AS2 (mov,%A0,%B0) CR_TAB
4006 AS1 (clr,%B0) CR_TAB
4007 AS1 (lsr,%A0) CR_TAB
4008 AS1 (lsr,%A0) CR_TAB
4015 return (AS2 (mov,%A0,%B0) CR_TAB
4016 AS1 (clr,%B0) CR_TAB
4017 AS1 (swap,%A0) CR_TAB
4018 AS2 (andi,%A0,0x0f));
4023 return (AS2 (mov,%A0,%B0) CR_TAB
4024 AS1 (clr,%B0) CR_TAB
4025 AS1 (swap,%A0) CR_TAB
4026 AS2 (ldi,%3,0x0f) CR_TAB
4030 return (AS2 (mov,%A0,%B0) CR_TAB
4031 AS1 (clr,%B0) CR_TAB
4032 AS1 (lsr,%A0) CR_TAB
4033 AS1 (lsr,%A0) CR_TAB
4034 AS1 (lsr,%A0) CR_TAB
4041 return (AS2 (mov,%A0,%B0) CR_TAB
4042 AS1 (clr,%B0) CR_TAB
4043 AS1 (swap,%A0) CR_TAB
4044 AS1 (lsr,%A0) CR_TAB
4045 AS2 (andi,%A0,0x07));
4047 if (AVR_ENHANCED && scratch)
4050 return (AS2 (ldi,%3,0x08) CR_TAB
4051 AS2 (mul,%B0,%3) CR_TAB
4052 AS2 (mov,%A0,r1) CR_TAB
4053 AS1 (clr,%B0) CR_TAB
4054 AS1 (clr,__zero_reg__));
4056 if (optimize_size && scratch)
4061 return (AS2 (mov,%A0,%B0) CR_TAB
4062 AS1 (clr,%B0) CR_TAB
4063 AS1 (swap,%A0) CR_TAB
4064 AS1 (lsr,%A0) CR_TAB
4065 AS2 (ldi,%3,0x07) CR_TAB
4071 return ("set" CR_TAB
4072 AS2 (bld,r1,3) CR_TAB
4073 AS2 (mul,%B0,r1) CR_TAB
4074 AS2 (mov,%A0,r1) CR_TAB
4075 AS1 (clr,%B0) CR_TAB
4076 AS1 (clr,__zero_reg__));
4079 return (AS2 (mov,%A0,%B0) CR_TAB
4080 AS1 (clr,%B0) CR_TAB
4081 AS1 (lsr,%A0) CR_TAB
4082 AS1 (lsr,%A0) CR_TAB
4083 AS1 (lsr,%A0) CR_TAB
4084 AS1 (lsr,%A0) CR_TAB
4088 if (AVR_ENHANCED && ldi_ok)
4091 return (AS2 (ldi,%A0,0x04) CR_TAB
4092 AS2 (mul,%B0,%A0) CR_TAB
4093 AS2 (mov,%A0,r1) CR_TAB
4094 AS1 (clr,%B0) CR_TAB
4095 AS1 (clr,__zero_reg__));
4097 if (AVR_ENHANCED && scratch)
4100 return (AS2 (ldi,%3,0x04) CR_TAB
4101 AS2 (mul,%B0,%3) CR_TAB
4102 AS2 (mov,%A0,r1) CR_TAB
4103 AS1 (clr,%B0) CR_TAB
4104 AS1 (clr,__zero_reg__));
4106 if (optimize_size && ldi_ok)
4109 return (AS2 (mov,%A0,%B0) CR_TAB
4110 AS2 (ldi,%B0,6) "\n1:\t"
4111 AS1 (lsr,%A0) CR_TAB
4112 AS1 (dec,%B0) CR_TAB
4115 if (optimize_size && scratch)
4118 return (AS1 (clr,%A0) CR_TAB
4119 AS1 (lsl,%B0) CR_TAB
4120 AS1 (rol,%A0) CR_TAB
4121 AS1 (lsl,%B0) CR_TAB
4122 AS1 (rol,%A0) CR_TAB
4127 return (AS1 (clr,%A0) CR_TAB
4128 AS1 (lsl,%B0) CR_TAB
4129 AS1 (rol,%A0) CR_TAB
4134 out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
4136 insn, operands, len, 2);
4140 /* 32bit logic shift right ((unsigned int)x >> i) */
4143 lshrsi3_out (insn, operands, len)
4148 if (GET_CODE (operands[2]) == CONST_INT)
4156 switch (INTVAL (operands[2]))
4160 int reg0 = true_regnum (operands[0]);
4161 int reg1 = true_regnum (operands[1]);
4164 return (AS2 (mov,%A0,%B1) CR_TAB
4165 AS2 (mov,%B0,%C1) CR_TAB
4166 AS2 (mov,%C0,%D1) CR_TAB
4168 else if (reg0 == reg1 + 1)
4169 return *len = 1, AS1 (clr,%D0);
4171 return (AS1 (clr,%D0) CR_TAB
4172 AS2 (mov,%C0,%D1) CR_TAB
4173 AS2 (mov,%B0,%C1) CR_TAB
4179 int reg0 = true_regnum (operands[0]);
4180 int reg1 = true_regnum (operands[1]);
4182 if (AVR_ENHANCED && (reg0 != reg1 + 2))
4185 return (AS2 (movw,%A0,%C1) CR_TAB
4186 AS1 (clr,%C0) CR_TAB
4189 if (reg0 <= reg1 + 1)
4190 return (AS2 (mov,%A0,%C1) CR_TAB
4191 AS2 (mov,%B0,%D1) CR_TAB
4192 AS1 (clr,%C0) CR_TAB
4194 else if (reg0 == reg1 + 2)
4195 return *len = 2, (AS1 (clr,%C0) CR_TAB
4198 return (AS2 (mov,%B0,%D1) CR_TAB
4199 AS2 (mov,%A0,%C1) CR_TAB
4200 AS1 (clr,%C0) CR_TAB
4205 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
4206 return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4207 AS1 (clr,%B0) CR_TAB
4208 AS1 (clr,%C0) CR_TAB
4211 return *len = 3, (AS1 (clr,%B0) CR_TAB
4212 AS1 (clr,%C0) CR_TAB
4217 return (AS1 (clr,%A0) CR_TAB
4218 AS2 (sbrc,%D0,7) CR_TAB
4219 AS1 (inc,%A0) CR_TAB
4220 AS1 (clr,%B0) CR_TAB
4221 AS1 (clr,%C0) CR_TAB
4226 out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4227 AS1 (ror,%C0) CR_TAB
4228 AS1 (ror,%B0) CR_TAB
4230 insn, operands, len, 4);
4234 /* Modifies the length assigned to instruction INSN
4235 LEN is the initially computed length of the insn. */
4238 adjust_insn_length (insn, len)
4242 rtx patt = PATTERN (insn);
4245 if (GET_CODE (patt) == SET)
4248 op[1] = SET_SRC (patt);
4249 op[0] = SET_DEST (patt);
4250 if (general_operand (op[1], VOIDmode)
4251 && general_operand (op[0], VOIDmode))
4253 switch (GET_MODE (op[0]))
4256 output_movqi (insn, op, &len);
4259 output_movhi (insn, op, &len);
4263 output_movsisf (insn, op, &len);
4269 else if (op[0] == cc0_rtx && REG_P (op[1]))
4271 switch (GET_MODE (op[1]))
4273 case HImode: out_tsthi (insn,&len); break;
4274 case SImode: out_tstsi (insn,&len); break;
4278 else if (GET_CODE (op[1]) == AND)
4280 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4282 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4283 if (GET_MODE (op[1]) == SImode)
4284 len = (((mask & 0xff) != 0xff)
4285 + ((mask & 0xff00) != 0xff00)
4286 + ((mask & 0xff0000L) != 0xff0000L)
4287 + ((mask & 0xff000000L) != 0xff000000L));
4288 else if (GET_MODE (op[1]) == HImode)
4289 len = (((mask & 0xff) != 0xff)
4290 + ((mask & 0xff00) != 0xff00));
4293 else if (GET_CODE (op[1]) == IOR)
4295 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4297 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4298 if (GET_MODE (op[1]) == SImode)
4299 len = (((mask & 0xff) != 0)
4300 + ((mask & 0xff00) != 0)
4301 + ((mask & 0xff0000L) != 0)
4302 + ((mask & 0xff000000L) != 0));
4303 else if (GET_MODE (op[1]) == HImode)
4304 len = (((mask & 0xff) != 0)
4305 + ((mask & 0xff00) != 0));
4309 set = single_set (insn);
4314 op[1] = SET_SRC (set);
4315 op[0] = SET_DEST (set);
4317 if (GET_CODE (patt) == PARALLEL
4318 && general_operand (op[1], VOIDmode)
4319 && general_operand (op[0], VOIDmode))
4321 if (XVECLEN (patt, 0) == 2)
4322 op[2] = XVECEXP (patt, 0, 1);
4324 switch (GET_MODE (op[0]))
4330 output_reload_inhi (insn, op, &len);
4334 output_reload_insisf (insn, op, &len);
4340 else if (GET_CODE (op[1]) == ASHIFT
4341 || GET_CODE (op[1]) == ASHIFTRT
4342 || GET_CODE (op[1]) == LSHIFTRT)
4346 ops[1] = XEXP (op[1],0);
4347 ops[2] = XEXP (op[1],1);
4348 switch (GET_CODE (op[1]))
4351 switch (GET_MODE (op[0]))
4353 case QImode: ashlqi3_out (insn,ops,&len); break;
4354 case HImode: ashlhi3_out (insn,ops,&len); break;
4355 case SImode: ashlsi3_out (insn,ops,&len); break;
4360 switch (GET_MODE (op[0]))
4362 case QImode: ashrqi3_out (insn,ops,&len); break;
4363 case HImode: ashrhi3_out (insn,ops,&len); break;
4364 case SImode: ashrsi3_out (insn,ops,&len); break;
4369 switch (GET_MODE (op[0]))
4371 case QImode: lshrqi3_out (insn,ops,&len); break;
4372 case HImode: lshrhi3_out (insn,ops,&len); break;
4373 case SImode: lshrsi3_out (insn,ops,&len); break;
4385 /* Return non-zero if register REG dead after INSN */
4388 reg_unused_after (insn, reg)
4392 return (dead_or_set_p (insn, reg)
4393 || (REG_P(reg) && _reg_unused_after (insn, reg)));
4396 /* Return non-zero if REG is not used after INSN.
4397 We assume REG is a reload reg, and therefore does
4398 not live past labels. It may live past calls or jumps though. */
4401 _reg_unused_after (insn, reg)
4408 /* If the reg is set by this instruction, then it is safe for our
4409 case. Disregard the case where this is a store to memory, since
4410 we are checking a register used in the store address. */
4411 set = single_set (insn);
4412 if (set && GET_CODE (SET_DEST (set)) != MEM
4413 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4416 while ((insn = NEXT_INSN (insn)))
4418 code = GET_CODE (insn);
4421 /* If this is a label that existed before reload, then the register
4422 if dead here. However, if this is a label added by reorg, then
4423 the register may still be live here. We can't tell the difference,
4424 so we just ignore labels completely. */
4425 if (code == CODE_LABEL)
4430 if (code == JUMP_INSN)
4433 /* If this is a sequence, we must handle them all at once.
4434 We could have for instance a call that sets the target register,
4435 and an insn in a delay slot that uses the register. In this case,
4436 we must return 0. */
4437 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
4442 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
4444 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
4445 rtx set = single_set (this_insn);
4447 if (GET_CODE (this_insn) == CALL_INSN)
4449 else if (GET_CODE (this_insn) == JUMP_INSN)
4451 if (INSN_ANNULLED_BRANCH_P (this_insn))
4456 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4458 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4460 if (GET_CODE (SET_DEST (set)) != MEM)
4466 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
4471 else if (code == JUMP_INSN)
4475 if (code == CALL_INSN)
4478 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4479 if (GET_CODE (XEXP (tem, 0)) == USE
4480 && REG_P (XEXP (XEXP (tem, 0), 0))
4481 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
4483 if (call_used_regs[REGNO (reg)])
4487 if (GET_RTX_CLASS (code) == 'i')
4489 rtx set = single_set (insn);
4491 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4493 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4494 return GET_CODE (SET_DEST (set)) != MEM;
4495 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
4502 /* Target hook for assembling integer objects. The AVR version needs
4503 special handling for references to certain labels. */
4506 avr_assemble_integer (x, size, aligned_p)
4511 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
4512 && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FLAG (x))
4513 || GET_CODE (x) == LABEL_REF))
4515 fputs ("\t.word\tpm(", asm_out_file);
4516 output_addr_const (asm_out_file, x);
4517 fputs (")\n", asm_out_file);
4520 return default_assemble_integer (x, size, aligned_p);
4523 /* Sets section name for declaration DECL */
4526 avr_unique_section (decl, reloc)
4528 int reloc ATTRIBUTE_UNUSED;
4531 const char *name, *prefix;
4534 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
4535 name = (* targetm.strip_name_encoding) (name);
4537 if (TREE_CODE (decl) == FUNCTION_DECL)
4539 if (flag_function_sections)
4547 if (flag_function_sections)
4549 len = strlen (name) + strlen (prefix);
4550 string = alloca (len + 1);
4551 sprintf (string, "%s%s", prefix, name);
4552 DECL_SECTION_NAME (decl) = build_string (len, string);
4557 /* The routine used to output NUL terminated strings. We use a special
4558 version of this for most svr4 targets because doing so makes the
4559 generated assembly code more compact (and thus faster to assemble)
4560 as well as more readable, especially for targets like the i386
4561 (where the only alternative is to output character sequences as
4562 comma separated lists of numbers). */
4565 gas_output_limited_string(file, str)
4569 const unsigned char *_limited_str = (unsigned char *) str;
4571 fprintf (file, "%s\"", STRING_ASM_OP);
4572 for (; (ch = *_limited_str); _limited_str++)
4575 switch (escape = ESCAPES[ch])
4581 fprintf (file, "\\%03o", ch);
4585 putc (escape, file);
4589 fprintf (file, "\"\n");
4592 /* The routine used to output sequences of byte values. We use a special
4593 version of this for most svr4 targets because doing so makes the
4594 generated assembly code more compact (and thus faster to assemble)
4595 as well as more readable. Note that if we find subparts of the
4596 character sequence which end with NUL (and which are shorter than
4597 STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
4600 gas_output_ascii(file, str, length)
4605 const unsigned char *_ascii_bytes = (const unsigned char *) str;
4606 const unsigned char *limit = _ascii_bytes + length;
4607 unsigned bytes_in_chunk = 0;
4608 for (; _ascii_bytes < limit; _ascii_bytes++)
4610 const unsigned char *p;
4611 if (bytes_in_chunk >= 60)
4613 fprintf (file, "\"\n");
4616 for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
4618 if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
4620 if (bytes_in_chunk > 0)
4622 fprintf (file, "\"\n");
4625 gas_output_limited_string (file, (char*)_ascii_bytes);
4632 if (bytes_in_chunk == 0)
4633 fprintf (file, "\t.ascii\t\"");
4634 switch (escape = ESCAPES[ch = *_ascii_bytes])
4641 fprintf (file, "\\%03o", ch);
4642 bytes_in_chunk += 4;
4646 putc (escape, file);
4647 bytes_in_chunk += 2;
4652 if (bytes_in_chunk > 0)
4653 fprintf (file, "\"\n");
4656 /* Return value is nonzero if pseudos that have been
4657 assigned to registers of class CLASS would likely be spilled
4658 because registers of CLASS are needed for spill registers. */
4661 class_likely_spilled_p (c)
4664 return (c != ALL_REGS && c != ADDW_REGS);
4667 /* Valid attributes:
4668 progmem - put data to program memory;
4669 signal - make a function to be hardware interrupt. After function
4670 prologue interrupts are disabled;
4671 interrupt - make a function to be hardware interrupt. After function
4672 prologue interrupts are enabled;
4673 naked - don't generate function prologue/epilogue and `ret' command.
4675 Only `progmem' attribute valid for type. */
4677 const struct attribute_spec avr_attribute_table[] =
4679 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
4680 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute },
4681 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4682 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4683 { "naked", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4684 { NULL, 0, 0, false, false, false, NULL }
4687 /* Handle a "progmem" attribute; arguments as in
4688 struct attribute_spec.handler. */
4690 avr_handle_progmem_attribute (node, name, args, flags, no_add_attrs)
4693 tree args ATTRIBUTE_UNUSED;
4694 int flags ATTRIBUTE_UNUSED;
4699 if (TREE_CODE (*node) == TYPE_DECL)
4701 /* This is really a decl attribute, not a type attribute,
4702 but try to handle it for GCC 3.0 backwards compatibility. */
4704 tree type = TREE_TYPE (*node);
4705 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
4706 tree newtype = build_type_attribute_variant (type, attr);
4708 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
4709 TREE_TYPE (*node) = newtype;
4710 *no_add_attrs = true;
4712 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
4714 if (DECL_INITIAL (*node) == NULL_TREE && !DECL_EXTERNAL (*node))
4716 warning ("only initialized variables can be placed into "
4717 "program memory area");
4718 *no_add_attrs = true;
4723 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
4724 *no_add_attrs = true;
4731 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
4732 struct attribute_spec.handler. */
4734 avr_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
4737 tree args ATTRIBUTE_UNUSED;
4738 int flags ATTRIBUTE_UNUSED;
4741 if (TREE_CODE (*node) != FUNCTION_DECL)
4743 warning ("`%s' attribute only applies to functions",
4744 IDENTIFIER_POINTER (name));
4745 *no_add_attrs = true;
4751 /* Look for attribute `progmem' in DECL
4752 if found return 1, otherwise 0. */
4755 avr_progmem_p (decl)
4760 if (TREE_CODE (decl) != VAR_DECL)
4764 != lookup_attribute ("progmem", DECL_ATTRIBUTES (decl)))
4770 while (TREE_CODE (a) == ARRAY_TYPE);
4772 if (a == error_mark_node)
4775 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
4781 /* Encode section information about tree DECL. */
4784 avr_encode_section_info (decl, first)
4788 if (TREE_CODE (decl) == FUNCTION_DECL)
4789 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
4791 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
4792 && TREE_CODE (decl) == VAR_DECL
4793 && avr_progmem_p (decl))
4795 static const char *const dsec = ".progmem.data";
4796 DECL_SECTION_NAME (decl) = build_string (strlen (dsec), dsec);
4797 TREE_READONLY (decl) = 1;
4801 /* Outputs to the stdio stream FILE some
4802 appropriate text to go at the start of an assembler file. */
4805 asm_file_start (file)
4809 error ("MCU `%s' supported for assembler only", avr_mcu_name);
4811 output_file_directive (file, main_input_filename);
4812 fprintf (file, "\t.arch %s\n", avr_mcu_name);
4813 fputs ("__SREG__ = 0x3f\n"
4815 "__SP_L__ = 0x3d\n", file);
4817 fputs ("__tmp_reg__ = 0\n"
4818 "__zero_reg__ = 1\n"
4819 "_PC_ = 2\n", file);
4821 commands_in_file = 0;
4822 commands_in_prologues = 0;
4823 commands_in_epilogues = 0;
4826 /* Outputs to the stdio stream FILE some
4827 appropriate text to go at the end of an assembler file. */
4833 fputs ("/* File ", file);
4834 output_quoted_string (file, main_input_filename);
4836 ": code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
4839 commands_in_file - commands_in_prologues - commands_in_epilogues,
4840 commands_in_prologues, commands_in_epilogues);
4843 /* Choose the order in which to allocate hard registers for
4844 pseudo-registers local to a basic block.
4846 Store the desired register order in the array `reg_alloc_order'.
4847 Element 0 should be the register to allocate first; element 1, the
4848 next register; and so on. */
4851 order_regs_for_local_alloc ()
4854 static const int order_0[] = {
4862 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4866 static const int order_1[] = {
4874 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4878 static const int order_2[] = {
4887 15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4892 const int *order = (TARGET_ORDER_1 ? order_1 :
4893 TARGET_ORDER_2 ? order_2 :
4895 for (i=0; i < ARRAY_SIZE (order_0); ++i)
4896 reg_alloc_order[i] = order[i];
4899 /* Calculate the cost of X code of the expression in which it is contained,
4900 found in OUTER_CODE */
4903 default_rtx_costs (X, code, outer_code)
4906 enum rtx_code outer_code;
4913 cost = 2 * GET_MODE_SIZE (GET_MODE (X));
4916 if (outer_code != SET)
4918 if (GET_CODE (XEXP (X,0)) == SYMBOL_REF)
4919 cost += 2 * GET_MODE_SIZE (GET_MODE (X));
4921 cost += GET_MODE_SIZE (GET_MODE (X));
4927 if (outer_code == SET)
4928 cost = GET_MODE_SIZE (GET_MODE (X));
4930 cost = -GET_MODE_SIZE (GET_MODE (X));
4933 if (outer_code == SET)
4934 cost = GET_MODE_SIZE (GET_MODE (X));
4940 if (outer_code == SET)
4942 if (X == stack_pointer_rtx)
4944 else if (GET_CODE (XEXP (X,1)) == CONST_INT)
4945 cost = (INTVAL (XEXP (X,1)) <= 63 ? 1 :
4946 GET_MODE_SIZE (GET_MODE (X)));
4948 cost = GET_MODE_SIZE (GET_MODE (X));
4952 if (GET_CODE (XEXP (X,1)) == CONST_INT)
4953 cost = GET_MODE_SIZE (GET_MODE (XEXP (X,0)));
4961 /* Calculate the cost of a memory address */
4964 avr_address_cost (x)
4967 if (GET_CODE (x) == PLUS
4968 && GET_CODE (XEXP (x,1)) == CONST_INT
4969 && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
4970 && INTVAL (XEXP (x,1)) >= 61)
4972 if (CONSTANT_ADDRESS_P (x))
4974 if (avr_io_address_p (x, 1))
4981 /* EXTRA_CONSTRAINT helper */
4984 extra_constraint (x, c)
4989 && GET_CODE (x) == MEM
4990 && GET_CODE (XEXP (x,0)) == PLUS)
4992 if (TARGET_ALL_DEBUG)
4994 fprintf (stderr, ("extra_constraint:\n"
4995 "reload_completed: %d\n"
4996 "reload_in_progress: %d\n"),
4997 reload_completed, reload_in_progress);
5000 if (GET_CODE (x) == MEM
5001 && GET_CODE (XEXP (x,0)) == PLUS
5002 && REG_P (XEXP (XEXP (x,0), 0))
5003 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
5004 && (INTVAL (XEXP (XEXP (x,0), 1))
5005 <= MAX_LD_OFFSET (GET_MODE (x))))
5007 rtx xx = XEXP (XEXP (x,0), 0);
5008 int regno = REGNO (xx);
5009 if (TARGET_ALL_DEBUG)
5011 fprintf (stderr, ("extra_constraint:\n"
5012 "reload_completed: %d\n"
5013 "reload_in_progress: %d\n"),
5014 reload_completed, reload_in_progress);
5017 if (regno >= FIRST_PSEUDO_REGISTER)
5018 return 1; /* allocate pseudos */
5019 else if (regno == REG_Z || regno == REG_Y)
5020 return 1; /* strictly check */
5021 else if (xx == frame_pointer_rtx
5022 || xx == arg_pointer_rtx)
5023 return 1; /* XXX frame & arg pointer checks */
5029 /* Convert condition code CONDITION to the valid AVR condition code */
5032 avr_normalize_condition (condition)
5050 /* This fnction optimizes conditional jumps */
5053 machine_dependent_reorg (first_insn)
5058 for (insn = first_insn; insn; insn = NEXT_INSN (insn))
5060 if (! (GET_CODE (insn) == INSN
5061 || GET_CODE (insn) == CALL_INSN
5062 || GET_CODE (insn) == JUMP_INSN)
5063 || !single_set (insn))
5066 pattern = PATTERN (insn);
5068 if (GET_CODE (pattern) == PARALLEL)
5069 pattern = XVECEXP (pattern, 0, 0);
5070 if (GET_CODE (pattern) == SET
5071 && SET_DEST (pattern) == cc0_rtx
5072 && compare_diff_p (insn))
5074 if (GET_CODE (SET_SRC (pattern)) == COMPARE)
5076 /* Now we work under compare insn */
5078 pattern = SET_SRC (pattern);
5079 if (true_regnum (XEXP (pattern,0)) >= 0
5080 && true_regnum (XEXP (pattern,1)) >= 0 )
5082 rtx x = XEXP (pattern,0);
5083 rtx next = next_real_insn (insn);
5084 rtx pat = PATTERN (next);
5085 rtx src = SET_SRC (pat);
5086 rtx t = XEXP (src,0);
5087 PUT_CODE (t, swap_condition (GET_CODE (t)));
5088 XEXP (pattern,0) = XEXP (pattern,1);
5089 XEXP (pattern,1) = x;
5090 INSN_CODE (next) = -1;
5092 else if (true_regnum (XEXP (pattern,0)) >= 0
5093 && GET_CODE (XEXP (pattern,1)) == CONST_INT)
5095 rtx x = XEXP (pattern,1);
5096 rtx next = next_real_insn (insn);
5097 rtx pat = PATTERN (next);
5098 rtx src = SET_SRC (pat);
5099 rtx t = XEXP (src,0);
5100 enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
5102 if (avr_simplify_comparision_p (mode, GET_CODE (t), x))
5104 XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
5105 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
5106 INSN_CODE (next) = -1;
5107 INSN_CODE (insn) = -1;
5111 else if (true_regnum (SET_SRC (pattern)) >= 0)
5113 /* This is a tst insn */
5114 rtx next = next_real_insn (insn);
5115 rtx pat = PATTERN (next);
5116 rtx src = SET_SRC (pat);
5117 rtx t = XEXP (src,0);
5119 PUT_CODE (t, swap_condition (GET_CODE (t)));
5120 SET_SRC (pattern) = gen_rtx (NEG,
5121 GET_MODE (SET_SRC (pattern)),
5123 INSN_CODE (next) = -1;
5124 INSN_CODE (insn) = -1;
5130 /* Returns register number for function return value.*/
5138 /* Ceate an RTX representing the place where a
5139 library function returns a value of mode MODE. */
5142 avr_libcall_value (mode)
5143 enum machine_mode mode;
5145 int offs = GET_MODE_SIZE (mode);
5148 return gen_rtx (REG, mode, RET_REGISTER + 2 - offs);
5151 /* Create an RTX representing the place where a
5152 function returns a value of data type VALTYPE. */
5155 avr_function_value (type, func)
5157 tree func ATTRIBUTE_UNUSED;
5161 if (TYPE_MODE (type) != BLKmode)
5162 return avr_libcall_value (TYPE_MODE (type));
5164 offs = int_size_in_bytes (type);
5167 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
5168 offs = GET_MODE_SIZE (SImode);
5169 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
5170 offs = GET_MODE_SIZE (DImode);
5172 return gen_rtx (REG, BLKmode, RET_REGISTER + 2 - offs);
5175 /* Returns non-zero if the number MASK has only one bit set. */
5178 mask_one_bit_p (mask)
5182 unsigned HOST_WIDE_INT n=mask;
5183 for (i = 0; i < 32; ++i)
5185 if (n & 0x80000000L)
5187 if (n & 0x7fffffffL)
5198 /* Places additional restrictions on the register class to
5199 use when it is necessary to copy value X into a register
5203 preferred_reload_class (x, class)
5204 rtx x ATTRIBUTE_UNUSED;
5205 enum reg_class class;
5211 test_hard_reg_class (class, x)
5212 enum reg_class class;
5215 int regno = true_regnum (x);
5218 return TEST_HARD_REG_CLASS (class, regno);
5222 debug_hard_reg_set (set)
5226 for (i=0; i < FIRST_PSEUDO_REGISTER; ++i)
5228 if (TEST_HARD_REG_BIT (set, i))
5230 fprintf (stderr, "r%-2d ", i);
5233 fprintf (stderr, "\n");
5237 jump_over_one_insn_p (insn, dest)
5241 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
5244 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
5245 int dest_addr = INSN_ADDRESSES (uid);
5246 return dest_addr - jump_addr == get_attr_length (insn) + 1;
5249 /* Returns 1 if a value of mode MODE can be stored starting with hard
5250 register number REGNO. On the enhanced core, anything larger than
5251 1 byte must start in even numbered register for "movw" to work
5252 (this way we don't have to check for odd registers everywhere). */
5255 avr_hard_regno_mode_ok (regno, mode)
5257 enum machine_mode mode;
5259 /* Bug workaround: recog.c (peep2_find_free_register) and probably
5260 a few other places assume that the frame pointer is a single hard
5261 register, so r29 may be allocated and overwrite the high byte of
5262 the frame pointer. Do not allow any value to start in r29. */
5263 if (regno == REG_Y + 1)
5268 /* if (regno < 24 && !AVR_ENHANCED)
5270 return !(regno & 1);
5273 /* Returns 1 if we know register operand OP was 0 before INSN. */
5276 reg_was_0 (insn, op)
5281 return (optimize > 0 && insn && op && REG_P (op)
5282 && (link = find_reg_note (insn, REG_WAS_0, 0))
5283 /* Make sure the insn that stored the 0 is still present. */
5284 && ! INSN_DELETED_P (XEXP (link, 0))
5285 && GET_CODE (XEXP (link, 0)) != NOTE
5286 /* Make sure cross jumping didn't happen here. */
5287 && no_labels_between_p (XEXP (link, 0), insn)
5288 /* Make sure the reg hasn't been clobbered. */
5289 && ! reg_set_between_p (op, XEXP (link, 0), insn));
5292 /* Returns 1 if X is a valid address for an I/O register of size SIZE
5293 (1 or 2). Used for lds/sts -> in/out optimization. Add 0x20 to SIZE
5294 to check for the lower half of I/O space (for cbi/sbi/sbic/sbis). */
5297 avr_io_address_p (x, size)
5301 return (optimize > 0 && GET_CODE (x) == CONST_INT
5302 && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size);
5305 /* Returns nonzero (bit number + 1) if X, or -X, is a constant power of 2. */
5308 const_int_pow2_p (x)
5311 if (GET_CODE (x) == CONST_INT)
5313 HOST_WIDE_INT d = INTVAL (x);
5314 HOST_WIDE_INT abs_d = (d >= 0) ? d : -d;
5315 return exact_log2 (abs_d) + 1;
5321 output_reload_inhi (insn, operands, len)
5322 rtx insn ATTRIBUTE_UNUSED;
5330 if (GET_CODE (operands[1]) == CONST_INT)
5332 int val = INTVAL (operands[1]);
5333 if ((val & 0xff) == 0)
5336 return (AS2 (mov,%A0,__zero_reg__) CR_TAB
5337 AS2 (ldi,%2,hi8(%1)) CR_TAB
5340 else if ((val & 0xff00) == 0)
5343 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5344 AS2 (mov,%A0,%2) CR_TAB
5345 AS2 (mov,%B0,__zero_reg__));
5347 else if ((val & 0xff) == ((val & 0xff00) >> 8))
5350 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5351 AS2 (mov,%A0,%2) CR_TAB
5356 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5357 AS2 (mov,%A0,%2) CR_TAB
5358 AS2 (ldi,%2,hi8(%1)) CR_TAB
5364 output_reload_insisf (insn, operands, len)
5365 rtx insn ATTRIBUTE_UNUSED;
5369 rtx src = operands[1];
5370 int cnst = (GET_CODE (src) == CONST_INT);
5375 *len = 4 + ((INTVAL (src) & 0xff) != 0)
5376 + ((INTVAL (src) & 0xff00) != 0)
5377 + ((INTVAL (src) & 0xff0000) != 0)
5378 + ((INTVAL (src) & 0xff000000) != 0);
5385 if (cnst && ((INTVAL (src) & 0xff) == 0))
5386 output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
5389 output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
5390 output_asm_insn (AS2 (mov, %A0, %2), operands);
5392 if (cnst && ((INTVAL (src) & 0xff00) == 0))
5393 output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
5396 output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
5397 output_asm_insn (AS2 (mov, %B0, %2), operands);
5399 if (cnst && ((INTVAL (src) & 0xff0000) == 0))
5400 output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
5403 output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
5404 output_asm_insn (AS2 (mov, %C0, %2), operands);
5406 if (cnst && ((INTVAL (src) & 0xff000000) == 0))
5407 output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
5410 output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
5411 output_asm_insn (AS2 (mov, %D0, %2), operands);
5417 avr_output_bld (operands, bit_nr)
5421 static char s[] = "bld %A0,0";
5423 s[5] = 'A' + (bit_nr >> 3);
5424 s[8] = '0' + (bit_nr & 7);
5425 output_asm_insn (s, operands);
5429 avr_output_addr_vec_elt (stream, value)
5434 fprintf (stream, "\t.word pm(.L%d)\n", value);
5436 fprintf (stream, "\trjmp .L%d\n", value);
5441 /* Returns 1 if SCRATCH are safe to be allocated as a scratch
5442 registers (for a define_peephole2) in the current function. */
5445 avr_peep2_scratch_safe (scratch)
5448 if ((interrupt_function_p (current_function_decl)
5449 || signal_function_p (current_function_decl))
5450 && leaf_function_p ())
5452 int first_reg = true_regnum (scratch);
5453 int last_reg = first_reg + GET_MODE_SIZE (GET_MODE (scratch)) - 1;
5456 for (reg = first_reg; reg <= last_reg; reg++)
5458 if (!regs_ever_live[reg])
5465 /* Output a branch that tests a single bit of a register (QI, HI or SImode)
5466 or memory location in the I/O space (QImode only).
5468 Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
5469 Operand 1: register operand to test, or CONST_INT memory address.
5470 Operand 2: bit number (for QImode operand) or mask (HImode, SImode).
5471 Operand 3: label to jump to if the test is true. */
5474 avr_out_sbxx_branch (insn, operands)
5478 enum rtx_code comp = GET_CODE (operands[0]);
5479 int long_jump = (get_attr_length (insn) >= 4);
5480 int reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
5484 else if (comp == LT)
5488 comp = reverse_condition (comp);
5490 if (GET_CODE (operands[1]) == CONST_INT)
5492 if (INTVAL (operands[1]) < 0x40)
5495 output_asm_insn (AS2 (sbis,%1-0x20,%2), operands);
5497 output_asm_insn (AS2 (sbic,%1-0x20,%2), operands);
5501 output_asm_insn (AS2 (in,__tmp_reg__,%1-0x20), operands);
5503 output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands);
5505 output_asm_insn (AS2 (sbrc,__tmp_reg__,%2), operands);
5508 else /* GET_CODE (operands[1]) == REG */
5510 if (GET_MODE (operands[1]) == QImode)
5513 output_asm_insn (AS2 (sbrs,%1,%2), operands);
5515 output_asm_insn (AS2 (sbrc,%1,%2), operands);
5517 else /* HImode or SImode */
5519 static char buf[] = "sbrc %A1,0";
5520 int bit_nr = exact_log2 (INTVAL (operands[2])
5521 & GET_MODE_MASK (GET_MODE (operands[1])));
5523 buf[3] = (comp == EQ) ? 's' : 'c';
5524 buf[6] = 'A' + (bit_nr >> 3);
5525 buf[9] = '0' + (bit_nr & 7);
5526 output_asm_insn (buf, operands);
5531 return (AS1 (rjmp,_PC_+4) CR_TAB
5534 return AS1 (rjmp,%3);