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));
69 static unsigned int avr_section_type_flags PARAMS ((tree, const char *, int));
71 static void avr_asm_out_ctor PARAMS ((rtx, int));
72 static void avr_asm_out_dtor PARAMS ((rtx, int));
74 /* Allocate registers from r25 to r8 for parameters for function calls */
75 #define FIRST_CUM_REG 26
77 /* Temporary register RTX (gen_rtx (REG,QImode,TMP_REGNO)) */
80 /* Zeroed register RTX (gen_rtx (REG,QImode,ZERO_REGNO)) */
83 /* RTX for register which will be used for loading immediate values to
87 /* AVR register names {"r0", "r1", ..., "r31"} */
88 static const char *const avr_regnames[] = REGISTER_NAMES;
90 /* This holds the last insn address. */
91 static int last_insn_address = 0;
93 /* Commands count in the compiled file */
94 static int commands_in_file;
96 /* Commands in the functions prologues in the compiled file */
97 static int commands_in_prologues;
99 /* Commands in the functions epilogues in the compiled file */
100 static int commands_in_epilogues;
102 /* Prologue/Epilogue size in words */
103 static int prologue_size;
104 static int epilogue_size;
106 /* Size of all jump tables in the current function, in words. */
107 static int jump_tables_size;
109 /* Initial stack value specified by the `-minit-stack=' option */
110 const char *avr_init_stack = "__stack";
112 /* Default MCU name */
113 const char *avr_mcu_name = "avr2";
115 /* Preprocessor macros to define depending on MCU type. */
116 const char *avr_base_arch_macro;
117 const char *avr_extra_arch_macro;
119 /* More than 8K of program memory: use "call" and "jmp". */
122 /* Enhanced core: use "movw", "mul", ... */
123 int avr_enhanced_p = 0;
125 /* Assembler only. */
126 int avr_asm_only_p = 0;
132 const char *const macro;
135 static const struct base_arch_s avr_arch_types[] = {
136 { 1, 0, 0, NULL }, /* unknown device specified */
137 { 1, 0, 0, "__AVR_ARCH__=1" },
138 { 0, 0, 0, "__AVR_ARCH__=2" },
139 { 0, 0, 1, "__AVR_ARCH__=3" },
140 { 0, 1, 0, "__AVR_ARCH__=4" },
141 { 0, 1, 1, "__AVR_ARCH__=5" }
145 const char *const name;
146 int arch; /* index in avr_arch_types[] */
147 /* Must lie outside user's namespace. NULL == no macro. */
148 const char *const macro;
151 /* List of all known AVR MCU types - if updated, it has to be kept
152 in sync in several places (FIXME: is there a better way?):
154 - avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
155 - t-avr (MULTILIB_MATCHES)
156 - gas/config/tc-avr.c
159 static const struct mcu_type_s avr_mcu_types[] = {
160 /* Classic, <= 8K. */
162 { "at90s2313", 2, "__AVR_AT90S2313__" },
163 { "at90s2323", 2, "__AVR_AT90S2323__" },
164 { "at90s2333", 2, "__AVR_AT90S2333__" },
165 { "at90s2343", 2, "__AVR_AT90S2343__" },
166 { "attiny22", 2, "__AVR_ATtiny22__" },
167 { "attiny26", 2, "__AVR_ATtiny26__" },
168 { "at90s4414", 2, "__AVR_AT90S4414__" },
169 { "at90s4433", 2, "__AVR_AT90S4433__" },
170 { "at90s4434", 2, "__AVR_AT90S4434__" },
171 { "at90s8515", 2, "__AVR_AT90S8515__" },
172 { "at90c8534", 2, "__AVR_AT90C8534__" },
173 { "at90s8535", 2, "__AVR_AT90S8535__" },
174 { "at86rf401", 2, "__AVR_AT86RF401__" },
177 { "atmega103", 3, "__AVR_ATmega103__" },
178 { "atmega603", 3, "__AVR_ATmega603__" },
179 { "at43usb320", 3, "__AVR_AT43USB320__" },
180 { "at43usb355", 3, "__AVR_AT43USB355__" },
181 { "at76c711", 3, "__AVR_AT76C711__" },
182 /* Enhanced, <= 8K. */
184 { "atmega8", 4, "__AVR_ATmega8__" },
185 { "atmega8515", 4, "__AVR_ATmega8515__" },
186 { "atmega8535", 4, "__AVR_ATmega8535__" },
187 /* Enhanced, > 8K. */
189 { "atmega16", 5, "__AVR_ATmega16__" },
190 { "atmega161", 5, "__AVR_ATmega161__" },
191 { "atmega162", 5, "__AVR_ATmega162__" },
192 { "atmega163", 5, "__AVR_ATmega163__" },
193 { "atmega169", 5, "__AVR_ATmega169__" },
194 { "atmega32", 5, "__AVR_ATmega32__" },
195 { "atmega323", 5, "__AVR_ATmega323__" },
196 { "atmega64", 5, "__AVR_ATmega64__" },
197 { "atmega128", 5, "__AVR_ATmega128__" },
198 { "at94k", 5, "__AVR_AT94K__" },
199 /* Assembler only. */
201 { "at90s1200", 1, "__AVR_AT90S1200__" },
202 { "attiny11", 1, "__AVR_ATtiny11__" },
203 { "attiny12", 1, "__AVR_ATtiny12__" },
204 { "attiny15", 1, "__AVR_ATtiny15__" },
205 { "attiny28", 1, "__AVR_ATtiny28__" },
209 int avr_case_values_threshold = 30000;
211 /* Initialize the GCC target structure. */
212 #undef TARGET_ASM_ALIGNED_HI_OP
213 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
214 #undef TARGET_ASM_INTEGER
215 #define TARGET_ASM_INTEGER avr_assemble_integer
217 #undef TARGET_ASM_FUNCTION_PROLOGUE
218 #define TARGET_ASM_FUNCTION_PROLOGUE avr_output_function_prologue
219 #undef TARGET_ASM_FUNCTION_EPILOGUE
220 #define TARGET_ASM_FUNCTION_EPILOGUE avr_output_function_epilogue
221 #undef TARGET_ATTRIBUTE_TABLE
222 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
223 #undef TARGET_ASM_UNIQUE_SECTION
224 #define TARGET_ASM_UNIQUE_SECTION avr_unique_section
225 #undef TARGET_ENCODE_SECTION_INFO
226 #define TARGET_ENCODE_SECTION_INFO avr_encode_section_info
227 #undef TARGET_SECTION_TYPE_FLAGS
228 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
230 struct gcc_target targetm = TARGET_INITIALIZER;
233 avr_override_options ()
235 const struct mcu_type_s *t;
236 const struct base_arch_s *base;
238 for (t = avr_mcu_types; t->name; t++)
239 if (strcmp (t->name, avr_mcu_name) == 0)
244 fprintf (stderr, "unknown MCU `%s' specified\nKnown MCU names:\n",
246 for (t = avr_mcu_types; t->name; t++)
247 fprintf (stderr," %s\n", t->name);
250 base = &avr_arch_types[t->arch];
251 avr_asm_only_p = base->asm_only;
252 avr_enhanced_p = base->enhanced;
253 avr_mega_p = base->mega;
254 avr_base_arch_macro = base->macro;
255 avr_extra_arch_macro = t->macro;
257 if (optimize && !TARGET_NO_TABLEJUMP)
258 avr_case_values_threshold = (!AVR_MEGA || TARGET_CALL_PROLOGUES) ? 8 : 17;
262 /* Initialize TMP_REG_RTX and ZERO_REG_RTX */
266 tmp_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
267 memset (tmp_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
268 PUT_CODE (tmp_reg_rtx, REG);
269 PUT_MODE (tmp_reg_rtx, QImode);
270 XINT (tmp_reg_rtx, 0) = TMP_REGNO;
272 zero_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
273 memset (zero_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
274 PUT_CODE (zero_reg_rtx, REG);
275 PUT_MODE (zero_reg_rtx, QImode);
276 XINT (zero_reg_rtx, 0) = ZERO_REGNO;
278 ldi_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
279 memset (ldi_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
280 PUT_CODE (ldi_reg_rtx, REG);
281 PUT_MODE (ldi_reg_rtx, QImode);
282 XINT (ldi_reg_rtx, 0) = LDI_REG_REGNO;
285 /* return register class from register number */
287 static const int reg_class_tab[]={
288 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
289 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
290 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
291 GENERAL_REGS, /* r0 - r15 */
292 LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
293 LD_REGS, /* r16 - 23 */
294 ADDW_REGS,ADDW_REGS, /* r24,r25 */
295 POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
296 POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
297 POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
298 STACK_REG,STACK_REG /* SPL,SPH */
301 /* Return register class for register R */
304 avr_regno_reg_class (r)
308 return reg_class_tab[r];
313 /* A C expression which defines the machine-dependent operand
314 constraint letters for register classes. If C is such a
315 letter, the value should be the register class corresponding to
316 it. Otherwise, the value should be `NO_REGS'. The register
317 letter `r', corresponding to class `GENERAL_REGS', will not be
318 passed to this macro; you do not need to handle it. */
321 avr_reg_class_from_letter (c)
326 case 't' : return R0_REG;
327 case 'b' : return BASE_POINTER_REGS;
328 case 'e' : return POINTER_REGS;
329 case 'w' : return ADDW_REGS;
330 case 'd' : return LD_REGS;
331 case 'l' : return NO_LD_REGS;
332 case 'a' : return SIMPLE_LD_REGS;
333 case 'x' : return POINTER_X_REGS;
334 case 'y' : return POINTER_Y_REGS;
335 case 'z' : return POINTER_Z_REGS;
336 case 'q' : return STACK_REG;
342 /* Return non-zero if FUNC is a naked function. */
345 avr_naked_function_p (func)
350 if (TREE_CODE (func) != FUNCTION_DECL)
353 a = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
354 return a != NULL_TREE;
357 /* Return nonzero if FUNC is an interrupt function as specified
358 by the "interrupt" attribute. */
361 interrupt_function_p (func)
366 if (TREE_CODE (func) != FUNCTION_DECL)
369 a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
370 return a != NULL_TREE;
373 /* Return nonzero if FUNC is a signal function as specified
374 by the "signal" attribute. */
377 signal_function_p (func)
382 if (TREE_CODE (func) != FUNCTION_DECL)
385 a = lookup_attribute ("signal", DECL_ATTRIBUTES (func));
386 return a != NULL_TREE;
389 /* Return the number of hard registers to push/pop in the prologue/epilogue
390 of the current function, and optionally store these registers in SET. */
393 avr_regs_to_save (set)
397 int int_or_sig_p = (interrupt_function_p (current_function_decl)
398 || signal_function_p (current_function_decl));
399 int leaf_func_p = leaf_function_p ();
402 CLEAR_HARD_REG_SET (*set);
405 /* No need to save any registers if the function never returns. */
406 if (TREE_THIS_VOLATILE (current_function_decl))
409 for (reg = 0; reg < 32; reg++)
411 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
412 any global register variables. */
416 if ((int_or_sig_p && !leaf_func_p && call_used_regs[reg])
417 || (regs_ever_live[reg]
418 && (int_or_sig_p || !call_used_regs[reg])
419 && !(frame_pointer_needed
420 && (reg == REG_Y || reg == (REG_Y+1)))))
423 SET_HARD_REG_BIT (*set, reg);
430 /* Compute offset between arg_pointer and frame_pointer */
433 initial_elimination_offset (from, to)
437 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
441 int offset = frame_pointer_needed ? 2 : 0;
443 offset += avr_regs_to_save (NULL);
444 return get_frame_size () + 2 + 1 + offset;
448 /* This function checks sequence of live registers */
457 for (reg = 0; reg < 18; ++reg)
459 if (!call_used_regs[reg])
461 if (regs_ever_live[reg])
471 if (!frame_pointer_needed)
473 if (regs_ever_live[REG_Y])
481 if (regs_ever_live[REG_Y+1])
494 return (cur_seq == live_seq) ? live_seq : 0;
498 /* Output to FILE the asm instructions to adjust the frame pointer by
499 ADJ (r29:r28 -= ADJ;) which can be positive (prologue) or negative
500 (epilogue). Returns the number of instructions generated. */
503 out_adj_frame_ptr (file, adj)
511 if (TARGET_TINY_STACK)
513 if (adj < -63 || adj > 63)
514 warning ("large frame pointer change (%d) with -mtiny-stack", adj);
516 /* The high byte (r29) doesn't change - prefer "subi" (1 cycle)
517 over "sbiw" (2 cycles, same size). */
519 fprintf (file, (AS2 (subi, r28, %d) CR_TAB), adj);
522 else if (adj < -63 || adj > 63)
524 fprintf (file, (AS2 (subi, r28, lo8(%d)) CR_TAB
525 AS2 (sbci, r29, hi8(%d)) CR_TAB),
531 fprintf (file, (AS2 (adiw, r28, %d) CR_TAB), -adj);
536 fprintf (file, (AS2 (sbiw, r28, %d) CR_TAB), adj);
544 /* Output to FILE the asm instructions to copy r29:r28 to SPH:SPL,
545 handling various cases of interrupt enable flag state BEFORE and AFTER
546 (0=disabled, 1=enabled, -1=unknown/unchanged) and target_flags.
547 Returns the number of instructions generated. */
550 out_set_stack_ptr (file, before, after)
555 int do_sph, do_cli, do_save, do_sei, lock_sph, size;
557 /* The logic here is so that -mno-interrupts actually means
558 "it is safe to write SPH in one instruction, then SPL in the
559 next instruction, without disabling interrupts first".
560 The after != -1 case (interrupt/signal) is not affected. */
562 do_sph = !TARGET_TINY_STACK;
563 lock_sph = do_sph && !TARGET_NO_INTERRUPTS;
564 do_cli = (before != 0 && (after == 0 || lock_sph));
565 do_save = (do_cli && before == -1 && after == -1);
566 do_sei = ((do_cli || before != 1) && after == 1);
571 fprintf (file, AS2 (in, __tmp_reg__, __SREG__) CR_TAB);
577 fprintf (file, "cli" CR_TAB);
581 /* Do SPH first - maybe this will disable interrupts for one instruction
582 someday (a suggestion has been sent to avr@atmel.com for consideration
583 in future devices - that would make -mno-interrupts always safe). */
586 fprintf (file, AS2 (out, __SP_H__, r29) CR_TAB);
590 /* Set/restore the I flag now - interrupts will be really enabled only
591 after the next instruction. This is not clearly documented, but
592 believed to be true for all AVR devices. */
595 fprintf (file, AS2 (out, __SREG__, __tmp_reg__) CR_TAB);
600 fprintf (file, "sei" CR_TAB);
604 fprintf (file, AS2 (out, __SP_L__, r28) "\n");
610 /* Output function prologue */
613 avr_output_function_prologue (file, size)
618 int interrupt_func_p;
624 last_insn_address = 0;
625 jump_tables_size = 0;
627 fprintf (file, "/* prologue: frame size=%d */\n", size);
629 if (avr_naked_function_p (current_function_decl))
631 fputs ("/* prologue: naked */\n", file);
635 interrupt_func_p = interrupt_function_p (current_function_decl);
636 signal_func_p = signal_function_p (current_function_decl);
637 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
638 live_seq = sequent_regs_live ();
639 minimize = (TARGET_CALL_PROLOGUES
640 && !interrupt_func_p && !signal_func_p && live_seq);
642 if (interrupt_func_p)
644 fprintf (file,"\tsei\n");
647 if (interrupt_func_p || signal_func_p)
650 AS1 (push,__zero_reg__) CR_TAB
651 AS1 (push,__tmp_reg__) CR_TAB
652 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
653 AS1 (push,__tmp_reg__) CR_TAB
654 AS1 (clr,__zero_reg__) "\n");
660 AS2 (ldi,r28,lo8(%s - %d)) CR_TAB
661 AS2 (ldi,r29,hi8(%s - %d)) CR_TAB
662 AS2 (out,__SP_H__,r29) CR_TAB
663 AS2 (out,__SP_L__,r28) "\n"),
664 avr_init_stack, size, avr_init_stack, size);
668 else if (minimize && (frame_pointer_needed || live_seq > 6))
671 AS2 (ldi, r26, lo8(%d)) CR_TAB
672 AS2 (ldi, r27, hi8(%d)) CR_TAB), size, size);
674 fprintf (file, (AS2 (ldi, r30, pm_lo8(.L_%s_body)) CR_TAB
675 AS2 (ldi, r31, pm_hi8(.L_%s_body)) CR_TAB)
676 ,current_function_name, current_function_name);
682 fprintf (file, AS1 (jmp,__prologue_saves__+%d) "\n",
683 (18 - live_seq) * 2);
688 fprintf (file, AS1 (rjmp,__prologue_saves__+%d) "\n",
689 (18 - live_seq) * 2);
692 fprintf (file, ".L_%s_body:\n", current_function_name);
698 prologue_size += avr_regs_to_save (&set);
699 for (reg = 0; reg < 32; ++reg)
701 if (TEST_HARD_REG_BIT (set, reg))
703 fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
706 if (frame_pointer_needed)
710 AS1 (push,r28) CR_TAB
711 AS1 (push,r29) CR_TAB
712 AS2 (in,r28,__SP_L__) CR_TAB
713 AS2 (in,r29,__SP_H__) "\n");
718 prologue_size += out_adj_frame_ptr (file, size);
720 if (interrupt_func_p)
722 prologue_size += out_set_stack_ptr (file, 1, 1);
724 else if (signal_func_p)
726 prologue_size += out_set_stack_ptr (file, 0, 0);
730 prologue_size += out_set_stack_ptr (file, -1, -1);
738 fprintf (file, "/* prologue end (size=%d) */\n", prologue_size);
741 /* Output function epilogue */
744 avr_output_function_epilogue (file, size)
749 int interrupt_func_p;
755 rtx last = get_last_nonnote_insn ();
757 function_size = jump_tables_size;
760 rtx first = get_first_nonnote_insn ();
761 function_size += (INSN_ADDRESSES (INSN_UID (last)) -
762 INSN_ADDRESSES (INSN_UID (first)));
763 function_size += get_attr_length (last);
766 fprintf (file, "/* epilogue: frame size=%d */\n", size);
769 if (avr_naked_function_p (current_function_decl))
771 fputs ("/* epilogue: naked */\n", file);
775 if (last && GET_CODE (last) == BARRIER)
777 fputs ("/* epilogue: noreturn */\n", file);
781 interrupt_func_p = interrupt_function_p (current_function_decl);
782 signal_func_p = signal_function_p (current_function_decl);
783 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
784 live_seq = sequent_regs_live ();
785 minimize = (TARGET_CALL_PROLOGUES
786 && !interrupt_func_p && !signal_func_p && live_seq);
790 /* Return value from main() is already in the correct registers
791 (r25:r24) as the exit() argument. */
794 fputs ("\t" AS1 (jmp,exit) "\n", file);
799 fputs ("\t" AS1 (rjmp,exit) "\n", file);
803 else if (minimize && (frame_pointer_needed || live_seq > 4))
805 fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
807 if (frame_pointer_needed)
809 epilogue_size += out_adj_frame_ptr (file, -size);
813 fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
814 AS2 (in , r29, __SP_H__) CR_TAB));
820 fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
821 (18 - live_seq) * 2);
826 fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
827 (18 - live_seq) * 2);
835 if (frame_pointer_needed)
840 epilogue_size += out_adj_frame_ptr (file, -size);
842 if (interrupt_func_p || signal_func_p)
844 epilogue_size += out_set_stack_ptr (file, -1, 0);
848 epilogue_size += out_set_stack_ptr (file, -1, -1);
857 epilogue_size += avr_regs_to_save (&set);
858 for (reg = 31; reg >= 0; --reg)
860 if (TEST_HARD_REG_BIT (set, reg))
862 fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
866 if (interrupt_func_p || signal_func_p)
869 AS1 (pop,__tmp_reg__) CR_TAB
870 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
871 AS1 (pop,__tmp_reg__) CR_TAB
872 AS1 (pop,__zero_reg__) "\n");
874 fprintf (file, "\treti\n");
877 fprintf (file, "\tret\n");
882 fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
883 fprintf (file, "/* function %s size %d (%d) */\n", current_function_name,
884 prologue_size + function_size + epilogue_size, function_size);
885 commands_in_file += prologue_size + function_size + epilogue_size;
886 commands_in_prologues += prologue_size;
887 commands_in_epilogues += epilogue_size;
891 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
892 machine for a memory operand of mode MODE. */
895 legitimate_address_p (mode, x, strict)
896 enum machine_mode mode;
900 enum reg_class r = NO_REGS;
902 if (TARGET_ALL_DEBUG)
904 fprintf (stderr, "mode: (%s) %s %s %s %s:",
906 strict ? "(strict)": "",
907 reload_completed ? "(reload_completed)": "",
908 reload_in_progress ? "(reload_in_progress)": "",
909 reg_renumber ? "(reg_renumber)" : "");
910 if (GET_CODE (x) == PLUS
911 && REG_P (XEXP (x, 0))
912 && GET_CODE (XEXP (x, 1)) == CONST_INT
913 && INTVAL (XEXP (x, 1)) >= 0
914 && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
917 fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
918 true_regnum (XEXP (x, 0)));
921 if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
922 : REG_OK_FOR_BASE_NOSTRICT_P (x)))
924 else if (CONSTANT_ADDRESS_P (x))
926 else if (GET_CODE (x) == PLUS
927 && REG_P (XEXP (x, 0))
928 && GET_CODE (XEXP (x, 1)) == CONST_INT
929 && INTVAL (XEXP (x, 1)) >= 0)
931 int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
935 || REGNO (XEXP (x,0)) == REG_Y
936 || REGNO (XEXP (x,0)) == REG_Z)
937 r = BASE_POINTER_REGS;
938 if (XEXP (x,0) == frame_pointer_rtx
939 || XEXP (x,0) == arg_pointer_rtx)
940 r = BASE_POINTER_REGS;
942 else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
945 else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
946 && REG_P (XEXP (x, 0))
947 && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
948 : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
952 if (TARGET_ALL_DEBUG)
954 fprintf (stderr, " ret = %c\n", r);
956 return r == NO_REGS ? 0 : (int)r;
959 /* Attempts to replace X with a valid
960 memory address for an operand of mode MODE */
963 legitimize_address (x, oldx, mode)
966 enum machine_mode mode;
969 if (TARGET_ALL_DEBUG)
971 fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
975 if (GET_CODE (oldx) == PLUS
976 && REG_P (XEXP (oldx,0)))
978 if (REG_P (XEXP (oldx,1)))
979 x = force_reg (GET_MODE (oldx), oldx);
980 else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
982 int offs = INTVAL (XEXP (oldx,1));
983 if (frame_pointer_rtx != XEXP (oldx,0))
984 if (offs > MAX_LD_OFFSET (mode))
986 if (TARGET_ALL_DEBUG)
987 fprintf (stderr, "force_reg (big offset)\n");
988 x = force_reg (GET_MODE (oldx), oldx);
996 /* Return a pointer register name as a string */
999 ptrreg_to_str (regno)
1004 case REG_X: return "X";
1005 case REG_Y: return "Y";
1006 case REG_Z: return "Z";
1013 /* Return the condition name as a string.
1014 Used in conditional jump constructing */
1027 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1032 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1045 /* Output ADDR to FILE as address */
1048 print_operand_address (file, addr)
1052 switch (GET_CODE (addr))
1055 fprintf (file, ptrreg_to_str (REGNO (addr)));
1059 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1063 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1067 if (CONSTANT_ADDRESS_P (addr)
1068 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
1069 || GET_CODE (addr) == LABEL_REF))
1071 fprintf (file, "pm(");
1072 output_addr_const (file,addr);
1073 fprintf (file ,")");
1076 output_addr_const (file, addr);
1081 /* Output X as assembler operand to file FILE */
1084 print_operand (file, x, code)
1091 if (code >= 'A' && code <= 'D')
1101 if (x == zero_reg_rtx)
1102 fprintf (file, "__zero_reg__");
1104 fprintf (file, reg_names[true_regnum (x) + abcd]);
1106 else if (GET_CODE (x) == CONST_INT)
1107 fprintf (file, "%d", INTVAL (x) + abcd);
1108 else if (GET_CODE (x) == MEM)
1110 rtx addr = XEXP (x,0);
1112 if (CONSTANT_P (addr) && abcd)
1115 output_address (addr);
1116 fprintf (file, ")+%d", abcd);
1118 else if (code == 'o')
1120 if (GET_CODE (addr) != PLUS)
1121 fatal_insn ("bad address, not (reg+disp):", addr);
1123 print_operand (file, XEXP (addr, 1), 0);
1125 else if (GET_CODE (addr) == PLUS)
1127 print_operand_address (file, XEXP (addr,0));
1128 if (REGNO (XEXP (addr, 0)) == REG_X)
1129 fatal_insn ("internal compiler error. Bad address:"
1132 print_operand (file, XEXP (addr,1), code);
1135 print_operand_address (file, addr);
1137 else if (GET_CODE (x) == CONST_DOUBLE)
1141 if (GET_MODE (x) != SFmode)
1142 fatal_insn ("internal compiler error. Unknown mode:", x);
1143 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1144 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1145 asm_fprintf (file, "0x%lx", val);
1147 else if (code == 'j')
1148 asm_fprintf (file, cond_string (GET_CODE (x)));
1149 else if (code == 'k')
1150 asm_fprintf (file, cond_string (reverse_condition (GET_CODE (x))));
1152 print_operand_address (file, x);
1155 /* Recognize operand OP of mode MODE used in call instructions */
1158 call_insn_operand (op, mode)
1160 enum machine_mode mode ATTRIBUTE_UNUSED;
1162 if (GET_CODE (op) == MEM)
1164 rtx inside = XEXP (op, 0);
1165 if (register_operand (inside, Pmode))
1167 if (CONSTANT_ADDRESS_P (inside))
1173 /* Update the condition code in the INSN. */
1176 notice_update_cc (body, insn)
1177 rtx body ATTRIBUTE_UNUSED;
1182 switch (get_attr_cc (insn))
1185 /* Insn does not affect CC at all. */
1193 set = single_set (insn);
1197 cc_status.flags |= CC_NO_OVERFLOW;
1198 cc_status.value1 = SET_DEST (set);
1203 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1204 The V flag may or may not be known but that's ok because
1205 alter_cond will change tests to use EQ/NE. */
1206 set = single_set (insn);
1210 cc_status.value1 = SET_DEST (set);
1211 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1216 set = single_set (insn);
1219 cc_status.value1 = SET_SRC (set);
1223 /* Insn doesn't leave CC in a usable state. */
1226 /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1227 set = single_set (insn);
1230 rtx src = SET_SRC (set);
1232 if (GET_CODE (src) == ASHIFTRT
1233 && GET_MODE (src) == QImode)
1235 rtx x = XEXP (src, 1);
1237 if (GET_CODE (x) == CONST_INT
1240 cc_status.value1 = SET_DEST (set);
1241 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1249 /* Return maximum number of consecutive registers of
1250 class CLASS needed to hold a value of mode MODE. */
1253 class_max_nregs (class, mode)
1254 enum reg_class class ATTRIBUTE_UNUSED;
1255 enum machine_mode mode;
1257 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1260 /* Choose mode for jump insn:
1261 1 - relative jump in range -63 <= x <= 62 ;
1262 2 - relative jump in range -2046 <= x <= 2045 ;
1263 3 - absolute jump (only for ATmega[16]03). */
1266 avr_jump_mode (x, insn)
1267 rtx x; /* jump operand */
1268 rtx insn; /* jump insn */
1270 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1271 ? XEXP (x, 0) : x));
1272 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1273 int jump_distance = cur_addr - dest_addr;
1275 if (-63 <= jump_distance && jump_distance <= 62)
1277 else if (-2046 <= jump_distance && jump_distance <= 2045)
1285 /* return an AVR condition jump commands.
1286 X is a comparison RTX.
1287 LEN is a number returned by avr_jump_mode function.
1288 if REVERSE nonzero then condition code in X must be reversed. */
1291 ret_cond_branch (x, len, reverse)
1296 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1301 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1302 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1304 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1305 AS1 (brmi,_PC_+2) CR_TAB
1307 (AS1 (breq,_PC_+6) CR_TAB
1308 AS1 (brmi,_PC_+4) CR_TAB
1312 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1314 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1315 AS1 (brlt,_PC_+2) CR_TAB
1317 (AS1 (breq,_PC_+6) CR_TAB
1318 AS1 (brlt,_PC_+4) CR_TAB
1321 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1323 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1324 AS1 (brlo,_PC_+2) CR_TAB
1326 (AS1 (breq,_PC_+6) CR_TAB
1327 AS1 (brlo,_PC_+4) CR_TAB
1330 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1331 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1333 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1334 AS1 (brpl,_PC_+2) CR_TAB
1336 (AS1 (breq,_PC_+2) CR_TAB
1337 AS1 (brpl,_PC_+4) CR_TAB
1340 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1342 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1343 AS1 (brge,_PC_+2) CR_TAB
1345 (AS1 (breq,_PC_+2) CR_TAB
1346 AS1 (brge,_PC_+4) CR_TAB
1349 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1351 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1352 AS1 (brsh,_PC_+2) CR_TAB
1354 (AS1 (breq,_PC_+2) CR_TAB
1355 AS1 (brsh,_PC_+4) CR_TAB
1363 return AS1 (br%k1,%0);
1365 return (AS1 (br%j1,_PC_+2) CR_TAB
1368 return (AS1 (br%j1,_PC_+4) CR_TAB
1377 return AS1 (br%j1,%0);
1379 return (AS1 (br%k1,_PC_+2) CR_TAB
1382 return (AS1 (br%k1,_PC_+4) CR_TAB
1390 /* Predicate function for immediate operand which fits to byte (8bit) */
1393 byte_immediate_operand (op, mode)
1395 enum machine_mode mode ATTRIBUTE_UNUSED;
1397 return (GET_CODE (op) == CONST_INT
1398 && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1401 /* Output all insn addresses and their sizes into the assembly language
1402 output file. This is helpful for debugging whether the length attributes
1403 in the md file are correct.
1404 Output insn cost for next insn. */
1407 final_prescan_insn (insn, operand, num_operands)
1408 rtx insn, *operand ATTRIBUTE_UNUSED;
1409 int num_operands ATTRIBUTE_UNUSED;
1411 int uid = INSN_UID (insn);
1413 if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1415 fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1416 INSN_ADDRESSES (uid),
1417 INSN_ADDRESSES (uid) - last_insn_address,
1418 rtx_cost (PATTERN (insn), INSN));
1420 last_insn_address = INSN_ADDRESSES (uid);
1422 if (TARGET_RTL_DUMP)
1424 fprintf (asm_out_file, "/*****************\n");
1425 print_rtl_single (asm_out_file, insn);
1426 fprintf (asm_out_file, "*****************/\n");
1430 /* Return 0 if undefined, 1 if always true or always false. */
1433 avr_simplify_comparision_p (mode, operator, x)
1434 enum machine_mode mode;
1438 unsigned int max = (mode == QImode ? 0xff :
1439 mode == HImode ? 0xffff :
1440 mode == SImode ? 0xffffffff : 0);
1441 if (max && operator && GET_CODE (x) == CONST_INT)
1443 if (unsigned_condition (operator) != operator)
1446 if (max != (INTVAL (x) & max)
1447 && INTVAL (x) != 0xff)
1454 /* Returns nonzero if REGNO is the number of a hard
1455 register in which function arguments are sometimes passed. */
1458 function_arg_regno_p(r)
1461 return (r >= 8 && r <= 25);
1464 /* Initializing the variable cum for the state at the beginning
1465 of the argument list. */
1468 init_cumulative_args (cum, fntype, libname, indirect)
1469 CUMULATIVE_ARGS *cum;
1472 int indirect ATTRIBUTE_UNUSED;
1475 cum->regno = FIRST_CUM_REG;
1478 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1479 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1480 != void_type_node));
1486 /* Returns the number of registers to allocate for a function argument. */
1489 avr_num_arg_regs (mode, type)
1490 enum machine_mode mode;
1495 if (mode == BLKmode)
1496 size = int_size_in_bytes (type);
1498 size = GET_MODE_SIZE (mode);
1500 /* Align all function arguments to start in even-numbered registers.
1501 Odd-sized arguments leave holes above them. */
1503 return (size + 1) & ~1;
1506 /* Controls whether a function argument is passed
1507 in a register, and which register. */
1510 function_arg (cum, mode, type, named)
1511 CUMULATIVE_ARGS *cum;
1512 enum machine_mode mode;
1514 int named ATTRIBUTE_UNUSED;
1516 int bytes = avr_num_arg_regs (mode, type);
1518 if (cum->nregs && bytes <= cum->nregs)
1519 return gen_rtx (REG, mode, cum->regno - bytes);
1524 /* Update the summarizer variable CUM to advance past an argument
1525 in the argument list. */
1528 function_arg_advance (cum, mode, type, named)
1529 CUMULATIVE_ARGS *cum; /* current arg information */
1530 enum machine_mode mode; /* current arg mode */
1531 tree type; /* type of the argument or 0 if lib support */
1532 int named ATTRIBUTE_UNUSED; /* whether or not the argument was named */
1534 int bytes = avr_num_arg_regs (mode, type);
1536 cum->nregs -= bytes;
1537 cum->regno -= bytes;
1539 if (cum->nregs <= 0)
1542 cum->regno = FIRST_CUM_REG;
1546 /***********************************************************************
1547 Functions for outputting various mov's for a various modes
1548 ************************************************************************/
1550 output_movqi (insn, operands, l)
1556 rtx dest = operands[0];
1557 rtx src = operands[1];
1565 if (register_operand (dest, QImode))
1567 if (register_operand (src, QImode)) /* mov r,r */
1569 if (test_hard_reg_class (STACK_REG, dest))
1570 return AS2 (out,%0,%1);
1571 else if (test_hard_reg_class (STACK_REG, src))
1572 return AS2 (in,%0,%1);
1574 return AS2 (mov,%0,%1);
1576 else if (CONSTANT_P (src))
1578 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1579 return AS2 (ldi,%0,lo8(%1));
1581 if (GET_CODE (src) == CONST_INT)
1583 if (src == const0_rtx) /* mov r,L */
1584 return AS1 (clr,%0);
1585 else if (src == const1_rtx)
1587 if (reg_was_0 (insn, dest))
1588 return AS1 (inc,%0 ; reg_was_0);
1591 return (AS1 (clr,%0) CR_TAB
1594 else if (src == constm1_rtx)
1596 /* Immediate constants -1 to any register */
1597 if (reg_was_0 (insn, dest))
1598 return AS1 (dec,%0 ; reg_was_0);
1601 return (AS1 (clr,%0) CR_TAB
1606 int bit_nr = exact_log2 (INTVAL (src));
1610 if (reg_was_0 (insn, dest))
1614 output_asm_insn ("set ; reg_was_0", operands);
1620 output_asm_insn ((AS1 (clr,%0) CR_TAB
1624 avr_output_bld (operands, bit_nr);
1631 /* Last resort, larger than loading from memory. */
1633 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1634 AS2 (ldi,r31,lo8(%1)) CR_TAB
1635 AS2 (mov,%0,r31) CR_TAB
1636 AS2 (mov,r31,__tmp_reg__));
1638 else if (GET_CODE (src) == MEM)
1639 return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1641 else if (GET_CODE (dest) == MEM)
1643 const char *template;
1645 if (src == const0_rtx)
1646 operands[1] = zero_reg_rtx;
1648 template = out_movqi_mr_r (insn, operands, real_l);
1651 output_asm_insn (template, operands);
1660 output_movhi (insn, operands, l)
1666 rtx dest = operands[0];
1667 rtx src = operands[1];
1673 if (register_operand (dest, HImode))
1675 if (register_operand (src, HImode)) /* mov r,r */
1677 if (test_hard_reg_class (STACK_REG, dest))
1679 if (TARGET_TINY_STACK)
1682 return AS2 (out,__SP_L__,%A1);
1684 else if (TARGET_NO_INTERRUPTS)
1687 return (AS2 (out,__SP_H__,%B1) CR_TAB
1688 AS2 (out,__SP_L__,%A1));
1692 return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB
1694 AS2 (out,__SP_H__,%B1) CR_TAB
1695 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1696 AS2 (out,__SP_L__,%A1));
1698 else if (test_hard_reg_class (STACK_REG, src))
1701 return (AS2 (in,%A0,__SP_L__) CR_TAB
1702 AS2 (in,%B0,__SP_H__));
1708 return (AS2 (movw,%0,%1));
1711 if (true_regnum (dest) > true_regnum (src))
1714 return (AS2 (mov,%B0,%B1) CR_TAB
1720 return (AS2 (mov,%A0,%A1) CR_TAB
1724 else if (CONSTANT_P (src))
1726 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1728 if (byte_immediate_operand (src, HImode)
1729 && reg_was_0 (insn, dest))
1732 return (AS2 (ldi,%A0,lo8(%1) ; reg_was_0));
1736 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1737 AS2 (ldi,%B0,hi8(%1)));
1740 if (GET_CODE (src) == CONST_INT)
1742 if (src == const0_rtx) /* mov r,L */
1745 return (AS1 (clr,%A0) CR_TAB
1748 else if (src == const1_rtx)
1750 if (reg_was_0 (insn, dest))
1753 return AS1 (inc,%0 ; reg_was_0);
1757 return (AS1 (clr,%A0) CR_TAB
1758 AS1 (clr,%B0) CR_TAB
1761 else if (src == constm1_rtx)
1763 /* Immediate constants -1 to any register */
1764 if (reg_was_0 (insn, dest))
1767 return (AS1 (dec,%A0 ; reg_was_0) CR_TAB
1772 return (AS1 (clr,%0) CR_TAB
1773 AS1 (dec,%A0) CR_TAB
1778 int bit_nr = exact_log2 (INTVAL (src));
1782 if (reg_was_0 (insn, dest))
1786 output_asm_insn ("set ; reg_was_0", operands);
1792 output_asm_insn ((AS1 (clr,%A0) CR_TAB
1793 AS1 (clr,%B0) CR_TAB
1797 avr_output_bld (operands, bit_nr);
1803 if ((INTVAL (src) & 0xff) == 0)
1806 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1807 AS1 (clr,%A0) CR_TAB
1808 AS2 (ldi,r31,hi8(%1)) CR_TAB
1809 AS2 (mov,%B0,r31) CR_TAB
1810 AS2 (mov,r31,__tmp_reg__));
1812 else if ((INTVAL (src) & 0xff00) == 0)
1815 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1816 AS2 (ldi,r31,lo8(%1)) CR_TAB
1817 AS2 (mov,%A0,r31) CR_TAB
1818 AS1 (clr,%B0) CR_TAB
1819 AS2 (mov,r31,__tmp_reg__));
1823 /* Last resort, equal to loading from memory. */
1825 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1826 AS2 (ldi,r31,lo8(%1)) CR_TAB
1827 AS2 (mov,%A0,r31) CR_TAB
1828 AS2 (ldi,r31,hi8(%1)) CR_TAB
1829 AS2 (mov,%B0,r31) CR_TAB
1830 AS2 (mov,r31,__tmp_reg__));
1832 else if (GET_CODE (src) == MEM)
1833 return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1835 else if (GET_CODE (dest) == MEM)
1837 const char *template;
1839 if (src == const0_rtx)
1840 operands[1] = zero_reg_rtx;
1842 template = out_movhi_mr_r (insn, operands, real_l);
1845 output_asm_insn (template, operands);
1850 fatal_insn ("invalid insn:", insn);
1855 out_movqi_r_mr (insn, op, l)
1858 int *l; /* instruction length */
1862 rtx x = XEXP (src, 0);
1868 if (CONSTANT_ADDRESS_P (x))
1870 if (avr_io_address_p (x, 1))
1873 return AS2 (in,%0,%1-0x20);
1876 return AS2 (lds,%0,%1);
1878 /* memory access by reg+disp */
1879 else if (GET_CODE (x) == PLUS
1880 && REG_P (XEXP (x,0))
1881 && GET_CODE (XEXP (x,1)) == CONST_INT)
1883 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1885 int disp = INTVAL (XEXP (x,1));
1886 if (REGNO (XEXP (x,0)) != REG_Y)
1887 fatal_insn ("incorrect insn:",insn);
1889 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1890 return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
1891 AS2 (ldd,%0,Y+63) CR_TAB
1892 AS2 (sbiw,r28,%o1-63));
1894 return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1895 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1896 AS2 (ld,%0,Y) CR_TAB
1897 AS2 (subi,r28,lo8(%o1)) CR_TAB
1898 AS2 (sbci,r29,hi8(%o1)));
1900 else if (REGNO (XEXP (x,0)) == REG_X)
1902 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1903 it but I have this situation with extremal optimizing options. */
1904 if (reg_overlap_mentioned_p (dest, XEXP (x,0))
1905 || reg_unused_after (insn, XEXP (x,0)))
1906 return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
1909 return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
1910 AS2 (ld,%0,X) CR_TAB
1911 AS2 (sbiw,r26,%o1));
1914 return AS2 (ldd,%0,%1);
1917 return AS2 (ld,%0,%1);
1921 out_movhi_r_mr (insn, op, l)
1924 int *l; /* instruction length */
1928 rtx base = XEXP (src, 0);
1929 int reg_dest = true_regnum (dest);
1930 int reg_base = true_regnum (base);
1938 if (reg_dest == reg_base) /* R = (R) */
1941 return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1942 AS2 (ld,%B0,%1) CR_TAB
1943 AS2 (mov,%A0,__tmp_reg__));
1945 else if (reg_base == REG_X) /* (R26) */
1947 if (reg_unused_after (insn, base))
1950 return (AS2 (ld,%A0,X+) CR_TAB
1954 return (AS2 (ld,%A0,X+) CR_TAB
1955 AS2 (ld,%B0,X) CR_TAB
1961 return (AS2 (ld,%A0,%1) CR_TAB
1962 AS2 (ldd,%B0,%1+1));
1965 else if (GET_CODE (base) == PLUS) /* (R + i) */
1967 int disp = INTVAL (XEXP (base, 1));
1968 int reg_base = true_regnum (XEXP (base, 0));
1970 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
1972 if (REGNO (XEXP (base, 0)) != REG_Y)
1973 fatal_insn ("incorrect insn:",insn);
1975 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1976 return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
1977 AS2 (ldd,%A0,Y+62) CR_TAB
1978 AS2 (ldd,%B0,Y+63) CR_TAB
1979 AS2 (sbiw,r28,%o1-62));
1981 return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1982 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1983 AS2 (ld,%A0,Y) CR_TAB
1984 AS2 (ldd,%B0,Y+1) CR_TAB
1985 AS2 (subi,r28,lo8(%o1)) CR_TAB
1986 AS2 (sbci,r29,hi8(%o1)));
1988 if (reg_base == REG_X)
1990 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1991 it but I have this situation with extremal
1992 optimization options. */
1995 if (reg_base == reg_dest)
1996 return (AS2 (adiw,r26,%o1) CR_TAB
1997 AS2 (ld,__tmp_reg__,X+) CR_TAB
1998 AS2 (ld,%B0,X) CR_TAB
1999 AS2 (mov,%A0,__tmp_reg__));
2001 return (AS2 (adiw,r26,%o1) CR_TAB
2002 AS2 (ld,%A0,X+) CR_TAB
2003 AS2 (ld,%B0,X) CR_TAB
2004 AS2 (sbiw,r26,%o1+1));
2007 if (reg_base == reg_dest)
2010 return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
2011 AS2 (ldd,%B0,%B1) CR_TAB
2012 AS2 (mov,%A0,__tmp_reg__));
2016 return (AS2 (ldd,%A0,%A1) CR_TAB
2019 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2021 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
2022 fatal_insn ("incorrect insn:", insn);
2025 return (AS2 (ld,%B0,%1) CR_TAB
2028 else if (GET_CODE (base) == POST_INC) /* (R++) */
2030 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
2031 fatal_insn ("incorrect insn:", insn);
2034 return (AS2 (ld,%A0,%1) CR_TAB
2037 else if (CONSTANT_ADDRESS_P (base))
2039 if (avr_io_address_p (base, 2))
2042 return (AS2 (in,%A0,%A1-0x20) CR_TAB
2043 AS2 (in,%B0,%B1-0x20));
2046 return (AS2 (lds,%A0,%A1) CR_TAB
2050 fatal_insn ("unknown move insn:",insn);
2055 out_movsi_r_mr (insn, op, l)
2058 int *l; /* instruction length */
2062 rtx base = XEXP (src, 0);
2063 int reg_dest = true_regnum (dest);
2064 int reg_base = true_regnum (base);
2072 if (reg_base == REG_X) /* (R26) */
2074 if (reg_dest == REG_X)
2075 /* "ld r26,-X" is undefined */
2076 return *l=7, (AS2 (adiw,r26,3) CR_TAB
2077 AS2 (ld,r29,X) CR_TAB
2078 AS2 (ld,r28,-X) CR_TAB
2079 AS2 (ld,__tmp_reg__,-X) CR_TAB
2080 AS2 (sbiw,r26,1) CR_TAB
2081 AS2 (ld,r26,X) CR_TAB
2082 AS2 (mov,r27,__tmp_reg__));
2083 else if (reg_dest == REG_X - 2)
2084 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2085 AS2 (ld,%B0,X+) CR_TAB
2086 AS2 (ld,__tmp_reg__,X+) CR_TAB
2087 AS2 (ld,%D0,X) CR_TAB
2088 AS2 (mov,%C0,__tmp_reg__));
2089 else if (reg_unused_after (insn, base))
2090 return *l=4, (AS2 (ld,%A0,X+) CR_TAB
2091 AS2 (ld,%B0,X+) CR_TAB
2092 AS2 (ld,%C0,X+) CR_TAB
2095 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2096 AS2 (ld,%B0,X+) CR_TAB
2097 AS2 (ld,%C0,X+) CR_TAB
2098 AS2 (ld,%D0,X) CR_TAB
2103 if (reg_dest == reg_base)
2104 return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
2105 AS2 (ldd,%C0,%1+2) CR_TAB
2106 AS2 (ldd,__tmp_reg__,%1+1) CR_TAB
2107 AS2 (ld,%A0,%1) CR_TAB
2108 AS2 (mov,%B0,__tmp_reg__));
2109 else if (reg_base == reg_dest + 2)
2110 return *l=5, (AS2 (ld ,%A0,%1) CR_TAB
2111 AS2 (ldd,%B0,%1+1) CR_TAB
2112 AS2 (ldd,__tmp_reg__,%1+2) CR_TAB
2113 AS2 (ldd,%D0,%1+3) CR_TAB
2114 AS2 (mov,%C0,__tmp_reg__));
2116 return *l=4, (AS2 (ld ,%A0,%1) CR_TAB
2117 AS2 (ldd,%B0,%1+1) CR_TAB
2118 AS2 (ldd,%C0,%1+2) CR_TAB
2119 AS2 (ldd,%D0,%1+3));
2122 else if (GET_CODE (base) == PLUS) /* (R + i) */
2124 int disp = INTVAL (XEXP (base, 1));
2126 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2128 if (REGNO (XEXP (base, 0)) != REG_Y)
2129 fatal_insn ("incorrect insn:",insn);
2131 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2132 return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2133 AS2 (ldd,%A0,Y+60) CR_TAB
2134 AS2 (ldd,%B0,Y+61) CR_TAB
2135 AS2 (ldd,%C0,Y+62) CR_TAB
2136 AS2 (ldd,%D0,Y+63) CR_TAB
2137 AS2 (sbiw,r28,%o1-60));
2139 return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2140 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2141 AS2 (ld,%A0,Y) CR_TAB
2142 AS2 (ldd,%B0,Y+1) CR_TAB
2143 AS2 (ldd,%C0,Y+2) CR_TAB
2144 AS2 (ldd,%D0,Y+3) CR_TAB
2145 AS2 (subi,r28,lo8(%o1)) CR_TAB
2146 AS2 (sbci,r29,hi8(%o1)));
2149 reg_base = true_regnum (XEXP (base, 0));
2150 if (reg_base == REG_X)
2153 if (reg_dest == REG_X)
2156 /* "ld r26,-X" is undefined */
2157 return (AS2 (adiw,r26,%o1+3) CR_TAB
2158 AS2 (ld,r29,X) CR_TAB
2159 AS2 (ld,r28,-X) CR_TAB
2160 AS2 (ld,__tmp_reg__,-X) CR_TAB
2161 AS2 (sbiw,r26,1) CR_TAB
2162 AS2 (ld,r26,X) CR_TAB
2163 AS2 (mov,r27,__tmp_reg__));
2166 if (reg_dest == REG_X - 2)
2167 return (AS2 (adiw,r26,%o1) CR_TAB
2168 AS2 (ld,r24,X+) CR_TAB
2169 AS2 (ld,r25,X+) CR_TAB
2170 AS2 (ld,__tmp_reg__,X+) CR_TAB
2171 AS2 (ld,r27,X) CR_TAB
2172 AS2 (mov,r26,__tmp_reg__));
2174 return (AS2 (adiw,r26,%o1) CR_TAB
2175 AS2 (ld,%A0,X+) CR_TAB
2176 AS2 (ld,%B0,X+) CR_TAB
2177 AS2 (ld,%C0,X+) CR_TAB
2178 AS2 (ld,%D0,X) CR_TAB
2179 AS2 (sbiw,r26,%o1+3));
2181 if (reg_dest == reg_base)
2182 return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2183 AS2 (ldd,%C0,%C1) CR_TAB
2184 AS2 (ldd,__tmp_reg__,%B1) CR_TAB
2185 AS2 (ldd,%A0,%A1) CR_TAB
2186 AS2 (mov,%B0,__tmp_reg__));
2187 else if (reg_dest == reg_base - 2)
2188 return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2189 AS2 (ldd,%B0,%B1) CR_TAB
2190 AS2 (ldd,__tmp_reg__,%C1) CR_TAB
2191 AS2 (ldd,%D0,%D1) CR_TAB
2192 AS2 (mov,%C0,__tmp_reg__));
2193 return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2194 AS2 (ldd,%B0,%B1) CR_TAB
2195 AS2 (ldd,%C0,%C1) CR_TAB
2198 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2199 return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2200 AS2 (ld,%C0,%1) CR_TAB
2201 AS2 (ld,%B0,%1) CR_TAB
2203 else if (GET_CODE (base) == POST_INC) /* (R++) */
2204 return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2205 AS2 (ld,%B0,%1) CR_TAB
2206 AS2 (ld,%C0,%1) CR_TAB
2208 else if (CONSTANT_ADDRESS_P (base))
2209 return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2210 AS2 (lds,%B0,%B1) CR_TAB
2211 AS2 (lds,%C0,%C1) CR_TAB
2214 fatal_insn ("unknown move insn:",insn);
2219 out_movsi_mr_r (insn, op, l)
2226 rtx base = XEXP (dest, 0);
2227 int reg_base = true_regnum (base);
2228 int reg_src = true_regnum (src);
2234 if (CONSTANT_ADDRESS_P (base))
2235 return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2236 AS2 (sts,%B0,%B1) CR_TAB
2237 AS2 (sts,%C0,%C1) CR_TAB
2239 if (reg_base > 0) /* (r) */
2241 if (reg_base == REG_X) /* (R26) */
2243 if (reg_src == REG_X)
2245 /* "st X+,r26" is undefined */
2246 if (reg_unused_after (insn, base))
2247 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2248 AS2 (st,X,r26) CR_TAB
2249 AS2 (adiw,r26,1) CR_TAB
2250 AS2 (st,X+,__tmp_reg__) CR_TAB
2251 AS2 (st,X+,r28) CR_TAB
2254 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2255 AS2 (st,X,r26) CR_TAB
2256 AS2 (adiw,r26,1) CR_TAB
2257 AS2 (st,X+,__tmp_reg__) CR_TAB
2258 AS2 (st,X+,r28) CR_TAB
2259 AS2 (st,X,r29) CR_TAB
2262 else if (reg_base == reg_src + 2)
2264 if (reg_unused_after (insn, base))
2265 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2266 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2267 AS2 (st,%0+,%A1) CR_TAB
2268 AS2 (st,%0+,%B1) CR_TAB
2269 AS2 (st,%0+,__zero_reg__) CR_TAB
2270 AS2 (st,%0,__tmp_reg__) CR_TAB
2271 AS1 (clr,__zero_reg__));
2273 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2274 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2275 AS2 (st,%0+,%A1) CR_TAB
2276 AS2 (st,%0+,%B1) CR_TAB
2277 AS2 (st,%0+,__zero_reg__) CR_TAB
2278 AS2 (st,%0,__tmp_reg__) CR_TAB
2279 AS1 (clr,__zero_reg__) CR_TAB
2282 return *l=5, (AS2 (st,%0+,%A1) CR_TAB
2283 AS2 (st,%0+,%B1) CR_TAB
2284 AS2 (st,%0+,%C1) CR_TAB
2285 AS2 (st,%0,%D1) CR_TAB
2289 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2290 AS2 (std,%0+1,%B1) CR_TAB
2291 AS2 (std,%0+2,%C1) CR_TAB
2292 AS2 (std,%0+3,%D1));
2294 else if (GET_CODE (base) == PLUS) /* (R + i) */
2296 int disp = INTVAL (XEXP (base, 1));
2297 reg_base = REGNO (XEXP (base, 0));
2298 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2300 if (reg_base != REG_Y)
2301 fatal_insn ("incorrect insn:",insn);
2303 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2304 return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2305 AS2 (std,Y+60,%A1) CR_TAB
2306 AS2 (std,Y+61,%B1) CR_TAB
2307 AS2 (std,Y+62,%C1) CR_TAB
2308 AS2 (std,Y+63,%D1) CR_TAB
2309 AS2 (sbiw,r28,%o0-60));
2311 return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2312 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2313 AS2 (st,Y,%A1) CR_TAB
2314 AS2 (std,Y+1,%B1) CR_TAB
2315 AS2 (std,Y+2,%C1) CR_TAB
2316 AS2 (std,Y+3,%D1) CR_TAB
2317 AS2 (subi,r28,lo8(%o0)) CR_TAB
2318 AS2 (sbci,r29,hi8(%o0)));
2320 if (reg_base == REG_X)
2323 if (reg_src == REG_X)
2326 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2327 AS2 (mov,__zero_reg__,r27) CR_TAB
2328 AS2 (adiw,r26,%o0) CR_TAB
2329 AS2 (st,X+,__tmp_reg__) CR_TAB
2330 AS2 (st,X+,__zero_reg__) CR_TAB
2331 AS2 (st,X+,r28) CR_TAB
2332 AS2 (st,X,r29) CR_TAB
2333 AS1 (clr,__zero_reg__) CR_TAB
2334 AS2 (sbiw,r26,%o0+3));
2336 else if (reg_src == REG_X - 2)
2339 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2340 AS2 (mov,__zero_reg__,r27) CR_TAB
2341 AS2 (adiw,r26,%o0) CR_TAB
2342 AS2 (st,X+,r24) CR_TAB
2343 AS2 (st,X+,r25) CR_TAB
2344 AS2 (st,X+,__tmp_reg__) CR_TAB
2345 AS2 (st,X,__zero_reg__) CR_TAB
2346 AS1 (clr,__zero_reg__) CR_TAB
2347 AS2 (sbiw,r26,%o0+3));
2350 return (AS2 (adiw,r26,%o0) CR_TAB
2351 AS2 (st,X+,%A1) CR_TAB
2352 AS2 (st,X+,%B1) CR_TAB
2353 AS2 (st,X+,%C1) CR_TAB
2354 AS2 (st,X,%D1) CR_TAB
2355 AS2 (sbiw,r26,%o0+3));
2357 return *l=4, (AS2 (std,%A0,%A1) CR_TAB
2358 AS2 (std,%B0,%B1) CR_TAB
2359 AS2 (std,%C0,%C1) CR_TAB
2362 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2363 return *l=4, (AS2 (st,%0,%D1) CR_TAB
2364 AS2 (st,%0,%C1) CR_TAB
2365 AS2 (st,%0,%B1) CR_TAB
2367 else if (GET_CODE (base) == POST_INC) /* (R++) */
2368 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2369 AS2 (st,%0,%B1) CR_TAB
2370 AS2 (st,%0,%C1) CR_TAB
2372 fatal_insn ("unknown move insn:",insn);
2377 output_movsisf(insn, operands, l)
2383 rtx dest = operands[0];
2384 rtx src = operands[1];
2390 if (register_operand (dest, VOIDmode))
2392 if (register_operand (src, VOIDmode)) /* mov r,r */
2394 if (true_regnum (dest) > true_regnum (src))
2399 return (AS2 (movw,%C0,%C1) CR_TAB
2400 AS2 (movw,%A0,%A1));
2403 return (AS2 (mov,%D0,%D1) CR_TAB
2404 AS2 (mov,%C0,%C1) CR_TAB
2405 AS2 (mov,%B0,%B1) CR_TAB
2413 return (AS2 (movw,%A0,%A1) CR_TAB
2414 AS2 (movw,%C0,%C1));
2417 return (AS2 (mov,%A0,%A1) CR_TAB
2418 AS2 (mov,%B0,%B1) CR_TAB
2419 AS2 (mov,%C0,%C1) CR_TAB
2423 else if (CONSTANT_P (src))
2425 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2427 if (byte_immediate_operand (src, SImode)
2428 && reg_was_0 (insn, dest))
2431 return (AS2 (ldi,%A0,lo8(%1) ; reg_was_0));
2435 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
2436 AS2 (ldi,%B0,hi8(%1)) CR_TAB
2437 AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2438 AS2 (ldi,%D0,hhi8(%1)));
2441 if (GET_CODE (src) == CONST_INT)
2443 const char *const clr_op0 =
2444 AVR_ENHANCED ? (AS1 (clr,%A0) CR_TAB
2445 AS1 (clr,%B0) CR_TAB
2447 : (AS1 (clr,%A0) CR_TAB
2448 AS1 (clr,%B0) CR_TAB
2449 AS1 (clr,%C0) CR_TAB
2452 if (src == const0_rtx) /* mov r,L */
2454 *l = AVR_ENHANCED ? 3 : 4;
2457 else if (src == const1_rtx)
2459 if (reg_was_0 (insn, dest))
2462 return AS1 (inc,%A0 ; reg_was_0);
2465 output_asm_insn (clr_op0, operands);
2466 *l = AVR_ENHANCED ? 4 : 5;
2467 return AS1 (inc,%A0);
2469 else if (src == constm1_rtx)
2471 /* Immediate constants -1 to any register */
2472 if (reg_was_0 (insn, dest))
2477 return (AS1 (dec,%A0) CR_TAB
2478 AS1 (dec,%B0) CR_TAB
2479 AS2 (movw,%C0,%A0));
2482 return (AS1 (dec,%D0 ; reg_was_0) CR_TAB
2483 AS1 (dec,%C0) CR_TAB
2484 AS1 (dec,%B0) CR_TAB
2490 return (AS1 (clr,%A0) CR_TAB
2491 AS1 (dec,%A0) CR_TAB
2492 AS2 (mov,%B0,%A0) CR_TAB
2493 AS2 (movw,%C0,%A0));
2496 return (AS1 (clr,%A0) CR_TAB
2497 AS1 (dec,%A0) CR_TAB
2498 AS2 (mov,%B0,%A0) CR_TAB
2499 AS2 (mov,%C0,%A0) CR_TAB
2504 int bit_nr = exact_log2 (INTVAL (src));
2508 if (reg_was_0 (insn, dest))
2512 output_asm_insn ("set ; reg_was_0", operands);
2516 *l = AVR_ENHANCED ? 5 : 6;
2519 output_asm_insn (clr_op0, operands);
2520 output_asm_insn ("set", operands);
2524 avr_output_bld (operands, bit_nr);
2531 /* Last resort, better than loading from memory. */
2533 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2534 AS2 (ldi,r31,lo8(%1)) CR_TAB
2535 AS2 (mov,%A0,r31) CR_TAB
2536 AS2 (ldi,r31,hi8(%1)) CR_TAB
2537 AS2 (mov,%B0,r31) CR_TAB
2538 AS2 (ldi,r31,hlo8(%1)) CR_TAB
2539 AS2 (mov,%C0,r31) CR_TAB
2540 AS2 (ldi,r31,hhi8(%1)) CR_TAB
2541 AS2 (mov,%D0,r31) CR_TAB
2542 AS2 (mov,r31,__tmp_reg__));
2544 else if (GET_CODE (src) == MEM)
2545 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2547 else if (GET_CODE (dest) == MEM)
2549 const char *template;
2551 if (src == const0_rtx)
2552 operands[1] = zero_reg_rtx;
2554 template = out_movsi_mr_r (insn, operands, real_l);
2557 output_asm_insn (template, operands);
2562 fatal_insn ("invalid insn:", insn);
2567 out_movqi_mr_r (insn, op, l)
2570 int *l; /* instruction length */
2574 rtx x = XEXP (dest, 0);
2580 if (CONSTANT_ADDRESS_P (x))
2582 if (avr_io_address_p (x, 1))
2585 return AS2 (out,%0-0x20,%1);
2588 return AS2 (sts,%0,%1);
2590 /* memory access by reg+disp */
2591 else if (GET_CODE (x) == PLUS
2592 && REG_P (XEXP (x,0))
2593 && GET_CODE (XEXP (x,1)) == CONST_INT)
2595 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2597 int disp = INTVAL (XEXP (x,1));
2598 if (REGNO (XEXP (x,0)) != REG_Y)
2599 fatal_insn ("incorrect insn:",insn);
2601 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2602 return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2603 AS2 (std,Y+63,%1) CR_TAB
2604 AS2 (sbiw,r28,%o0-63));
2606 return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2607 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2608 AS2 (st,Y,%1) CR_TAB
2609 AS2 (subi,r28,lo8(%o0)) CR_TAB
2610 AS2 (sbci,r29,hi8(%o0)));
2612 else if (REGNO (XEXP (x,0)) == REG_X)
2614 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2616 if (reg_unused_after (insn, XEXP (x,0)))
2617 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2618 AS2 (adiw,r26,%o0) CR_TAB
2619 AS2 (st,X,__tmp_reg__));
2621 return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2622 AS2 (adiw,r26,%o0) CR_TAB
2623 AS2 (st,X,__tmp_reg__) CR_TAB
2624 AS2 (sbiw,r26,%o0));
2628 if (reg_unused_after (insn, XEXP (x,0)))
2629 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2632 return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2633 AS2 (st,X,%1) CR_TAB
2634 AS2 (sbiw,r26,%o0));
2638 return AS2 (std,%0,%1);
2641 return AS2 (st,%0,%1);
2645 out_movhi_mr_r (insn, op, l)
2652 rtx base = XEXP (dest, 0);
2653 int reg_base = true_regnum (base);
2654 int reg_src = true_regnum (src);
2658 if (CONSTANT_ADDRESS_P (base))
2660 if (avr_io_address_p (base, 2))
2663 return (AS2 (out,%B0-0x20,%B1) CR_TAB
2664 AS2 (out,%A0-0x20,%A1));
2666 return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2671 if (reg_base == REG_X)
2673 if (reg_src == REG_X)
2675 /* "st X+,r26" is undefined */
2676 if (reg_unused_after (insn, src))
2677 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2678 AS2 (st,X,r26) CR_TAB
2679 AS2 (adiw,r26,1) CR_TAB
2680 AS2 (st,X,__tmp_reg__));
2682 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2683 AS2 (st,X,r26) CR_TAB
2684 AS2 (adiw,r26,1) CR_TAB
2685 AS2 (st,X,__tmp_reg__) CR_TAB
2690 if (reg_unused_after (insn, base))
2691 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2694 return *l=3, (AS2 (st ,X+,%A1) CR_TAB
2695 AS2 (st ,X,%B1) CR_TAB
2700 return *l=2, (AS2 (st ,%0,%A1) CR_TAB
2701 AS2 (std,%0+1,%B1));
2703 else if (GET_CODE (base) == PLUS)
2705 int disp = INTVAL (XEXP (base, 1));
2706 reg_base = REGNO (XEXP (base, 0));
2707 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2709 if (reg_base != REG_Y)
2710 fatal_insn ("incorrect insn:",insn);
2712 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2713 return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2714 AS2 (std,Y+62,%A1) CR_TAB
2715 AS2 (std,Y+63,%B1) CR_TAB
2716 AS2 (sbiw,r28,%o0-62));
2718 return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2719 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2720 AS2 (st,Y,%A1) CR_TAB
2721 AS2 (std,Y+1,%B1) CR_TAB
2722 AS2 (subi,r28,lo8(%o0)) CR_TAB
2723 AS2 (sbci,r29,hi8(%o0)));
2725 if (reg_base == REG_X)
2728 if (reg_src == REG_X)
2731 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2732 AS2 (mov,__zero_reg__,r27) CR_TAB
2733 AS2 (adiw,r26,%o0) CR_TAB
2734 AS2 (st,X+,__tmp_reg__) CR_TAB
2735 AS2 (st,X,__zero_reg__) CR_TAB
2736 AS1 (clr,__zero_reg__) CR_TAB
2737 AS2 (sbiw,r26,%o0+1));
2740 return (AS2 (adiw,r26,%o0) CR_TAB
2741 AS2 (st,X+,%A1) CR_TAB
2742 AS2 (st,X,%B1) CR_TAB
2743 AS2 (sbiw,r26,%o0+1));
2745 return *l=2, (AS2 (std,%A0,%A1) CR_TAB
2748 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2749 return *l=2, (AS2 (st,%0,%B1) CR_TAB
2751 else if (GET_CODE (base) == POST_INC) /* (R++) */
2752 return *l=2, (AS2 (st,%0,%A1) CR_TAB
2754 fatal_insn ("unknown move insn:",insn);
2758 /* Return 1 if frame pointer for current function required */
2761 frame_pointer_required_p ()
2763 return (current_function_calls_alloca
2764 || current_function_args_info.nregs == 0
2765 || current_function_varargs
2766 || get_frame_size () > 0);
2769 /* Returns the condition of compare insn INSN, or UNKNOWN. */
2772 compare_condition (insn)
2775 rtx next = next_real_insn (insn);
2776 RTX_CODE cond = UNKNOWN;
2777 if (next && GET_CODE (next) == JUMP_INSN)
2779 rtx pat = PATTERN (next);
2780 rtx src = SET_SRC (pat);
2781 rtx t = XEXP (src, 0);
2782 cond = GET_CODE (t);
2787 /* Returns nonzero if INSN is a tst insn that only tests the sign. */
2790 compare_sign_p (insn)
2793 RTX_CODE cond = compare_condition (insn);
2794 return (cond == GE || cond == LT);
2797 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
2798 that needs to be swapped (GT, GTU, LE, LEU). */
2801 compare_diff_p (insn)
2804 RTX_CODE cond = compare_condition (insn);
2805 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2808 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition. */
2814 RTX_CODE cond = compare_condition (insn);
2815 return (cond == EQ || cond == NE);
2819 /* Output test instruction for HImode */
2826 if (compare_sign_p (insn))
2829 return AS1 (tst,%B0);
2831 if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
2832 && compare_eq_p (insn))
2834 /* faster than sbiw if we can clobber the operand */
2836 return AS2 (or,%A0,%B0);
2838 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2841 return AS2 (sbiw,%0,0);
2844 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2845 AS2 (cpc,%B0,__zero_reg__));
2849 /* Output test instruction for SImode */
2856 if (compare_sign_p (insn))
2859 return AS1 (tst,%D0);
2861 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2864 return (AS2 (sbiw,%A0,0) CR_TAB
2865 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2866 AS2 (cpc,%D0,__zero_reg__));
2869 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2870 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2871 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2872 AS2 (cpc,%D0,__zero_reg__));
2876 /* Generate asm equivalent for various shifts.
2877 Shift count is a CONST_INT, MEM or REG.
2878 This only handles cases that are not already
2879 carefully hand-optimized in ?sh??i3_out. */
2882 out_shift_with_cnt (template, insn, operands, len, t_len)
2883 const char *template;
2887 int t_len; /* Length of template. */
2891 int second_label = 1;
2892 int saved_in_tmp = 0;
2893 int use_zero_reg = 0;
2895 op[0] = operands[0];
2896 op[1] = operands[1];
2897 op[2] = operands[2];
2898 op[3] = operands[3];
2904 if (GET_CODE (operands[2]) == CONST_INT)
2906 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2907 int count = INTVAL (operands[2]);
2908 int max_len = 10; /* If larger than this, always use a loop. */
2910 if (count < 8 && !scratch)
2914 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
2916 if (t_len * count <= max_len)
2918 /* Output shifts inline with no loop - faster. */
2920 *len = t_len * count;
2924 output_asm_insn (template, op);
2933 strcat (str, AS2 (ldi,%3,%2));
2935 else if (use_zero_reg)
2937 /* Hack to save one word: use __zero_reg__ as loop counter.
2938 Set one bit, then shift in a loop until it is 0 again. */
2940 op[3] = zero_reg_rtx;
2944 strcat (str, ("set" CR_TAB
2945 AS2 (bld,%3,%2-1)));
2949 /* No scratch register available, use one from LD_REGS (saved in
2950 __tmp_reg__) that doesn't overlap with registers to shift. */
2952 op[3] = gen_rtx (REG, QImode,
2953 ((true_regnum (operands[0]) - 1) & 15) + 16);
2954 op[4] = tmp_reg_rtx;
2958 *len = 3; /* Includes "mov %3,%4" after the loop. */
2960 strcat (str, (AS2 (mov,%4,%3) CR_TAB
2966 else if (GET_CODE (operands[2]) == MEM)
2970 op[3] = op_mov[0] = tmp_reg_rtx;
2974 out_movqi_r_mr (insn, op_mov, len);
2976 output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2978 else if (register_operand (operands[2], QImode))
2980 if (reg_unused_after (insn, operands[2]))
2984 op[3] = tmp_reg_rtx;
2986 strcat (str, (AS2 (mov,%3,%2) CR_TAB));
2990 fatal_insn ("bad shift insn:", insn);
2997 strcat (str, AS1 (rjmp,2f));
3001 *len += t_len + 2; /* template + dec + brXX */
3004 strcat (str, "\n1:\t");
3005 strcat (str, template);
3006 strcat (str, second_label ? "\n2:\t" : "\n\t");
3007 strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
3008 strcat (str, CR_TAB);
3009 strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
3011 strcat (str, (CR_TAB AS2 (mov,%3,%4)));
3012 output_asm_insn (str, op);
3017 /* 8bit shift left ((char)x << i) */
3020 ashlqi3_out (insn, operands, len)
3023 int *len; /* insn length (may be NULL) */
3025 if (GET_CODE (operands[2]) == CONST_INT)
3032 switch (INTVAL (operands[2]))
3036 return AS1 (clr,%0);
3040 return AS1 (lsl,%0);
3044 return (AS1 (lsl,%0) CR_TAB
3049 return (AS1 (lsl,%0) CR_TAB
3054 if (test_hard_reg_class (LD_REGS, operands[0]))
3057 return (AS1 (swap,%0) CR_TAB
3058 AS2 (andi,%0,0xf0));
3061 return (AS1 (lsl,%0) CR_TAB
3067 if (test_hard_reg_class (LD_REGS, operands[0]))
3070 return (AS1 (swap,%0) CR_TAB
3072 AS2 (andi,%0,0xe0));
3075 return (AS1 (lsl,%0) CR_TAB
3082 if (test_hard_reg_class (LD_REGS, operands[0]))
3085 return (AS1 (swap,%0) CR_TAB
3088 AS2 (andi,%0,0xc0));
3091 return (AS1 (lsl,%0) CR_TAB
3100 return (AS1 (ror,%0) CR_TAB
3105 else if (CONSTANT_P (operands[2]))
3106 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3108 out_shift_with_cnt (AS1 (lsl,%0),
3109 insn, operands, len, 1);
3114 /* 16bit shift left ((short)x << i) */
3117 ashlhi3_out (insn, operands, len)
3122 if (GET_CODE (operands[2]) == CONST_INT)
3124 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3125 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3132 switch (INTVAL (operands[2]))
3135 if (optimize_size && scratch)
3140 return (AS1 (swap,%A0) CR_TAB
3141 AS1 (swap,%B0) CR_TAB
3142 AS2 (andi,%B0,0xf0) CR_TAB
3143 AS2 (eor,%B0,%A0) CR_TAB
3144 AS2 (andi,%A0,0xf0) CR_TAB
3150 return (AS1 (swap,%A0) CR_TAB
3151 AS1 (swap,%B0) CR_TAB
3152 AS2 (ldi,%3,0xf0) CR_TAB
3153 AS2 (and,%B0,%3) CR_TAB
3154 AS2 (eor,%B0,%A0) CR_TAB
3155 AS2 (and,%A0,%3) CR_TAB
3158 break; /* optimize_size ? 6 : 8 */
3162 break; /* scratch ? 5 : 6 */
3166 return (AS1 (lsl,%A0) CR_TAB
3167 AS1 (rol,%B0) CR_TAB
3168 AS1 (swap,%A0) CR_TAB
3169 AS1 (swap,%B0) CR_TAB
3170 AS2 (andi,%B0,0xf0) CR_TAB
3171 AS2 (eor,%B0,%A0) CR_TAB
3172 AS2 (andi,%A0,0xf0) CR_TAB
3178 return (AS1 (lsl,%A0) CR_TAB
3179 AS1 (rol,%B0) CR_TAB
3180 AS1 (swap,%A0) CR_TAB
3181 AS1 (swap,%B0) CR_TAB
3182 AS2 (ldi,%3,0xf0) CR_TAB
3183 AS2 (and,%B0,%3) CR_TAB
3184 AS2 (eor,%B0,%A0) CR_TAB
3185 AS2 (and,%A0,%3) CR_TAB
3192 break; /* scratch ? 5 : 6 */
3194 return (AS1 (clr,__tmp_reg__) CR_TAB
3195 AS1 (lsr,%B0) CR_TAB
3196 AS1 (ror,%A0) CR_TAB
3197 AS1 (ror,__tmp_reg__) CR_TAB
3198 AS1 (lsr,%B0) CR_TAB
3199 AS1 (ror,%A0) CR_TAB
3200 AS1 (ror,__tmp_reg__) CR_TAB
3201 AS2 (mov,%B0,%A0) CR_TAB
3202 AS2 (mov,%A0,__tmp_reg__));
3206 return (AS1 (lsr,%B0) CR_TAB
3207 AS2 (mov,%B0,%A0) CR_TAB
3208 AS1 (clr,%A0) CR_TAB
3209 AS1 (ror,%B0) CR_TAB
3213 if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
3214 return *len = 1, AS1 (clr,%A0);
3216 return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3221 return (AS2 (mov,%B0,%A0) CR_TAB
3222 AS1 (clr,%A0) CR_TAB
3227 return (AS2 (mov,%B0,%A0) CR_TAB
3228 AS1 (clr,%A0) CR_TAB
3229 AS1 (lsl,%B0) CR_TAB
3234 return (AS2 (mov,%B0,%A0) CR_TAB
3235 AS1 (clr,%A0) CR_TAB
3236 AS1 (lsl,%B0) CR_TAB
3237 AS1 (lsl,%B0) CR_TAB
3244 return (AS2 (mov,%B0,%A0) CR_TAB
3245 AS1 (clr,%A0) CR_TAB
3246 AS1 (swap,%B0) CR_TAB
3247 AS2 (andi,%B0,0xf0));
3252 return (AS2 (mov,%B0,%A0) CR_TAB
3253 AS1 (clr,%A0) CR_TAB
3254 AS1 (swap,%B0) CR_TAB
3255 AS2 (ldi,%3,0xf0) CR_TAB
3259 return (AS2 (mov,%B0,%A0) CR_TAB
3260 AS1 (clr,%A0) CR_TAB
3261 AS1 (lsl,%B0) CR_TAB
3262 AS1 (lsl,%B0) CR_TAB
3263 AS1 (lsl,%B0) CR_TAB
3270 return (AS2 (mov,%B0,%A0) CR_TAB
3271 AS1 (clr,%A0) CR_TAB
3272 AS1 (swap,%B0) CR_TAB
3273 AS1 (lsl,%B0) CR_TAB
3274 AS2 (andi,%B0,0xe0));
3276 if (AVR_ENHANCED && scratch)
3279 return (AS2 (ldi,%3,0x20) CR_TAB
3280 AS2 (mul,%A0,%3) CR_TAB
3281 AS2 (mov,%B0,r0) CR_TAB
3282 AS1 (clr,%A0) CR_TAB
3283 AS1 (clr,__zero_reg__));
3285 if (optimize_size && scratch)
3290 return (AS2 (mov,%B0,%A0) CR_TAB
3291 AS1 (clr,%A0) CR_TAB
3292 AS1 (swap,%B0) CR_TAB
3293 AS1 (lsl,%B0) CR_TAB
3294 AS2 (ldi,%3,0xe0) CR_TAB
3300 return ("set" CR_TAB
3301 AS2 (bld,r1,5) CR_TAB
3302 AS2 (mul,%A0,r1) CR_TAB
3303 AS2 (mov,%B0,r0) CR_TAB
3304 AS1 (clr,%A0) CR_TAB
3305 AS1 (clr,__zero_reg__));
3308 return (AS2 (mov,%B0,%A0) CR_TAB
3309 AS1 (clr,%A0) CR_TAB
3310 AS1 (lsl,%B0) CR_TAB
3311 AS1 (lsl,%B0) CR_TAB
3312 AS1 (lsl,%B0) CR_TAB
3313 AS1 (lsl,%B0) CR_TAB
3317 if (AVR_ENHANCED && ldi_ok)
3320 return (AS2 (ldi,%B0,0x40) CR_TAB
3321 AS2 (mul,%A0,%B0) CR_TAB
3322 AS2 (mov,%B0,r0) CR_TAB
3323 AS1 (clr,%A0) CR_TAB
3324 AS1 (clr,__zero_reg__));
3326 if (AVR_ENHANCED && scratch)
3329 return (AS2 (ldi,%3,0x40) CR_TAB
3330 AS2 (mul,%A0,%3) CR_TAB
3331 AS2 (mov,%B0,r0) CR_TAB
3332 AS1 (clr,%A0) CR_TAB
3333 AS1 (clr,__zero_reg__));
3335 if (optimize_size && ldi_ok)
3338 return (AS2 (mov,%B0,%A0) CR_TAB
3339 AS2 (ldi,%A0,6) "\n1:\t"
3340 AS1 (lsl,%B0) CR_TAB
3341 AS1 (dec,%A0) CR_TAB
3344 if (optimize_size && scratch)
3347 return (AS1 (clr,%B0) CR_TAB
3348 AS1 (lsr,%A0) CR_TAB
3349 AS1 (ror,%B0) CR_TAB
3350 AS1 (lsr,%A0) CR_TAB
3351 AS1 (ror,%B0) CR_TAB
3356 return (AS1 (clr,%B0) CR_TAB
3357 AS1 (lsr,%A0) CR_TAB
3358 AS1 (ror,%B0) CR_TAB
3363 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3365 insn, operands, len, 2);
3370 /* 32bit shift left ((long)x << i) */
3373 ashlsi3_out (insn, operands, len)
3378 if (GET_CODE (operands[2]) == CONST_INT)
3386 switch (INTVAL (operands[2]))
3390 int reg0 = true_regnum (operands[0]);
3391 int reg1 = true_regnum (operands[1]);
3394 return (AS2 (mov,%D0,%C1) CR_TAB
3395 AS2 (mov,%C0,%B1) CR_TAB
3396 AS2 (mov,%B0,%A1) CR_TAB
3398 else if (reg0 + 1 == reg1)
3401 return AS1 (clr,%A0);
3404 return (AS1 (clr,%A0) CR_TAB
3405 AS2 (mov,%B0,%A1) CR_TAB
3406 AS2 (mov,%C0,%B1) CR_TAB
3412 int reg0 = true_regnum (operands[0]);
3413 int reg1 = true_regnum (operands[1]);
3415 if (AVR_ENHANCED && (reg0 + 2 != reg1))
3418 return (AS2 (movw,%C0,%A1) CR_TAB
3419 AS1 (clr,%B0) CR_TAB
3422 if (reg0 + 1 >= reg1)
3423 return (AS2 (mov,%D0,%B1) CR_TAB
3424 AS2 (mov,%C0,%A1) CR_TAB
3425 AS1 (clr,%B0) CR_TAB
3427 if (reg0 + 2 == reg1)
3430 return (AS1 (clr,%B0) CR_TAB
3434 return (AS2 (mov,%C0,%A1) CR_TAB
3435 AS2 (mov,%D0,%B1) CR_TAB
3436 AS1 (clr,%B0) CR_TAB
3442 if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
3443 return (AS2 (mov,%D0,%A1) CR_TAB
3444 AS1 (clr,%C0) CR_TAB
3445 AS1 (clr,%B0) CR_TAB
3450 return (AS1 (clr,%C0) CR_TAB
3451 AS1 (clr,%B0) CR_TAB
3457 return (AS1 (clr,%D0) CR_TAB
3458 AS1 (lsr,%A0) CR_TAB
3459 AS1 (ror,%D0) CR_TAB
3460 AS1 (clr,%C0) CR_TAB
3461 AS1 (clr,%B0) CR_TAB
3466 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3467 AS1 (rol,%B0) CR_TAB
3468 AS1 (rol,%C0) CR_TAB
3470 insn, operands, len, 4);
3474 /* 8bit arithmetic shift right ((signed char)x >> i) */
3477 ashrqi3_out (insn, operands, len)
3480 int *len; /* insn length */
3482 if (GET_CODE (operands[2]) == CONST_INT)
3489 switch (INTVAL (operands[2]))
3493 return AS1 (asr,%0);
3497 return (AS1 (asr,%0) CR_TAB
3502 return (AS1 (asr,%0) CR_TAB
3508 return (AS1 (asr,%0) CR_TAB
3515 return (AS1 (asr,%0) CR_TAB
3523 return (AS2 (bst,%0,6) CR_TAB
3525 AS2 (sbc,%0,%0) CR_TAB
3531 return (AS1 (lsl,%0) CR_TAB
3535 else if (CONSTANT_P (operands[2]))
3536 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3538 out_shift_with_cnt (AS1 (asr,%0),
3539 insn, operands, len, 1);
3544 /* 16bit arithmetic shift right ((signed short)x >> i) */
3547 ashrhi3_out (insn, operands, len)
3552 if (GET_CODE (operands[2]) == CONST_INT)
3554 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3555 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3562 switch (INTVAL (operands[2]))
3566 /* XXX try to optimize this too? */
3571 break; /* scratch ? 5 : 6 */
3573 return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3574 AS2 (mov,%A0,%B0) CR_TAB
3575 AS1 (lsl,__tmp_reg__) CR_TAB
3576 AS1 (rol,%A0) CR_TAB
3577 AS2 (sbc,%B0,%B0) CR_TAB
3578 AS1 (lsl,__tmp_reg__) CR_TAB
3579 AS1 (rol,%A0) CR_TAB
3584 return (AS1 (lsl,%A0) CR_TAB
3585 AS2 (mov,%A0,%B0) CR_TAB
3586 AS1 (rol,%A0) CR_TAB
3591 int reg0 = true_regnum (operands[0]);
3592 int reg1 = true_regnum (operands[1]);
3595 return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3596 AS1 (lsl,%B0) CR_TAB
3598 else if (reg0 == reg1 + 1)
3599 return *len = 3, (AS1 (clr,%B0) CR_TAB
3600 AS2 (sbrc,%A0,7) CR_TAB
3603 return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3604 AS1 (clr,%B0) CR_TAB
3605 AS2 (sbrc,%A0,7) CR_TAB
3611 return (AS2 (mov,%A0,%B0) CR_TAB
3612 AS1 (lsl,%B0) CR_TAB
3613 AS2 (sbc,%B0,%B0) CR_TAB
3618 return (AS2 (mov,%A0,%B0) CR_TAB
3619 AS1 (lsl,%B0) CR_TAB
3620 AS2 (sbc,%B0,%B0) CR_TAB
3621 AS1 (asr,%A0) CR_TAB
3625 if (AVR_ENHANCED && ldi_ok)
3628 return (AS2 (ldi,%A0,0x20) CR_TAB
3629 AS2 (muls,%B0,%A0) CR_TAB
3630 AS2 (mov,%A0,r1) CR_TAB
3631 AS2 (sbc,%B0,%B0) CR_TAB
3632 AS1 (clr,__zero_reg__));
3634 if (optimize_size && scratch)
3637 return (AS2 (mov,%A0,%B0) CR_TAB
3638 AS1 (lsl,%B0) CR_TAB
3639 AS2 (sbc,%B0,%B0) CR_TAB
3640 AS1 (asr,%A0) CR_TAB
3641 AS1 (asr,%A0) CR_TAB
3645 if (AVR_ENHANCED && ldi_ok)
3648 return (AS2 (ldi,%A0,0x10) CR_TAB
3649 AS2 (muls,%B0,%A0) CR_TAB
3650 AS2 (mov,%A0,r1) CR_TAB
3651 AS2 (sbc,%B0,%B0) CR_TAB
3652 AS1 (clr,__zero_reg__));
3654 if (optimize_size && scratch)
3657 return (AS2 (mov,%A0,%B0) CR_TAB
3658 AS1 (lsl,%B0) CR_TAB
3659 AS2 (sbc,%B0,%B0) CR_TAB
3660 AS1 (asr,%A0) CR_TAB
3661 AS1 (asr,%A0) CR_TAB
3662 AS1 (asr,%A0) CR_TAB
3666 if (AVR_ENHANCED && ldi_ok)
3669 return (AS2 (ldi,%A0,0x08) CR_TAB
3670 AS2 (muls,%B0,%A0) CR_TAB
3671 AS2 (mov,%A0,r1) CR_TAB
3672 AS2 (sbc,%B0,%B0) CR_TAB
3673 AS1 (clr,__zero_reg__));
3676 break; /* scratch ? 5 : 7 */
3678 return (AS2 (mov,%A0,%B0) CR_TAB
3679 AS1 (lsl,%B0) CR_TAB
3680 AS2 (sbc,%B0,%B0) CR_TAB
3681 AS1 (asr,%A0) CR_TAB
3682 AS1 (asr,%A0) CR_TAB
3683 AS1 (asr,%A0) CR_TAB
3684 AS1 (asr,%A0) CR_TAB
3689 return (AS1 (lsl,%B0) CR_TAB
3690 AS2 (sbc,%A0,%A0) CR_TAB
3691 AS1 (lsl,%B0) CR_TAB
3692 AS2 (mov,%B0,%A0) CR_TAB
3696 return *len = 3, (AS1 (lsl,%B0) CR_TAB
3697 AS2 (sbc,%A0,%A0) CR_TAB
3702 out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3704 insn, operands, len, 2);
3709 /* 32bit arithmetic shift right ((signed long)x >> i) */
3712 ashrsi3_out (insn, operands, len)
3717 if (GET_CODE (operands[2]) == CONST_INT)
3725 switch (INTVAL (operands[2]))
3729 int reg0 = true_regnum (operands[0]);
3730 int reg1 = true_regnum (operands[1]);
3733 return (AS2 (mov,%A0,%B1) CR_TAB
3734 AS2 (mov,%B0,%C1) CR_TAB
3735 AS2 (mov,%C0,%D1) CR_TAB
3736 AS1 (clr,%D0) CR_TAB
3737 AS2 (sbrc,%C0,7) CR_TAB
3739 else if (reg0 == reg1 + 1)
3742 return (AS1 (clr,%D0) CR_TAB
3743 AS2 (sbrc,%C0,7) CR_TAB
3747 return (AS1 (clr,%D0) CR_TAB
3748 AS2 (sbrc,%D1,7) CR_TAB
3749 AS1 (dec,%D0) CR_TAB
3750 AS2 (mov,%C0,%D1) CR_TAB
3751 AS2 (mov,%B0,%C1) CR_TAB
3757 int reg0 = true_regnum (operands[0]);
3758 int reg1 = true_regnum (operands[1]);
3760 if (AVR_ENHANCED && (reg0 != reg1 + 2))
3763 return (AS2 (movw,%A0,%C1) CR_TAB
3764 AS1 (clr,%D0) CR_TAB
3765 AS2 (sbrc,%B0,7) CR_TAB
3766 AS1 (com,%D0) CR_TAB
3769 if (reg0 <= reg1 + 1)
3770 return (AS2 (mov,%A0,%C1) CR_TAB
3771 AS2 (mov,%B0,%D1) CR_TAB
3772 AS1 (clr,%D0) CR_TAB
3773 AS2 (sbrc,%B0,7) CR_TAB
3774 AS1 (com,%D0) CR_TAB
3776 else if (reg0 == reg1 + 2)
3777 return *len = 4, (AS1 (clr,%D0) CR_TAB
3778 AS2 (sbrc,%B0,7) CR_TAB
3779 AS1 (com,%D0) CR_TAB
3782 return (AS2 (mov,%B0,%D1) CR_TAB
3783 AS2 (mov,%A0,%C1) CR_TAB
3784 AS1 (clr,%D0) CR_TAB
3785 AS2 (sbrc,%B0,7) CR_TAB
3786 AS1 (com,%D0) CR_TAB
3791 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3792 return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3793 AS1 (clr,%D0) CR_TAB
3794 AS2 (sbrc,%A0,7) CR_TAB
3795 AS1 (com,%D0) CR_TAB
3796 AS2 (mov,%B0,%D0) CR_TAB
3799 return *len = 5, (AS1 (clr,%D0) CR_TAB
3800 AS2 (sbrc,%A0,7) CR_TAB
3801 AS1 (com,%D0) CR_TAB
3802 AS2 (mov,%B0,%D0) CR_TAB
3807 return *len = 4, (AS1 (lsl,%D0) CR_TAB
3808 AS2 (sbc,%A0,%A0) CR_TAB
3809 AS2 (mov,%B0,%A0) CR_TAB
3810 AS2 (movw,%C0,%A0));
3812 return *len = 5, (AS1 (lsl,%D0) CR_TAB
3813 AS2 (sbc,%A0,%A0) CR_TAB
3814 AS2 (mov,%B0,%A0) CR_TAB
3815 AS2 (mov,%C0,%A0) CR_TAB
3820 out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
3821 AS1 (ror,%C0) CR_TAB
3822 AS1 (ror,%B0) CR_TAB
3824 insn, operands, len, 4);
3828 /* 8bit logic shift right ((unsigned char)x >> i) */
3831 lshrqi3_out (insn, operands, len)
3836 if (GET_CODE (operands[2]) == CONST_INT)
3843 switch (INTVAL (operands[2]))
3847 return AS1 (clr,%0);
3851 return AS1 (lsr,%0);
3855 return (AS1 (lsr,%0) CR_TAB
3859 return (AS1 (lsr,%0) CR_TAB
3864 if (test_hard_reg_class (LD_REGS, operands[0]))
3867 return (AS1 (swap,%0) CR_TAB
3868 AS2 (andi,%0,0x0f));
3871 return (AS1 (lsr,%0) CR_TAB
3877 if (test_hard_reg_class (LD_REGS, operands[0]))
3880 return (AS1 (swap,%0) CR_TAB
3885 return (AS1 (lsr,%0) CR_TAB
3892 if (test_hard_reg_class (LD_REGS, operands[0]))
3895 return (AS1 (swap,%0) CR_TAB
3901 return (AS1 (lsr,%0) CR_TAB
3910 return (AS1 (rol,%0) CR_TAB
3915 else if (CONSTANT_P (operands[2]))
3916 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3918 out_shift_with_cnt (AS1 (lsr,%0),
3919 insn, operands, len, 1);
3923 /* 16bit logic shift right ((unsigned short)x >> i) */
3926 lshrhi3_out (insn, operands, len)
3931 if (GET_CODE (operands[2]) == CONST_INT)
3933 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3934 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3941 switch (INTVAL (operands[2]))
3944 if (optimize_size && scratch)
3949 return (AS1 (swap,%B0) CR_TAB
3950 AS1 (swap,%A0) CR_TAB
3951 AS2 (andi,%A0,0x0f) CR_TAB
3952 AS2 (eor,%A0,%B0) CR_TAB
3953 AS2 (andi,%B0,0x0f) CR_TAB
3959 return (AS1 (swap,%B0) CR_TAB
3960 AS1 (swap,%A0) CR_TAB
3961 AS2 (ldi,%3,0x0f) CR_TAB
3962 AS2 (and,%A0,%3) CR_TAB
3963 AS2 (eor,%A0,%B0) CR_TAB
3964 AS2 (and,%B0,%3) CR_TAB
3967 break; /* optimize_size ? 6 : 8 */
3971 break; /* scratch ? 5 : 6 */
3975 return (AS1 (lsr,%B0) CR_TAB
3976 AS1 (ror,%A0) CR_TAB
3977 AS1 (swap,%B0) CR_TAB
3978 AS1 (swap,%A0) CR_TAB
3979 AS2 (andi,%A0,0x0f) CR_TAB
3980 AS2 (eor,%A0,%B0) CR_TAB
3981 AS2 (andi,%B0,0x0f) CR_TAB
3987 return (AS1 (lsr,%B0) CR_TAB
3988 AS1 (ror,%A0) CR_TAB
3989 AS1 (swap,%B0) CR_TAB
3990 AS1 (swap,%A0) CR_TAB
3991 AS2 (ldi,%3,0x0f) CR_TAB
3992 AS2 (and,%A0,%3) CR_TAB
3993 AS2 (eor,%A0,%B0) CR_TAB
3994 AS2 (and,%B0,%3) CR_TAB
4001 break; /* scratch ? 5 : 6 */
4003 return (AS1 (clr,__tmp_reg__) CR_TAB
4004 AS1 (lsl,%A0) CR_TAB
4005 AS1 (rol,%B0) CR_TAB
4006 AS1 (rol,__tmp_reg__) CR_TAB
4007 AS1 (lsl,%A0) CR_TAB
4008 AS1 (rol,%B0) CR_TAB
4009 AS1 (rol,__tmp_reg__) CR_TAB
4010 AS2 (mov,%A0,%B0) CR_TAB
4011 AS2 (mov,%B0,__tmp_reg__));
4015 return (AS1 (lsl,%A0) CR_TAB
4016 AS2 (mov,%A0,%B0) CR_TAB
4017 AS1 (rol,%A0) CR_TAB
4018 AS2 (sbc,%B0,%B0) CR_TAB
4022 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
4023 return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
4026 return *len = 1, AS1 (clr,%B0);
4030 return (AS2 (mov,%A0,%B0) CR_TAB
4031 AS1 (clr,%B0) CR_TAB
4036 return (AS2 (mov,%A0,%B0) CR_TAB
4037 AS1 (clr,%B0) CR_TAB
4038 AS1 (lsr,%A0) CR_TAB
4043 return (AS2 (mov,%A0,%B0) CR_TAB
4044 AS1 (clr,%B0) CR_TAB
4045 AS1 (lsr,%A0) CR_TAB
4046 AS1 (lsr,%A0) CR_TAB
4053 return (AS2 (mov,%A0,%B0) CR_TAB
4054 AS1 (clr,%B0) CR_TAB
4055 AS1 (swap,%A0) CR_TAB
4056 AS2 (andi,%A0,0x0f));
4061 return (AS2 (mov,%A0,%B0) CR_TAB
4062 AS1 (clr,%B0) CR_TAB
4063 AS1 (swap,%A0) CR_TAB
4064 AS2 (ldi,%3,0x0f) CR_TAB
4068 return (AS2 (mov,%A0,%B0) CR_TAB
4069 AS1 (clr,%B0) CR_TAB
4070 AS1 (lsr,%A0) CR_TAB
4071 AS1 (lsr,%A0) CR_TAB
4072 AS1 (lsr,%A0) CR_TAB
4079 return (AS2 (mov,%A0,%B0) CR_TAB
4080 AS1 (clr,%B0) CR_TAB
4081 AS1 (swap,%A0) CR_TAB
4082 AS1 (lsr,%A0) CR_TAB
4083 AS2 (andi,%A0,0x07));
4085 if (AVR_ENHANCED && scratch)
4088 return (AS2 (ldi,%3,0x08) CR_TAB
4089 AS2 (mul,%B0,%3) CR_TAB
4090 AS2 (mov,%A0,r1) CR_TAB
4091 AS1 (clr,%B0) CR_TAB
4092 AS1 (clr,__zero_reg__));
4094 if (optimize_size && scratch)
4099 return (AS2 (mov,%A0,%B0) CR_TAB
4100 AS1 (clr,%B0) CR_TAB
4101 AS1 (swap,%A0) CR_TAB
4102 AS1 (lsr,%A0) CR_TAB
4103 AS2 (ldi,%3,0x07) CR_TAB
4109 return ("set" CR_TAB
4110 AS2 (bld,r1,3) CR_TAB
4111 AS2 (mul,%B0,r1) CR_TAB
4112 AS2 (mov,%A0,r1) CR_TAB
4113 AS1 (clr,%B0) CR_TAB
4114 AS1 (clr,__zero_reg__));
4117 return (AS2 (mov,%A0,%B0) CR_TAB
4118 AS1 (clr,%B0) CR_TAB
4119 AS1 (lsr,%A0) CR_TAB
4120 AS1 (lsr,%A0) CR_TAB
4121 AS1 (lsr,%A0) CR_TAB
4122 AS1 (lsr,%A0) CR_TAB
4126 if (AVR_ENHANCED && ldi_ok)
4129 return (AS2 (ldi,%A0,0x04) CR_TAB
4130 AS2 (mul,%B0,%A0) CR_TAB
4131 AS2 (mov,%A0,r1) CR_TAB
4132 AS1 (clr,%B0) CR_TAB
4133 AS1 (clr,__zero_reg__));
4135 if (AVR_ENHANCED && scratch)
4138 return (AS2 (ldi,%3,0x04) CR_TAB
4139 AS2 (mul,%B0,%3) CR_TAB
4140 AS2 (mov,%A0,r1) CR_TAB
4141 AS1 (clr,%B0) CR_TAB
4142 AS1 (clr,__zero_reg__));
4144 if (optimize_size && ldi_ok)
4147 return (AS2 (mov,%A0,%B0) CR_TAB
4148 AS2 (ldi,%B0,6) "\n1:\t"
4149 AS1 (lsr,%A0) CR_TAB
4150 AS1 (dec,%B0) CR_TAB
4153 if (optimize_size && scratch)
4156 return (AS1 (clr,%A0) CR_TAB
4157 AS1 (lsl,%B0) CR_TAB
4158 AS1 (rol,%A0) CR_TAB
4159 AS1 (lsl,%B0) CR_TAB
4160 AS1 (rol,%A0) CR_TAB
4165 return (AS1 (clr,%A0) CR_TAB
4166 AS1 (lsl,%B0) CR_TAB
4167 AS1 (rol,%A0) CR_TAB
4172 out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
4174 insn, operands, len, 2);
4178 /* 32bit logic shift right ((unsigned int)x >> i) */
4181 lshrsi3_out (insn, operands, len)
4186 if (GET_CODE (operands[2]) == CONST_INT)
4194 switch (INTVAL (operands[2]))
4198 int reg0 = true_regnum (operands[0]);
4199 int reg1 = true_regnum (operands[1]);
4202 return (AS2 (mov,%A0,%B1) CR_TAB
4203 AS2 (mov,%B0,%C1) CR_TAB
4204 AS2 (mov,%C0,%D1) CR_TAB
4206 else if (reg0 == reg1 + 1)
4207 return *len = 1, AS1 (clr,%D0);
4209 return (AS1 (clr,%D0) CR_TAB
4210 AS2 (mov,%C0,%D1) CR_TAB
4211 AS2 (mov,%B0,%C1) CR_TAB
4217 int reg0 = true_regnum (operands[0]);
4218 int reg1 = true_regnum (operands[1]);
4220 if (AVR_ENHANCED && (reg0 != reg1 + 2))
4223 return (AS2 (movw,%A0,%C1) CR_TAB
4224 AS1 (clr,%C0) CR_TAB
4227 if (reg0 <= reg1 + 1)
4228 return (AS2 (mov,%A0,%C1) CR_TAB
4229 AS2 (mov,%B0,%D1) CR_TAB
4230 AS1 (clr,%C0) CR_TAB
4232 else if (reg0 == reg1 + 2)
4233 return *len = 2, (AS1 (clr,%C0) CR_TAB
4236 return (AS2 (mov,%B0,%D1) CR_TAB
4237 AS2 (mov,%A0,%C1) CR_TAB
4238 AS1 (clr,%C0) CR_TAB
4243 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
4244 return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4245 AS1 (clr,%B0) CR_TAB
4246 AS1 (clr,%C0) CR_TAB
4249 return *len = 3, (AS1 (clr,%B0) CR_TAB
4250 AS1 (clr,%C0) CR_TAB
4255 return (AS1 (clr,%A0) CR_TAB
4256 AS2 (sbrc,%D0,7) CR_TAB
4257 AS1 (inc,%A0) CR_TAB
4258 AS1 (clr,%B0) CR_TAB
4259 AS1 (clr,%C0) CR_TAB
4264 out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4265 AS1 (ror,%C0) CR_TAB
4266 AS1 (ror,%B0) CR_TAB
4268 insn, operands, len, 4);
4272 /* Modifies the length assigned to instruction INSN
4273 LEN is the initially computed length of the insn. */
4276 adjust_insn_length (insn, len)
4280 rtx patt = PATTERN (insn);
4283 if (GET_CODE (patt) == SET)
4286 op[1] = SET_SRC (patt);
4287 op[0] = SET_DEST (patt);
4288 if (general_operand (op[1], VOIDmode)
4289 && general_operand (op[0], VOIDmode))
4291 switch (GET_MODE (op[0]))
4294 output_movqi (insn, op, &len);
4297 output_movhi (insn, op, &len);
4301 output_movsisf (insn, op, &len);
4307 else if (op[0] == cc0_rtx && REG_P (op[1]))
4309 switch (GET_MODE (op[1]))
4311 case HImode: out_tsthi (insn,&len); break;
4312 case SImode: out_tstsi (insn,&len); break;
4316 else if (GET_CODE (op[1]) == AND)
4318 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4320 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4321 if (GET_MODE (op[1]) == SImode)
4322 len = (((mask & 0xff) != 0xff)
4323 + ((mask & 0xff00) != 0xff00)
4324 + ((mask & 0xff0000L) != 0xff0000L)
4325 + ((mask & 0xff000000L) != 0xff000000L));
4326 else if (GET_MODE (op[1]) == HImode)
4327 len = (((mask & 0xff) != 0xff)
4328 + ((mask & 0xff00) != 0xff00));
4331 else if (GET_CODE (op[1]) == IOR)
4333 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4335 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4336 if (GET_MODE (op[1]) == SImode)
4337 len = (((mask & 0xff) != 0)
4338 + ((mask & 0xff00) != 0)
4339 + ((mask & 0xff0000L) != 0)
4340 + ((mask & 0xff000000L) != 0));
4341 else if (GET_MODE (op[1]) == HImode)
4342 len = (((mask & 0xff) != 0)
4343 + ((mask & 0xff00) != 0));
4347 set = single_set (insn);
4352 op[1] = SET_SRC (set);
4353 op[0] = SET_DEST (set);
4355 if (GET_CODE (patt) == PARALLEL
4356 && general_operand (op[1], VOIDmode)
4357 && general_operand (op[0], VOIDmode))
4359 if (XVECLEN (patt, 0) == 2)
4360 op[2] = XVECEXP (patt, 0, 1);
4362 switch (GET_MODE (op[0]))
4368 output_reload_inhi (insn, op, &len);
4372 output_reload_insisf (insn, op, &len);
4378 else if (GET_CODE (op[1]) == ASHIFT
4379 || GET_CODE (op[1]) == ASHIFTRT
4380 || GET_CODE (op[1]) == LSHIFTRT)
4384 ops[1] = XEXP (op[1],0);
4385 ops[2] = XEXP (op[1],1);
4386 switch (GET_CODE (op[1]))
4389 switch (GET_MODE (op[0]))
4391 case QImode: ashlqi3_out (insn,ops,&len); break;
4392 case HImode: ashlhi3_out (insn,ops,&len); break;
4393 case SImode: ashlsi3_out (insn,ops,&len); break;
4398 switch (GET_MODE (op[0]))
4400 case QImode: ashrqi3_out (insn,ops,&len); break;
4401 case HImode: ashrhi3_out (insn,ops,&len); break;
4402 case SImode: ashrsi3_out (insn,ops,&len); break;
4407 switch (GET_MODE (op[0]))
4409 case QImode: lshrqi3_out (insn,ops,&len); break;
4410 case HImode: lshrhi3_out (insn,ops,&len); break;
4411 case SImode: lshrsi3_out (insn,ops,&len); break;
4423 /* Return non-zero if register REG dead after INSN */
4426 reg_unused_after (insn, reg)
4430 return (dead_or_set_p (insn, reg)
4431 || (REG_P(reg) && _reg_unused_after (insn, reg)));
4434 /* Return non-zero if REG is not used after INSN.
4435 We assume REG is a reload reg, and therefore does
4436 not live past labels. It may live past calls or jumps though. */
4439 _reg_unused_after (insn, reg)
4446 /* If the reg is set by this instruction, then it is safe for our
4447 case. Disregard the case where this is a store to memory, since
4448 we are checking a register used in the store address. */
4449 set = single_set (insn);
4450 if (set && GET_CODE (SET_DEST (set)) != MEM
4451 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4454 while ((insn = NEXT_INSN (insn)))
4456 code = GET_CODE (insn);
4459 /* If this is a label that existed before reload, then the register
4460 if dead here. However, if this is a label added by reorg, then
4461 the register may still be live here. We can't tell the difference,
4462 so we just ignore labels completely. */
4463 if (code == CODE_LABEL)
4468 if (code == JUMP_INSN)
4471 /* If this is a sequence, we must handle them all at once.
4472 We could have for instance a call that sets the target register,
4473 and an insn in a delay slot that uses the register. In this case,
4474 we must return 0. */
4475 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
4480 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
4482 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
4483 rtx set = single_set (this_insn);
4485 if (GET_CODE (this_insn) == CALL_INSN)
4487 else if (GET_CODE (this_insn) == JUMP_INSN)
4489 if (INSN_ANNULLED_BRANCH_P (this_insn))
4494 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4496 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4498 if (GET_CODE (SET_DEST (set)) != MEM)
4504 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
4509 else if (code == JUMP_INSN)
4513 if (code == CALL_INSN)
4516 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4517 if (GET_CODE (XEXP (tem, 0)) == USE
4518 && REG_P (XEXP (XEXP (tem, 0), 0))
4519 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
4521 if (call_used_regs[REGNO (reg)])
4525 if (GET_RTX_CLASS (code) == 'i')
4527 rtx set = single_set (insn);
4529 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4531 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4532 return GET_CODE (SET_DEST (set)) != MEM;
4533 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
4540 /* Target hook for assembling integer objects. The AVR version needs
4541 special handling for references to certain labels. */
4544 avr_assemble_integer (x, size, aligned_p)
4549 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
4550 && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FLAG (x))
4551 || GET_CODE (x) == LABEL_REF))
4553 fputs ("\t.word\tpm(", asm_out_file);
4554 output_addr_const (asm_out_file, x);
4555 fputs (")\n", asm_out_file);
4558 return default_assemble_integer (x, size, aligned_p);
4561 /* Sets section name for declaration DECL */
4564 avr_unique_section (decl, reloc)
4566 int reloc ATTRIBUTE_UNUSED;
4569 const char *name, *prefix;
4572 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
4573 name = (* targetm.strip_name_encoding) (name);
4575 if (TREE_CODE (decl) == FUNCTION_DECL)
4577 if (flag_function_sections)
4585 if (flag_function_sections)
4587 len = strlen (name) + strlen (prefix);
4588 string = alloca (len + 1);
4589 sprintf (string, "%s%s", prefix, name);
4590 DECL_SECTION_NAME (decl) = build_string (len, string);
4595 /* The routine used to output NUL terminated strings. We use a special
4596 version of this for most svr4 targets because doing so makes the
4597 generated assembly code more compact (and thus faster to assemble)
4598 as well as more readable, especially for targets like the i386
4599 (where the only alternative is to output character sequences as
4600 comma separated lists of numbers). */
4603 gas_output_limited_string(file, str)
4607 const unsigned char *_limited_str = (unsigned char *) str;
4609 fprintf (file, "%s\"", STRING_ASM_OP);
4610 for (; (ch = *_limited_str); _limited_str++)
4613 switch (escape = ESCAPES[ch])
4619 fprintf (file, "\\%03o", ch);
4623 putc (escape, file);
4627 fprintf (file, "\"\n");
4630 /* The routine used to output sequences of byte values. We use a special
4631 version of this for most svr4 targets because doing so makes the
4632 generated assembly code more compact (and thus faster to assemble)
4633 as well as more readable. Note that if we find subparts of the
4634 character sequence which end with NUL (and which are shorter than
4635 STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
4638 gas_output_ascii(file, str, length)
4643 const unsigned char *_ascii_bytes = (const unsigned char *) str;
4644 const unsigned char *limit = _ascii_bytes + length;
4645 unsigned bytes_in_chunk = 0;
4646 for (; _ascii_bytes < limit; _ascii_bytes++)
4648 const unsigned char *p;
4649 if (bytes_in_chunk >= 60)
4651 fprintf (file, "\"\n");
4654 for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
4656 if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
4658 if (bytes_in_chunk > 0)
4660 fprintf (file, "\"\n");
4663 gas_output_limited_string (file, (char*)_ascii_bytes);
4670 if (bytes_in_chunk == 0)
4671 fprintf (file, "\t.ascii\t\"");
4672 switch (escape = ESCAPES[ch = *_ascii_bytes])
4679 fprintf (file, "\\%03o", ch);
4680 bytes_in_chunk += 4;
4684 putc (escape, file);
4685 bytes_in_chunk += 2;
4690 if (bytes_in_chunk > 0)
4691 fprintf (file, "\"\n");
4694 /* Return value is nonzero if pseudos that have been
4695 assigned to registers of class CLASS would likely be spilled
4696 because registers of CLASS are needed for spill registers. */
4699 class_likely_spilled_p (c)
4702 return (c != ALL_REGS && c != ADDW_REGS);
4705 /* Valid attributes:
4706 progmem - put data to program memory;
4707 signal - make a function to be hardware interrupt. After function
4708 prologue interrupts are disabled;
4709 interrupt - make a function to be hardware interrupt. After function
4710 prologue interrupts are enabled;
4711 naked - don't generate function prologue/epilogue and `ret' command.
4713 Only `progmem' attribute valid for type. */
4715 const struct attribute_spec avr_attribute_table[] =
4717 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
4718 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute },
4719 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4720 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4721 { "naked", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4722 { NULL, 0, 0, false, false, false, NULL }
4725 /* Handle a "progmem" attribute; arguments as in
4726 struct attribute_spec.handler. */
4728 avr_handle_progmem_attribute (node, name, args, flags, no_add_attrs)
4731 tree args ATTRIBUTE_UNUSED;
4732 int flags ATTRIBUTE_UNUSED;
4737 if (TREE_CODE (*node) == TYPE_DECL)
4739 /* This is really a decl attribute, not a type attribute,
4740 but try to handle it for GCC 3.0 backwards compatibility. */
4742 tree type = TREE_TYPE (*node);
4743 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
4744 tree newtype = build_type_attribute_variant (type, attr);
4746 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
4747 TREE_TYPE (*node) = newtype;
4748 *no_add_attrs = true;
4750 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
4752 if (DECL_INITIAL (*node) == NULL_TREE && !DECL_EXTERNAL (*node))
4754 warning ("only initialized variables can be placed into "
4755 "program memory area");
4756 *no_add_attrs = true;
4761 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
4762 *no_add_attrs = true;
4769 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
4770 struct attribute_spec.handler. */
4772 avr_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
4775 tree args ATTRIBUTE_UNUSED;
4776 int flags ATTRIBUTE_UNUSED;
4779 if (TREE_CODE (*node) != FUNCTION_DECL)
4781 warning ("`%s' attribute only applies to functions",
4782 IDENTIFIER_POINTER (name));
4783 *no_add_attrs = true;
4789 /* Look for attribute `progmem' in DECL
4790 if found return 1, otherwise 0. */
4793 avr_progmem_p (decl)
4798 if (TREE_CODE (decl) != VAR_DECL)
4802 != lookup_attribute ("progmem", DECL_ATTRIBUTES (decl)))
4808 while (TREE_CODE (a) == ARRAY_TYPE);
4810 if (a == error_mark_node)
4813 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
4819 /* Encode section information about tree DECL. */
4822 avr_encode_section_info (decl, first)
4826 if (TREE_CODE (decl) == FUNCTION_DECL)
4827 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
4829 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
4830 && TREE_CODE (decl) == VAR_DECL
4831 && avr_progmem_p (decl))
4833 static const char *const dsec = ".progmem.data";
4834 DECL_SECTION_NAME (decl) = build_string (strlen (dsec), dsec);
4835 TREE_READONLY (decl) = 1;
4840 avr_section_type_flags (decl, name, reloc)
4845 unsigned int flags = default_section_type_flags (decl, name, reloc);
4847 if (strncmp (name, ".noinit", 7) == 0)
4849 if (decl && TREE_CODE (decl) == VAR_DECL
4850 && DECL_INITIAL (decl) == NULL_TREE)
4851 flags |= SECTION_BSS; /* @nobits */
4853 warning ("only uninitialized variables can be placed in the "
4860 /* Outputs to the stdio stream FILE some
4861 appropriate text to go at the start of an assembler file. */
4864 asm_file_start (file)
4868 error ("MCU `%s' supported for assembler only", avr_mcu_name);
4870 output_file_directive (file, main_input_filename);
4871 fprintf (file, "\t.arch %s\n", avr_mcu_name);
4872 fputs ("__SREG__ = 0x3f\n"
4874 "__SP_L__ = 0x3d\n", file);
4876 fputs ("__tmp_reg__ = 0\n"
4877 "__zero_reg__ = 1\n"
4878 "_PC_ = 2\n", file);
4880 /* FIXME: output these only if there is anything in the .data / .bss
4881 sections - some code size could be saved by not linking in the
4882 initialization code from libgcc if one or both sections are empty. */
4883 fputs ("\t.global __do_copy_data\n", file);
4884 fputs ("\t.global __do_clear_bss\n", file);
4886 commands_in_file = 0;
4887 commands_in_prologues = 0;
4888 commands_in_epilogues = 0;
4891 /* Outputs to the stdio stream FILE some
4892 appropriate text to go at the end of an assembler file. */
4898 fputs ("/* File ", file);
4899 output_quoted_string (file, main_input_filename);
4901 ": code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
4904 commands_in_file - commands_in_prologues - commands_in_epilogues,
4905 commands_in_prologues, commands_in_epilogues);
4908 /* Choose the order in which to allocate hard registers for
4909 pseudo-registers local to a basic block.
4911 Store the desired register order in the array `reg_alloc_order'.
4912 Element 0 should be the register to allocate first; element 1, the
4913 next register; and so on. */
4916 order_regs_for_local_alloc ()
4919 static const int order_0[] = {
4927 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4931 static const int order_1[] = {
4939 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4943 static const int order_2[] = {
4952 15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4957 const int *order = (TARGET_ORDER_1 ? order_1 :
4958 TARGET_ORDER_2 ? order_2 :
4960 for (i=0; i < ARRAY_SIZE (order_0); ++i)
4961 reg_alloc_order[i] = order[i];
4964 /* Calculate the cost of X code of the expression in which it is contained,
4965 found in OUTER_CODE */
4968 default_rtx_costs (X, code, outer_code)
4971 enum rtx_code outer_code;
4978 cost = 2 * GET_MODE_SIZE (GET_MODE (X));
4981 if (outer_code != SET)
4983 if (GET_CODE (XEXP (X,0)) == SYMBOL_REF)
4984 cost += 2 * GET_MODE_SIZE (GET_MODE (X));
4986 cost += GET_MODE_SIZE (GET_MODE (X));
4992 if (outer_code == SET)
4993 cost = GET_MODE_SIZE (GET_MODE (X));
4995 cost = -GET_MODE_SIZE (GET_MODE (X));
4998 if (outer_code == SET)
4999 cost = GET_MODE_SIZE (GET_MODE (X));
5005 if (outer_code == SET)
5007 if (X == stack_pointer_rtx)
5009 else if (GET_CODE (XEXP (X,1)) == CONST_INT)
5010 cost = (INTVAL (XEXP (X,1)) <= 63 ? 1 :
5011 GET_MODE_SIZE (GET_MODE (X)));
5013 cost = GET_MODE_SIZE (GET_MODE (X));
5017 if (GET_CODE (XEXP (X,1)) == CONST_INT)
5018 cost = GET_MODE_SIZE (GET_MODE (XEXP (X,0)));
5026 /* Calculate the cost of a memory address */
5029 avr_address_cost (x)
5032 if (GET_CODE (x) == PLUS
5033 && GET_CODE (XEXP (x,1)) == CONST_INT
5034 && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
5035 && INTVAL (XEXP (x,1)) >= 61)
5037 if (CONSTANT_ADDRESS_P (x))
5039 if (avr_io_address_p (x, 1))
5046 /* EXTRA_CONSTRAINT helper */
5049 extra_constraint (x, c)
5054 && GET_CODE (x) == MEM
5055 && GET_CODE (XEXP (x,0)) == PLUS)
5057 if (TARGET_ALL_DEBUG)
5059 fprintf (stderr, ("extra_constraint:\n"
5060 "reload_completed: %d\n"
5061 "reload_in_progress: %d\n"),
5062 reload_completed, reload_in_progress);
5065 if (GET_CODE (x) == MEM
5066 && GET_CODE (XEXP (x,0)) == PLUS
5067 && REG_P (XEXP (XEXP (x,0), 0))
5068 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
5069 && (INTVAL (XEXP (XEXP (x,0), 1))
5070 <= MAX_LD_OFFSET (GET_MODE (x))))
5072 rtx xx = XEXP (XEXP (x,0), 0);
5073 int regno = REGNO (xx);
5074 if (TARGET_ALL_DEBUG)
5076 fprintf (stderr, ("extra_constraint:\n"
5077 "reload_completed: %d\n"
5078 "reload_in_progress: %d\n"),
5079 reload_completed, reload_in_progress);
5082 if (regno >= FIRST_PSEUDO_REGISTER)
5083 return 1; /* allocate pseudos */
5084 else if (regno == REG_Z || regno == REG_Y)
5085 return 1; /* strictly check */
5086 else if (xx == frame_pointer_rtx
5087 || xx == arg_pointer_rtx)
5088 return 1; /* XXX frame & arg pointer checks */
5094 /* Convert condition code CONDITION to the valid AVR condition code */
5097 avr_normalize_condition (condition)
5115 /* This fnction optimizes conditional jumps */
5118 machine_dependent_reorg (first_insn)
5123 for (insn = first_insn; insn; insn = NEXT_INSN (insn))
5125 if (! (GET_CODE (insn) == INSN
5126 || GET_CODE (insn) == CALL_INSN
5127 || GET_CODE (insn) == JUMP_INSN)
5128 || !single_set (insn))
5131 pattern = PATTERN (insn);
5133 if (GET_CODE (pattern) == PARALLEL)
5134 pattern = XVECEXP (pattern, 0, 0);
5135 if (GET_CODE (pattern) == SET
5136 && SET_DEST (pattern) == cc0_rtx
5137 && compare_diff_p (insn))
5139 if (GET_CODE (SET_SRC (pattern)) == COMPARE)
5141 /* Now we work under compare insn */
5143 pattern = SET_SRC (pattern);
5144 if (true_regnum (XEXP (pattern,0)) >= 0
5145 && true_regnum (XEXP (pattern,1)) >= 0 )
5147 rtx x = XEXP (pattern,0);
5148 rtx next = next_real_insn (insn);
5149 rtx pat = PATTERN (next);
5150 rtx src = SET_SRC (pat);
5151 rtx t = XEXP (src,0);
5152 PUT_CODE (t, swap_condition (GET_CODE (t)));
5153 XEXP (pattern,0) = XEXP (pattern,1);
5154 XEXP (pattern,1) = x;
5155 INSN_CODE (next) = -1;
5157 else if (true_regnum (XEXP (pattern,0)) >= 0
5158 && GET_CODE (XEXP (pattern,1)) == CONST_INT)
5160 rtx x = XEXP (pattern,1);
5161 rtx next = next_real_insn (insn);
5162 rtx pat = PATTERN (next);
5163 rtx src = SET_SRC (pat);
5164 rtx t = XEXP (src,0);
5165 enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
5167 if (avr_simplify_comparision_p (mode, GET_CODE (t), x))
5169 XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
5170 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
5171 INSN_CODE (next) = -1;
5172 INSN_CODE (insn) = -1;
5176 else if (true_regnum (SET_SRC (pattern)) >= 0)
5178 /* This is a tst insn */
5179 rtx next = next_real_insn (insn);
5180 rtx pat = PATTERN (next);
5181 rtx src = SET_SRC (pat);
5182 rtx t = XEXP (src,0);
5184 PUT_CODE (t, swap_condition (GET_CODE (t)));
5185 SET_SRC (pattern) = gen_rtx (NEG,
5186 GET_MODE (SET_SRC (pattern)),
5188 INSN_CODE (next) = -1;
5189 INSN_CODE (insn) = -1;
5195 /* Returns register number for function return value.*/
5203 /* Ceate an RTX representing the place where a
5204 library function returns a value of mode MODE. */
5207 avr_libcall_value (mode)
5208 enum machine_mode mode;
5210 int offs = GET_MODE_SIZE (mode);
5213 return gen_rtx (REG, mode, RET_REGISTER + 2 - offs);
5216 /* Create an RTX representing the place where a
5217 function returns a value of data type VALTYPE. */
5220 avr_function_value (type, func)
5222 tree func ATTRIBUTE_UNUSED;
5226 if (TYPE_MODE (type) != BLKmode)
5227 return avr_libcall_value (TYPE_MODE (type));
5229 offs = int_size_in_bytes (type);
5232 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
5233 offs = GET_MODE_SIZE (SImode);
5234 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
5235 offs = GET_MODE_SIZE (DImode);
5237 return gen_rtx (REG, BLKmode, RET_REGISTER + 2 - offs);
5240 /* Returns non-zero if the number MASK has only one bit set. */
5243 mask_one_bit_p (mask)
5247 unsigned HOST_WIDE_INT n=mask;
5248 for (i = 0; i < 32; ++i)
5250 if (n & 0x80000000L)
5252 if (n & 0x7fffffffL)
5263 /* Places additional restrictions on the register class to
5264 use when it is necessary to copy value X into a register
5268 preferred_reload_class (x, class)
5269 rtx x ATTRIBUTE_UNUSED;
5270 enum reg_class class;
5276 test_hard_reg_class (class, x)
5277 enum reg_class class;
5280 int regno = true_regnum (x);
5283 return TEST_HARD_REG_CLASS (class, regno);
5287 debug_hard_reg_set (set)
5291 for (i=0; i < FIRST_PSEUDO_REGISTER; ++i)
5293 if (TEST_HARD_REG_BIT (set, i))
5295 fprintf (stderr, "r%-2d ", i);
5298 fprintf (stderr, "\n");
5302 jump_over_one_insn_p (insn, dest)
5306 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
5309 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
5310 int dest_addr = INSN_ADDRESSES (uid);
5311 return dest_addr - jump_addr == get_attr_length (insn) + 1;
5314 /* Returns 1 if a value of mode MODE can be stored starting with hard
5315 register number REGNO. On the enhanced core, anything larger than
5316 1 byte must start in even numbered register for "movw" to work
5317 (this way we don't have to check for odd registers everywhere). */
5320 avr_hard_regno_mode_ok (regno, mode)
5322 enum machine_mode mode;
5324 /* Bug workaround: recog.c (peep2_find_free_register) and probably
5325 a few other places assume that the frame pointer is a single hard
5326 register, so r29 may be allocated and overwrite the high byte of
5327 the frame pointer. Do not allow any value to start in r29. */
5328 if (regno == REG_Y + 1)
5333 /* if (regno < 24 && !AVR_ENHANCED)
5335 return !(regno & 1);
5338 /* Returns 1 if we know register operand OP was 0 before INSN. */
5341 reg_was_0 (insn, op)
5346 return (optimize > 0 && insn && op && REG_P (op)
5347 && (link = find_reg_note (insn, REG_WAS_0, 0))
5348 /* Make sure the insn that stored the 0 is still present. */
5349 && ! INSN_DELETED_P (XEXP (link, 0))
5350 && GET_CODE (XEXP (link, 0)) != NOTE
5351 /* Make sure cross jumping didn't happen here. */
5352 && no_labels_between_p (XEXP (link, 0), insn)
5353 /* Make sure the reg hasn't been clobbered. */
5354 && ! reg_set_between_p (op, XEXP (link, 0), insn));
5357 /* Returns 1 if X is a valid address for an I/O register of size SIZE
5358 (1 or 2). Used for lds/sts -> in/out optimization. Add 0x20 to SIZE
5359 to check for the lower half of I/O space (for cbi/sbi/sbic/sbis). */
5362 avr_io_address_p (x, size)
5366 return (optimize > 0 && GET_CODE (x) == CONST_INT
5367 && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size);
5370 /* Returns nonzero (bit number + 1) if X, or -X, is a constant power of 2. */
5373 const_int_pow2_p (x)
5376 if (GET_CODE (x) == CONST_INT)
5378 HOST_WIDE_INT d = INTVAL (x);
5379 HOST_WIDE_INT abs_d = (d >= 0) ? d : -d;
5380 return exact_log2 (abs_d) + 1;
5386 output_reload_inhi (insn, operands, len)
5387 rtx insn ATTRIBUTE_UNUSED;
5395 if (GET_CODE (operands[1]) == CONST_INT)
5397 int val = INTVAL (operands[1]);
5398 if ((val & 0xff) == 0)
5401 return (AS2 (mov,%A0,__zero_reg__) CR_TAB
5402 AS2 (ldi,%2,hi8(%1)) CR_TAB
5405 else if ((val & 0xff00) == 0)
5408 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5409 AS2 (mov,%A0,%2) CR_TAB
5410 AS2 (mov,%B0,__zero_reg__));
5412 else if ((val & 0xff) == ((val & 0xff00) >> 8))
5415 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5416 AS2 (mov,%A0,%2) CR_TAB
5421 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5422 AS2 (mov,%A0,%2) CR_TAB
5423 AS2 (ldi,%2,hi8(%1)) CR_TAB
5429 output_reload_insisf (insn, operands, len)
5430 rtx insn ATTRIBUTE_UNUSED;
5434 rtx src = operands[1];
5435 int cnst = (GET_CODE (src) == CONST_INT);
5440 *len = 4 + ((INTVAL (src) & 0xff) != 0)
5441 + ((INTVAL (src) & 0xff00) != 0)
5442 + ((INTVAL (src) & 0xff0000) != 0)
5443 + ((INTVAL (src) & 0xff000000) != 0);
5450 if (cnst && ((INTVAL (src) & 0xff) == 0))
5451 output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
5454 output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
5455 output_asm_insn (AS2 (mov, %A0, %2), operands);
5457 if (cnst && ((INTVAL (src) & 0xff00) == 0))
5458 output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
5461 output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
5462 output_asm_insn (AS2 (mov, %B0, %2), operands);
5464 if (cnst && ((INTVAL (src) & 0xff0000) == 0))
5465 output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
5468 output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
5469 output_asm_insn (AS2 (mov, %C0, %2), operands);
5471 if (cnst && ((INTVAL (src) & 0xff000000) == 0))
5472 output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
5475 output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
5476 output_asm_insn (AS2 (mov, %D0, %2), operands);
5482 avr_output_bld (operands, bit_nr)
5486 static char s[] = "bld %A0,0";
5488 s[5] = 'A' + (bit_nr >> 3);
5489 s[8] = '0' + (bit_nr & 7);
5490 output_asm_insn (s, operands);
5494 avr_output_addr_vec_elt (stream, value)
5499 fprintf (stream, "\t.word pm(.L%d)\n", value);
5501 fprintf (stream, "\trjmp .L%d\n", value);
5506 /* Returns 1 if SCRATCH are safe to be allocated as a scratch
5507 registers (for a define_peephole2) in the current function. */
5510 avr_peep2_scratch_safe (scratch)
5513 if ((interrupt_function_p (current_function_decl)
5514 || signal_function_p (current_function_decl))
5515 && leaf_function_p ())
5517 int first_reg = true_regnum (scratch);
5518 int last_reg = first_reg + GET_MODE_SIZE (GET_MODE (scratch)) - 1;
5521 for (reg = first_reg; reg <= last_reg; reg++)
5523 if (!regs_ever_live[reg])
5530 /* Output a branch that tests a single bit of a register (QI, HI or SImode)
5531 or memory location in the I/O space (QImode only).
5533 Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
5534 Operand 1: register operand to test, or CONST_INT memory address.
5535 Operand 2: bit number (for QImode operand) or mask (HImode, SImode).
5536 Operand 3: label to jump to if the test is true. */
5539 avr_out_sbxx_branch (insn, operands)
5543 enum rtx_code comp = GET_CODE (operands[0]);
5544 int long_jump = (get_attr_length (insn) >= 4);
5545 int reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
5549 else if (comp == LT)
5553 comp = reverse_condition (comp);
5555 if (GET_CODE (operands[1]) == CONST_INT)
5557 if (INTVAL (operands[1]) < 0x40)
5560 output_asm_insn (AS2 (sbis,%1-0x20,%2), operands);
5562 output_asm_insn (AS2 (sbic,%1-0x20,%2), operands);
5566 output_asm_insn (AS2 (in,__tmp_reg__,%1-0x20), operands);
5568 output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands);
5570 output_asm_insn (AS2 (sbrc,__tmp_reg__,%2), operands);
5573 else /* GET_CODE (operands[1]) == REG */
5575 if (GET_MODE (operands[1]) == QImode)
5578 output_asm_insn (AS2 (sbrs,%1,%2), operands);
5580 output_asm_insn (AS2 (sbrc,%1,%2), operands);
5582 else /* HImode or SImode */
5584 static char buf[] = "sbrc %A1,0";
5585 int bit_nr = exact_log2 (INTVAL (operands[2])
5586 & GET_MODE_MASK (GET_MODE (operands[1])));
5588 buf[3] = (comp == EQ) ? 's' : 'c';
5589 buf[6] = 'A' + (bit_nr >> 3);
5590 buf[9] = '0' + (bit_nr & 7);
5591 output_asm_insn (buf, operands);
5596 return (AS1 (rjmp,_PC_+4) CR_TAB
5599 return AS1 (rjmp,%3);
5604 avr_asm_out_ctor (symbol, priority)
5608 fputs ("\t.global __do_global_ctors\n", asm_out_file);
5609 default_ctor_section_asm_out_constructor (symbol, priority);
5613 avr_asm_out_dtor (symbol, priority)
5617 fputs ("\t.global __do_global_dtors\n", asm_out_file);
5618 default_dtor_section_asm_out_destructor (symbol, priority);