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 extern void avr_encode_section_info PARAMS ((tree, int));
70 /* Allocate registers from r25 to r8 for parameters for function calls */
71 #define FIRST_CUM_REG 26
73 /* Temporary register RTX (gen_rtx (REG,QImode,TMP_REGNO)) */
76 /* Zeroed register RTX (gen_rtx (REG,QImode,ZERO_REGNO)) */
79 /* RTX for register which will be used for loading immediate values to
83 /* AVR register names {"r0", "r1", ..., "r31"} */
84 static const char *const avr_regnames[] = REGISTER_NAMES;
86 /* This holds the last insn address. */
87 static int last_insn_address = 0;
89 /* Commands count in the compiled file */
90 static int commands_in_file;
92 /* Commands in the functions prologues in the compiled file */
93 static int commands_in_prologues;
95 /* Commands in the functions epilogues in the compiled file */
96 static int commands_in_epilogues;
98 /* Prologue/Epilogue size in words */
99 static int prologue_size;
100 static int epilogue_size;
102 /* Size of all jump tables in the current function, in words. */
103 static int jump_tables_size;
105 /* Initial stack value specified by the `-minit-stack=' option */
106 const char *avr_init_stack = "__stack";
108 /* Default MCU name */
109 const char *avr_mcu_name = "avr2";
111 /* More than 8K of program memory: use "call" and "jmp". */
114 /* Enhanced core: use "movw", "mul", ... */
115 int avr_enhanced_p = 0;
126 const char *const name;
127 const enum avr_arch arch;
130 /* List of all known AVR MCU types - if updated, it has to be kept
131 in sync in several places (FIXME: is there a better way?):
133 - avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
134 - t-avr (MULTILIB_MATCHES)
135 - gas/config/tc-avr.c
138 static const struct mcu_type_s avr_mcu_types[] = {
139 /* Classic, <= 8K. */
141 { "at90s2313", AVR2 },
142 { "at90s2323", AVR2 },
143 { "at90s2333", AVR2 },
144 { "at90s2343", AVR2 },
145 { "attiny22", AVR2 },
146 { "attiny26", AVR2 },
147 { "at90s4414", AVR2 },
148 { "at90s4433", AVR2 },
149 { "at90s4434", AVR2 },
150 { "at90s8515", AVR2 },
151 { "at90c8534", AVR2 },
152 { "at90s8535", AVR2 },
155 { "atmega103", AVR3 },
156 { "atmega603", AVR3 },
157 { "at43usb320", AVR3 },
158 { "at43usb355", AVR3 },
159 { "at76c711", AVR3 },
160 /* Enhanced, <= 8K. */
163 { "atmega83", AVR4 },
164 { "atmega85", AVR4 },
165 { "atmega8515", AVR4 },
166 /* Enhanced, > 8K. */
168 { "atmega16", AVR5 },
169 { "atmega161", AVR5 },
170 { "atmega162", AVR5 },
171 { "atmega163", AVR5 },
172 { "atmega32", AVR5 },
173 { "atmega323", AVR5 },
174 { "atmega64", AVR5 },
175 { "atmega128", AVR5 },
177 /* Assembler only. */
179 { "at90s1200", AVR1 },
180 { "attiny10", AVR1 },
181 { "attiny11", AVR1 },
182 { "attiny12", AVR1 },
183 { "attiny15", AVR1 },
184 { "attiny28", AVR1 },
188 int avr_case_values_threshold = 30000;
190 /* Initialize the GCC target structure. */
191 #undef TARGET_ASM_ALIGNED_HI_OP
192 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
193 #undef TARGET_ASM_INTEGER
194 #define TARGET_ASM_INTEGER avr_assemble_integer
196 #undef TARGET_ASM_FUNCTION_PROLOGUE
197 #define TARGET_ASM_FUNCTION_PROLOGUE avr_output_function_prologue
198 #undef TARGET_ASM_FUNCTION_EPILOGUE
199 #define TARGET_ASM_FUNCTION_EPILOGUE avr_output_function_epilogue
200 #undef TARGET_ATTRIBUTE_TABLE
201 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
202 #undef TARGET_ASM_UNIQUE_SECTION
203 #define TARGET_ASM_UNIQUE_SECTION avr_unique_section
204 #undef TARGET_ENCODE_SECTION_INFO
205 #define TARGET_ENCODE_SECTION_INFO avr_encode_section_info
207 struct gcc_target targetm = TARGET_INITIALIZER;
210 avr_override_options ()
212 const struct mcu_type_s *t;
214 for (t = avr_mcu_types; t->name; t++)
215 if (strcmp (t->name, avr_mcu_name) == 0)
220 fprintf (stderr, "unknown MCU `%s' specified\nKnown MCU names:\n",
222 for (t = avr_mcu_types; t->name; t++)
223 fprintf (stderr," %s\n", t->name);
230 error ("MCU `%s' not supported", avr_mcu_name);
231 /* ... fall through ... */
232 case AVR2: avr_enhanced_p = 0; avr_mega_p = 0; break;
233 case AVR3: avr_enhanced_p = 0; avr_mega_p = 1; break;
234 case AVR4: avr_enhanced_p = 1; avr_mega_p = 0; break;
235 case AVR5: avr_enhanced_p = 1; avr_mega_p = 1; break;
238 if (optimize && !TARGET_NO_TABLEJUMP)
239 avr_case_values_threshold = (!AVR_MEGA || TARGET_CALL_PROLOGUES) ? 8 : 17;
243 /* Initialize TMP_REG_RTX and ZERO_REG_RTX */
247 tmp_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
248 memset (tmp_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
249 PUT_CODE (tmp_reg_rtx, REG);
250 PUT_MODE (tmp_reg_rtx, QImode);
251 XINT (tmp_reg_rtx, 0) = TMP_REGNO;
253 zero_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
254 memset (zero_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
255 PUT_CODE (zero_reg_rtx, REG);
256 PUT_MODE (zero_reg_rtx, QImode);
257 XINT (zero_reg_rtx, 0) = ZERO_REGNO;
259 ldi_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
260 memset (ldi_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
261 PUT_CODE (ldi_reg_rtx, REG);
262 PUT_MODE (ldi_reg_rtx, QImode);
263 XINT (ldi_reg_rtx, 0) = LDI_REG_REGNO;
266 /* return register class from register number */
268 static const int reg_class_tab[]={
269 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
270 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
271 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
272 GENERAL_REGS, /* r0 - r15 */
273 LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
274 LD_REGS, /* r16 - 23 */
275 ADDW_REGS,ADDW_REGS, /* r24,r25 */
276 POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
277 POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
278 POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
279 STACK_REG,STACK_REG /* SPL,SPH */
282 /* Return register class for register R */
285 avr_regno_reg_class (r)
289 return reg_class_tab[r];
294 /* A C expression which defines the machine-dependent operand
295 constraint letters for register classes. If C is such a
296 letter, the value should be the register class corresponding to
297 it. Otherwise, the value should be `NO_REGS'. The register
298 letter `r', corresponding to class `GENERAL_REGS', will not be
299 passed to this macro; you do not need to handle it. */
302 avr_reg_class_from_letter (c)
307 case 't' : return R0_REG;
308 case 'b' : return BASE_POINTER_REGS;
309 case 'e' : return POINTER_REGS;
310 case 'w' : return ADDW_REGS;
311 case 'd' : return LD_REGS;
312 case 'l' : return NO_LD_REGS;
313 case 'a' : return SIMPLE_LD_REGS;
314 case 'x' : return POINTER_X_REGS;
315 case 'y' : return POINTER_Y_REGS;
316 case 'z' : return POINTER_Z_REGS;
317 case 'q' : return STACK_REG;
323 /* Return non-zero if FUNC is a naked function. */
326 avr_naked_function_p (func)
331 if (TREE_CODE (func) != FUNCTION_DECL)
334 a = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
335 return a != NULL_TREE;
338 /* Return nonzero if FUNC is an interrupt function as specified
339 by the "interrupt" attribute. */
342 interrupt_function_p (func)
347 if (TREE_CODE (func) != FUNCTION_DECL)
350 a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
351 return a != NULL_TREE;
354 /* Return nonzero if FUNC is a signal function as specified
355 by the "signal" attribute. */
358 signal_function_p (func)
363 if (TREE_CODE (func) != FUNCTION_DECL)
366 a = lookup_attribute ("signal", DECL_ATTRIBUTES (func));
367 return a != NULL_TREE;
370 /* Return the number of hard registers to push/pop in the prologue/epilogue
371 of the current function, and optionally store these registers in SET. */
374 avr_regs_to_save (set)
378 int int_or_sig_p = (interrupt_function_p (current_function_decl)
379 || signal_function_p (current_function_decl));
380 int leaf_func_p = leaf_function_p ();
383 CLEAR_HARD_REG_SET (*set);
385 for (reg = 0; reg < 32; reg++)
387 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
388 any global register variables. */
392 if ((int_or_sig_p && !leaf_func_p && call_used_regs[reg])
393 || (regs_ever_live[reg]
394 && (int_or_sig_p || !call_used_regs[reg])
395 && !(frame_pointer_needed
396 && (reg == REG_Y || reg == (REG_Y+1)))))
399 SET_HARD_REG_BIT (*set, reg);
406 /* Compute offset between arg_pointer and frame_pointer */
409 initial_elimination_offset (from, to)
413 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
417 int offset = frame_pointer_needed ? 2 : 0;
419 offset += avr_regs_to_save (NULL);
420 return get_frame_size () + 2 + 1 + offset;
424 /* This function checks sequence of live registers */
433 for (reg = 0; reg < 18; ++reg)
435 if (!call_used_regs[reg])
437 if (regs_ever_live[reg])
447 if (!frame_pointer_needed)
449 if (regs_ever_live[REG_Y])
457 if (regs_ever_live[REG_Y+1])
470 return (cur_seq == live_seq) ? live_seq : 0;
474 /* Output to FILE the asm instructions to adjust the frame pointer by
475 ADJ (r29:r28 -= ADJ;) which can be positive (prologue) or negative
476 (epilogue). Returns the number of instructions generated. */
479 out_adj_frame_ptr (file, adj)
487 if (TARGET_TINY_STACK)
489 if (adj < -63 || adj > 63)
490 warning ("large frame pointer change (%d) with -mtiny-stack", adj);
492 /* The high byte (r29) doesn't change - prefer "subi" (1 cycle)
493 over "sbiw" (2 cycles, same size). */
495 fprintf (file, (AS2 (subi, r28, %d) CR_TAB), adj);
498 else if (adj < -63 || adj > 63)
500 fprintf (file, (AS2 (subi, r28, lo8(%d)) CR_TAB
501 AS2 (sbci, r29, hi8(%d)) CR_TAB),
507 fprintf (file, (AS2 (adiw, r28, %d) CR_TAB), -adj);
512 fprintf (file, (AS2 (sbiw, r28, %d) CR_TAB), adj);
520 /* Output to FILE the asm instructions to copy r29:r28 to SPH:SPL,
521 handling various cases of interrupt enable flag state BEFORE and AFTER
522 (0=disabled, 1=enabled, -1=unknown/unchanged) and target_flags.
523 Returns the number of instructions generated. */
526 out_set_stack_ptr (file, before, after)
531 int do_sph, do_cli, do_save, do_sei, lock_sph, size;
533 /* The logic here is so that -mno-interrupts actually means
534 "it is safe to write SPH in one instruction, then SPL in the
535 next instruction, without disabling interrupts first".
536 The after != -1 case (interrupt/signal) is not affected. */
538 do_sph = !TARGET_TINY_STACK;
539 lock_sph = do_sph && !TARGET_NO_INTERRUPTS;
540 do_cli = (before != 0 && (after == 0 || lock_sph));
541 do_save = (do_cli && before == -1 && after == -1);
542 do_sei = ((do_cli || before != 1) && after == 1);
547 fprintf (file, AS2 (in, __tmp_reg__, __SREG__) CR_TAB);
553 fprintf (file, "cli" CR_TAB);
557 /* Do SPH first - maybe this will disable interrupts for one instruction
558 someday (a suggestion has been sent to avr@atmel.com for consideration
559 in future devices - that would make -mno-interrupts always safe). */
562 fprintf (file, AS2 (out, __SP_H__, r29) CR_TAB);
566 /* Set/restore the I flag now - interrupts will be really enabled only
567 after the next instruction. This is not clearly documented, but
568 believed to be true for all AVR devices. */
571 fprintf (file, AS2 (out, __SREG__, __tmp_reg__) CR_TAB);
576 fprintf (file, "sei" CR_TAB);
580 fprintf (file, AS2 (out, __SP_L__, r28) "\n");
586 /* Output function prologue */
589 avr_output_function_prologue (file, size)
594 int interrupt_func_p;
600 if (avr_naked_function_p (current_function_decl))
602 fprintf (file, "/* prologue: naked */\n");
606 interrupt_func_p = interrupt_function_p (current_function_decl);
607 signal_func_p = signal_function_p (current_function_decl);
608 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
609 live_seq = sequent_regs_live ();
610 minimize = (TARGET_CALL_PROLOGUES
611 && !interrupt_func_p && !signal_func_p && live_seq);
613 last_insn_address = 0;
614 jump_tables_size = 0;
616 fprintf (file, "/* prologue: frame size=%d */\n", size);
618 if (interrupt_func_p)
620 fprintf (file,"\tsei\n");
623 if (interrupt_func_p || signal_func_p)
626 AS1 (push,__zero_reg__) CR_TAB
627 AS1 (push,__tmp_reg__) CR_TAB
628 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
629 AS1 (push,__tmp_reg__) CR_TAB
630 AS1 (clr,__zero_reg__) "\n");
636 AS2 (ldi,r28,lo8(%s - %d)) CR_TAB
637 AS2 (ldi,r29,hi8(%s - %d)) CR_TAB
638 AS2 (out,__SP_H__,r29) CR_TAB
639 AS2 (out,__SP_L__,r28) "\n"),
640 avr_init_stack, size, avr_init_stack, size);
644 else if (minimize && (frame_pointer_needed || live_seq > 6))
647 AS2 (ldi, r26, lo8(%d)) CR_TAB
648 AS2 (ldi, r27, hi8(%d)) CR_TAB), size, size);
650 fprintf (file, (AS2 (ldi, r30, pm_lo8(.L_%s_body)) CR_TAB
651 AS2 (ldi, r31, pm_hi8(.L_%s_body)) CR_TAB)
652 ,current_function_name, current_function_name);
658 fprintf (file, AS1 (jmp,__prologue_saves__+%d) "\n",
659 (18 - live_seq) * 2);
664 fprintf (file, AS1 (rjmp,__prologue_saves__+%d) "\n",
665 (18 - live_seq) * 2);
668 fprintf (file, ".L_%s_body:\n", current_function_name);
674 prologue_size += avr_regs_to_save (&set);
675 for (reg = 0; reg < 32; ++reg)
677 if (TEST_HARD_REG_BIT (set, reg))
679 fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
682 if (frame_pointer_needed)
686 AS1 (push,r28) CR_TAB
687 AS1 (push,r29) CR_TAB
688 AS2 (in,r28,__SP_L__) CR_TAB
689 AS2 (in,r29,__SP_H__) "\n");
694 prologue_size += out_adj_frame_ptr (file, size);
696 if (interrupt_func_p)
698 prologue_size += out_set_stack_ptr (file, 1, 1);
700 else if (signal_func_p)
702 prologue_size += out_set_stack_ptr (file, 0, 0);
706 prologue_size += out_set_stack_ptr (file, -1, -1);
712 fprintf (file, "/* prologue end (size=%d) */\n", prologue_size);
715 /* Output function epilogue */
718 avr_output_function_epilogue (file, size)
723 int interrupt_func_p;
730 if (avr_naked_function_p (current_function_decl))
732 fprintf (file, "/* epilogue: naked */\n");
736 interrupt_func_p = interrupt_function_p (current_function_decl);
737 signal_func_p = signal_function_p (current_function_decl);
738 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
739 function_size = (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
740 - INSN_ADDRESSES (INSN_UID (get_insns ())));
741 function_size += jump_tables_size;
742 live_seq = sequent_regs_live ();
743 minimize = (TARGET_CALL_PROLOGUES
744 && !interrupt_func_p && !signal_func_p && live_seq);
747 fprintf (file, "/* epilogue: frame size=%d */\n", size);
750 fprintf (file, "__stop_progIi__:\n\trjmp __stop_progIi__\n");
753 else if (minimize && (frame_pointer_needed || live_seq > 4))
755 fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
757 if (frame_pointer_needed)
759 epilogue_size += out_adj_frame_ptr (file, -size);
763 fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
764 AS2 (in , r29, __SP_H__) CR_TAB));
770 fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
771 (18 - live_seq) * 2);
776 fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
777 (18 - live_seq) * 2);
785 if (frame_pointer_needed)
790 epilogue_size += out_adj_frame_ptr (file, -size);
792 if (interrupt_func_p || signal_func_p)
794 epilogue_size += out_set_stack_ptr (file, -1, 0);
798 epilogue_size += out_set_stack_ptr (file, -1, -1);
807 epilogue_size += avr_regs_to_save (&set);
808 for (reg = 31; reg >= 0; --reg)
810 if (TEST_HARD_REG_BIT (set, reg))
812 fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
816 if (interrupt_func_p || signal_func_p)
819 AS1 (pop,__tmp_reg__) CR_TAB
820 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
821 AS1 (pop,__tmp_reg__) CR_TAB
822 AS1 (pop,__zero_reg__) "\n");
824 fprintf (file, "\treti\n");
827 fprintf (file, "\tret\n");
831 fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
832 fprintf (file, "/* function %s size %d (%d) */\n", current_function_name,
833 prologue_size + function_size + epilogue_size, function_size);
834 commands_in_file += prologue_size + function_size + epilogue_size;
835 commands_in_prologues += prologue_size;
836 commands_in_epilogues += epilogue_size;
840 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
841 machine for a memory operand of mode MODE. */
844 legitimate_address_p (mode, x, strict)
845 enum machine_mode mode;
849 enum reg_class r = NO_REGS;
851 if (TARGET_ALL_DEBUG)
853 fprintf (stderr, "mode: (%s) %s %s %s %s:",
855 strict ? "(strict)": "",
856 reload_completed ? "(reload_completed)": "",
857 reload_in_progress ? "(reload_in_progress)": "",
858 reg_renumber ? "(reg_renumber)" : "");
859 if (GET_CODE (x) == PLUS
860 && REG_P (XEXP (x, 0))
861 && GET_CODE (XEXP (x, 1)) == CONST_INT
862 && INTVAL (XEXP (x, 1)) >= 0
863 && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
866 fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
867 true_regnum (XEXP (x, 0)));
870 if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
871 : REG_OK_FOR_BASE_NOSTRICT_P (x)))
873 else if (CONSTANT_ADDRESS_P (x))
875 else if (GET_CODE (x) == PLUS
876 && REG_P (XEXP (x, 0))
877 && GET_CODE (XEXP (x, 1)) == CONST_INT
878 && INTVAL (XEXP (x, 1)) >= 0)
880 int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
884 || REGNO (XEXP (x,0)) == REG_Y
885 || REGNO (XEXP (x,0)) == REG_Z)
886 r = BASE_POINTER_REGS;
887 if (XEXP (x,0) == frame_pointer_rtx
888 || XEXP (x,0) == arg_pointer_rtx)
889 r = BASE_POINTER_REGS;
891 else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
894 else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
895 && REG_P (XEXP (x, 0))
896 && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
897 : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
901 if (TARGET_ALL_DEBUG)
903 fprintf (stderr, " ret = %c\n", r);
905 return r == NO_REGS ? 0 : (int)r;
908 /* Attempts to replace X with a valid
909 memory address for an operand of mode MODE */
912 legitimize_address (x, oldx, mode)
915 enum machine_mode mode;
918 if (TARGET_ALL_DEBUG)
920 fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
924 if (GET_CODE (oldx) == PLUS
925 && REG_P (XEXP (oldx,0)))
927 if (REG_P (XEXP (oldx,1)))
928 x = force_reg (GET_MODE (oldx), oldx);
929 else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
931 int offs = INTVAL (XEXP (oldx,1));
932 if (frame_pointer_rtx != XEXP (oldx,0))
933 if (offs > MAX_LD_OFFSET (mode))
935 if (TARGET_ALL_DEBUG)
936 fprintf (stderr, "force_reg (big offset)\n");
937 x = force_reg (GET_MODE (oldx), oldx);
945 /* Return a pointer register name as a string */
948 ptrreg_to_str (regno)
953 case REG_X: return "X";
954 case REG_Y: return "Y";
955 case REG_Z: return "Z";
962 /* Return the condition name as a string.
963 Used in conditional jump constructing */
976 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
981 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
994 /* Output ADDR to FILE as address */
997 print_operand_address (file, addr)
1001 switch (GET_CODE (addr))
1004 fprintf (file, ptrreg_to_str (REGNO (addr)));
1008 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1012 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1016 if (CONSTANT_ADDRESS_P (addr)
1017 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
1018 || GET_CODE (addr) == LABEL_REF))
1020 fprintf (file, "pm(");
1021 output_addr_const (file,addr);
1022 fprintf (file ,")");
1025 output_addr_const (file, addr);
1030 /* Output X as assembler operand to file FILE */
1033 print_operand (file, x, code)
1040 if (code >= 'A' && code <= 'D')
1050 if (x == zero_reg_rtx)
1051 fprintf (file, "__zero_reg__");
1053 fprintf (file, reg_names[true_regnum (x) + abcd]);
1055 else if (GET_CODE (x) == CONST_INT)
1056 fprintf (file, "%d", INTVAL (x) + abcd);
1057 else if (GET_CODE (x) == MEM)
1059 rtx addr = XEXP (x,0);
1061 if (CONSTANT_P (addr) && abcd)
1064 output_address (addr);
1065 fprintf (file, ")+%d", abcd);
1067 else if (code == 'o')
1069 if (GET_CODE (addr) != PLUS)
1070 fatal_insn ("bad address, not (reg+disp):", addr);
1072 print_operand (file, XEXP (addr, 1), 0);
1074 else if (GET_CODE (addr) == PLUS)
1076 print_operand_address (file, XEXP (addr,0));
1077 if (REGNO (XEXP (addr, 0)) == REG_X)
1078 fatal_insn ("internal compiler error. Bad address:"
1081 print_operand (file, XEXP (addr,1), code);
1084 print_operand_address (file, addr);
1086 else if (GET_CODE (x) == CONST_DOUBLE)
1090 if (GET_MODE (x) != SFmode)
1091 fatal_insn ("internal compiler error. Unknown mode:", x);
1092 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1093 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1094 asm_fprintf (file, "0x%lx", val);
1096 else if (code == 'j')
1097 asm_fprintf (file, cond_string (GET_CODE (x)));
1098 else if (code == 'k')
1099 asm_fprintf (file, cond_string (reverse_condition (GET_CODE (x))));
1101 print_operand_address (file, x);
1104 /* Recognize operand OP of mode MODE used in call instructions */
1107 call_insn_operand (op, mode)
1109 enum machine_mode mode ATTRIBUTE_UNUSED;
1111 if (GET_CODE (op) == MEM)
1113 rtx inside = XEXP (op, 0);
1114 if (register_operand (inside, Pmode))
1116 if (CONSTANT_ADDRESS_P (inside))
1122 /* Update the condition code in the INSN. */
1125 notice_update_cc (body, insn)
1126 rtx body ATTRIBUTE_UNUSED;
1131 switch (get_attr_cc (insn))
1134 /* Insn does not affect CC at all. */
1142 set = single_set (insn);
1146 cc_status.flags |= CC_NO_OVERFLOW;
1147 cc_status.value1 = SET_DEST (set);
1152 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1153 The V flag may or may not be known but that's ok because
1154 alter_cond will change tests to use EQ/NE. */
1155 set = single_set (insn);
1159 cc_status.value1 = SET_DEST (set);
1160 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1165 set = single_set (insn);
1168 cc_status.value1 = SET_SRC (set);
1172 /* Insn doesn't leave CC in a usable state. */
1175 /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1176 set = single_set (insn);
1179 rtx src = SET_SRC (set);
1181 if (GET_CODE (src) == ASHIFTRT
1182 && GET_MODE (src) == QImode)
1184 rtx x = XEXP (src, 1);
1186 if (GET_CODE (x) == CONST_INT
1189 cc_status.value1 = SET_DEST (set);
1190 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1198 /* Return maximum number of consecutive registers of
1199 class CLASS needed to hold a value of mode MODE. */
1202 class_max_nregs (class, mode)
1203 enum reg_class class ATTRIBUTE_UNUSED;
1204 enum machine_mode mode;
1206 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1209 /* Choose mode for jump insn:
1210 1 - relative jump in range -63 <= x <= 62 ;
1211 2 - relative jump in range -2046 <= x <= 2045 ;
1212 3 - absolute jump (only for ATmega[16]03). */
1215 avr_jump_mode (x, insn)
1216 rtx x; /* jump operand */
1217 rtx insn; /* jump insn */
1219 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1220 ? XEXP (x, 0) : x));
1221 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1222 int jump_distance = cur_addr - dest_addr;
1224 if (-63 <= jump_distance && jump_distance <= 62)
1226 else if (-2046 <= jump_distance && jump_distance <= 2045)
1234 /* return an AVR condition jump commands.
1235 X is a comparison RTX.
1236 LEN is a number returned by avr_jump_mode function.
1237 if REVERSE nonzero then condition code in X must be reversed. */
1240 ret_cond_branch (x, len, reverse)
1245 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1250 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1251 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1253 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1254 AS1 (brmi,_PC_+2) CR_TAB
1256 (AS1 (breq,_PC_+6) CR_TAB
1257 AS1 (brmi,_PC_+4) CR_TAB
1261 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1263 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1264 AS1 (brlt,_PC_+2) CR_TAB
1266 (AS1 (breq,_PC_+6) CR_TAB
1267 AS1 (brlt,_PC_+4) CR_TAB
1270 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1272 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1273 AS1 (brlo,_PC_+2) CR_TAB
1275 (AS1 (breq,_PC_+6) CR_TAB
1276 AS1 (brlo,_PC_+4) CR_TAB
1279 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1280 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1282 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1283 AS1 (brpl,_PC_+2) CR_TAB
1285 (AS1 (breq,_PC_+2) CR_TAB
1286 AS1 (brpl,_PC_+4) CR_TAB
1289 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1291 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1292 AS1 (brge,_PC_+2) CR_TAB
1294 (AS1 (breq,_PC_+2) CR_TAB
1295 AS1 (brge,_PC_+4) CR_TAB
1298 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1300 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1301 AS1 (brsh,_PC_+2) CR_TAB
1303 (AS1 (breq,_PC_+2) CR_TAB
1304 AS1 (brsh,_PC_+4) CR_TAB
1312 return AS1 (br%k1,%0);
1314 return (AS1 (br%j1,_PC_+2) CR_TAB
1317 return (AS1 (br%j1,_PC_+4) CR_TAB
1326 return AS1 (br%j1,%0);
1328 return (AS1 (br%k1,_PC_+2) CR_TAB
1331 return (AS1 (br%k1,_PC_+4) CR_TAB
1339 /* Predicate function for immediate operand which fits to byte (8bit) */
1342 byte_immediate_operand (op, mode)
1344 enum machine_mode mode ATTRIBUTE_UNUSED;
1346 return (GET_CODE (op) == CONST_INT
1347 && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1350 /* Output all insn addresses and their sizes into the assembly language
1351 output file. This is helpful for debugging whether the length attributes
1352 in the md file are correct.
1353 Output insn cost for next insn. */
1356 final_prescan_insn (insn, operand, num_operands)
1357 rtx insn, *operand ATTRIBUTE_UNUSED;
1358 int num_operands ATTRIBUTE_UNUSED;
1360 int uid = INSN_UID (insn);
1362 if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1364 fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1365 INSN_ADDRESSES (uid),
1366 INSN_ADDRESSES (uid) - last_insn_address,
1367 rtx_cost (PATTERN (insn), INSN));
1369 last_insn_address = INSN_ADDRESSES (uid);
1371 if (TARGET_RTL_DUMP)
1373 fprintf (asm_out_file, "/*****************\n");
1374 print_rtl_single (asm_out_file, insn);
1375 fprintf (asm_out_file, "*****************/\n");
1379 /* Return 0 if undefined, 1 if always true or always false. */
1382 avr_simplify_comparision_p (mode, operator, x)
1383 enum machine_mode mode;
1387 unsigned int max = (mode == QImode ? 0xff :
1388 mode == HImode ? 0xffff :
1389 mode == SImode ? 0xffffffff : 0);
1390 if (max && operator && GET_CODE (x) == CONST_INT)
1392 if (unsigned_condition (operator) != operator)
1395 if (max != (INTVAL (x) & max)
1396 && INTVAL (x) != 0xff)
1403 /* Returns nonzero if REGNO is the number of a hard
1404 register in which function arguments are sometimes passed. */
1407 function_arg_regno_p(r)
1410 return (r >= 8 && r <= 25);
1413 /* Initializing the variable cum for the state at the beginning
1414 of the argument list. */
1417 init_cumulative_args (cum, fntype, libname, indirect)
1418 CUMULATIVE_ARGS *cum;
1421 int indirect ATTRIBUTE_UNUSED;
1424 cum->regno = FIRST_CUM_REG;
1427 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1428 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1429 != void_type_node));
1435 /* Returns the number of registers to allocate for a function argument. */
1438 avr_num_arg_regs (mode, type)
1439 enum machine_mode mode;
1444 if (mode == BLKmode)
1445 size = int_size_in_bytes (type);
1447 size = GET_MODE_SIZE (mode);
1449 /* Align all function arguments to start in even-numbered registers.
1450 Odd-sized arguments leave holes above them. */
1452 return (size + 1) & ~1;
1455 /* Controls whether a function argument is passed
1456 in a register, and which register. */
1459 function_arg (cum, mode, type, named)
1460 CUMULATIVE_ARGS *cum;
1461 enum machine_mode mode;
1463 int named ATTRIBUTE_UNUSED;
1465 int bytes = avr_num_arg_regs (mode, type);
1467 if (cum->nregs && bytes <= cum->nregs)
1468 return gen_rtx (REG, mode, cum->regno - bytes);
1473 /* Update the summarizer variable CUM to advance past an argument
1474 in the argument list. */
1477 function_arg_advance (cum, mode, type, named)
1478 CUMULATIVE_ARGS *cum; /* current arg information */
1479 enum machine_mode mode; /* current arg mode */
1480 tree type; /* type of the argument or 0 if lib support */
1481 int named ATTRIBUTE_UNUSED; /* whether or not the argument was named */
1483 int bytes = avr_num_arg_regs (mode, type);
1485 cum->nregs -= bytes;
1486 cum->regno -= bytes;
1488 if (cum->nregs <= 0)
1491 cum->regno = FIRST_CUM_REG;
1495 /***********************************************************************
1496 Functions for outputting various mov's for a various modes
1497 ************************************************************************/
1499 output_movqi (insn, operands, l)
1505 rtx dest = operands[0];
1506 rtx src = operands[1];
1514 if (register_operand (dest, QImode))
1516 if (register_operand (src, QImode)) /* mov r,r */
1518 if (test_hard_reg_class (STACK_REG, dest))
1519 return AS2 (out,%0,%1);
1520 else if (test_hard_reg_class (STACK_REG, src))
1521 return AS2 (in,%0,%1);
1523 return AS2 (mov,%0,%1);
1525 else if (CONSTANT_P (src))
1527 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1528 return AS2 (ldi,%0,lo8(%1));
1530 if (GET_CODE (src) == CONST_INT)
1532 if (src == const0_rtx) /* mov r,L */
1533 return AS1 (clr,%0);
1534 else if (src == const1_rtx)
1536 if (reg_was_0 (insn, dest))
1537 return AS1 (inc,%0 ; reg_was_0);
1540 return (AS1 (clr,%0) CR_TAB
1543 else if (src == constm1_rtx)
1545 /* Immediate constants -1 to any register */
1546 if (reg_was_0 (insn, dest))
1547 return AS1 (dec,%0 ; reg_was_0);
1550 return (AS1 (clr,%0) CR_TAB
1555 int bit_nr = exact_log2 (INTVAL (src));
1559 if (reg_was_0 (insn, dest))
1563 output_asm_insn ("set ; reg_was_0", operands);
1569 output_asm_insn ((AS1 (clr,%0) CR_TAB
1573 avr_output_bld (operands, bit_nr);
1580 /* Last resort, larger than loading from memory. */
1582 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1583 AS2 (ldi,r31,lo8(%1)) CR_TAB
1584 AS2 (mov,%0,r31) CR_TAB
1585 AS2 (mov,r31,__tmp_reg__));
1587 else if (GET_CODE (src) == MEM)
1588 return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1590 else if (GET_CODE (dest) == MEM)
1592 const char *template;
1594 if (src == const0_rtx)
1595 operands[1] = zero_reg_rtx;
1597 template = out_movqi_mr_r (insn, operands, real_l);
1600 output_asm_insn (template, operands);
1609 output_movhi (insn, operands, l)
1615 rtx dest = operands[0];
1616 rtx src = operands[1];
1622 if (register_operand (dest, HImode))
1624 if (register_operand (src, HImode)) /* mov r,r */
1626 if (test_hard_reg_class (STACK_REG, dest))
1628 if (TARGET_TINY_STACK)
1631 return AS2 (out,__SP_L__,%A1);
1633 else if (TARGET_NO_INTERRUPTS)
1636 return (AS2 (out,__SP_H__,%B1) CR_TAB
1637 AS2 (out,__SP_L__,%A1));
1641 return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB
1643 AS2 (out,__SP_H__,%B1) CR_TAB
1644 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1645 AS2 (out,__SP_L__,%A1));
1647 else if (test_hard_reg_class (STACK_REG, src))
1650 return (AS2 (in,%A0,__SP_L__) CR_TAB
1651 AS2 (in,%B0,__SP_H__));
1657 return (AS2 (movw,%0,%1));
1660 if (true_regnum (dest) > true_regnum (src))
1663 return (AS2 (mov,%B0,%B1) CR_TAB
1669 return (AS2 (mov,%A0,%A1) CR_TAB
1673 else if (CONSTANT_P (src))
1675 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1677 if (byte_immediate_operand (src, HImode)
1678 && reg_was_0 (insn, dest))
1681 return (AS2 (ldi,%A0,lo8(%1) ; reg_was_0));
1685 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1686 AS2 (ldi,%B0,hi8(%1)));
1689 if (GET_CODE (src) == CONST_INT)
1691 if (src == const0_rtx) /* mov r,L */
1694 return (AS1 (clr,%A0) CR_TAB
1697 else if (src == const1_rtx)
1699 if (reg_was_0 (insn, dest))
1702 return AS1 (inc,%0 ; reg_was_0);
1706 return (AS1 (clr,%A0) CR_TAB
1707 AS1 (clr,%B0) CR_TAB
1710 else if (src == constm1_rtx)
1712 /* Immediate constants -1 to any register */
1713 if (reg_was_0 (insn, dest))
1716 return (AS1 (dec,%A0 ; reg_was_0) CR_TAB
1721 return (AS1 (clr,%0) CR_TAB
1722 AS1 (dec,%A0) CR_TAB
1727 int bit_nr = exact_log2 (INTVAL (src));
1731 if (reg_was_0 (insn, dest))
1735 output_asm_insn ("set ; reg_was_0", operands);
1741 output_asm_insn ((AS1 (clr,%A0) CR_TAB
1742 AS1 (clr,%B0) CR_TAB
1746 avr_output_bld (operands, bit_nr);
1752 if ((INTVAL (src) & 0xff) == 0)
1755 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1756 AS1 (clr,%A0) CR_TAB
1757 AS2 (ldi,r31,hi8(%1)) CR_TAB
1758 AS2 (mov,%B0,r31) CR_TAB
1759 AS2 (mov,r31,__tmp_reg__));
1761 else if ((INTVAL (src) & 0xff00) == 0)
1764 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1765 AS2 (ldi,r31,lo8(%1)) CR_TAB
1766 AS2 (mov,%A0,r31) CR_TAB
1767 AS1 (clr,%B0) CR_TAB
1768 AS2 (mov,r31,__tmp_reg__));
1772 /* Last resort, equal to loading from memory. */
1774 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1775 AS2 (ldi,r31,lo8(%1)) CR_TAB
1776 AS2 (mov,%A0,r31) CR_TAB
1777 AS2 (ldi,r31,hi8(%1)) CR_TAB
1778 AS2 (mov,%B0,r31) CR_TAB
1779 AS2 (mov,r31,__tmp_reg__));
1781 else if (GET_CODE (src) == MEM)
1782 return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1784 else if (GET_CODE (dest) == MEM)
1786 const char *template;
1788 if (src == const0_rtx)
1789 operands[1] = zero_reg_rtx;
1791 template = out_movhi_mr_r (insn, operands, real_l);
1794 output_asm_insn (template, operands);
1799 fatal_insn ("invalid insn:", insn);
1804 out_movqi_r_mr (insn, op, l)
1807 int *l; /* instruction length */
1811 rtx x = XEXP (src, 0);
1817 if (CONSTANT_ADDRESS_P (x))
1819 if (avr_io_address_p (x, 1))
1822 return AS2 (in,%0,%1-0x20);
1825 return AS2 (lds,%0,%1);
1827 /* memory access by reg+disp */
1828 else if (GET_CODE (x) == PLUS
1829 && REG_P (XEXP (x,0))
1830 && GET_CODE (XEXP (x,1)) == CONST_INT)
1832 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1834 int disp = INTVAL (XEXP (x,1));
1835 if (REGNO (XEXP (x,0)) != REG_Y)
1836 fatal_insn ("incorrect insn:",insn);
1838 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1839 return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
1840 AS2 (ldd,%0,Y+63) CR_TAB
1841 AS2 (sbiw,r28,%o1-63));
1843 return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1844 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1845 AS2 (ld,%0,Y) CR_TAB
1846 AS2 (subi,r28,lo8(%o1)) CR_TAB
1847 AS2 (sbci,r29,hi8(%o1)));
1849 else if (REGNO (XEXP (x,0)) == REG_X)
1851 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1852 it but I have this situation with extremal optimizing options. */
1853 if (reg_overlap_mentioned_p (dest, XEXP (x,0))
1854 || reg_unused_after (insn, XEXP (x,0)))
1855 return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
1858 return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
1859 AS2 (ld,%0,X) CR_TAB
1860 AS2 (sbiw,r26,%o1));
1863 return AS2 (ldd,%0,%1);
1866 return AS2 (ld,%0,%1);
1870 out_movhi_r_mr (insn, op, l)
1873 int *l; /* instruction length */
1877 rtx base = XEXP (src, 0);
1878 int reg_dest = true_regnum (dest);
1879 int reg_base = true_regnum (base);
1887 if (reg_dest == reg_base) /* R = (R) */
1890 return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1891 AS2 (ld,%B0,%1) CR_TAB
1892 AS2 (mov,%A0,__tmp_reg__));
1894 else if (reg_base == REG_X) /* (R26) */
1896 if (reg_unused_after (insn, base))
1899 return (AS2 (ld,%A0,X+) CR_TAB
1903 return (AS2 (ld,%A0,X+) CR_TAB
1904 AS2 (ld,%B0,X) CR_TAB
1910 return (AS2 (ld,%A0,%1) CR_TAB
1911 AS2 (ldd,%B0,%1+1));
1914 else if (GET_CODE (base) == PLUS) /* (R + i) */
1916 int disp = INTVAL (XEXP (base, 1));
1917 int reg_base = true_regnum (XEXP (base, 0));
1919 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
1921 if (REGNO (XEXP (base, 0)) != REG_Y)
1922 fatal_insn ("incorrect insn:",insn);
1924 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1925 return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
1926 AS2 (ldd,%A0,Y+62) CR_TAB
1927 AS2 (ldd,%B0,Y+63) CR_TAB
1928 AS2 (sbiw,r28,%o1-62));
1930 return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1931 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1932 AS2 (ld,%A0,Y) CR_TAB
1933 AS2 (ldd,%B0,Y+1) CR_TAB
1934 AS2 (subi,r28,lo8(%o1)) CR_TAB
1935 AS2 (sbci,r29,hi8(%o1)));
1937 if (reg_base == REG_X)
1939 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1940 it but I have this situation with extremal
1941 optimization options. */
1944 if (reg_base == reg_dest)
1945 return (AS2 (adiw,r26,%o1) CR_TAB
1946 AS2 (ld,__tmp_reg__,X+) CR_TAB
1947 AS2 (ld,%B0,X) CR_TAB
1948 AS2 (mov,%A0,__tmp_reg__));
1950 return (AS2 (adiw,r26,%o1) CR_TAB
1951 AS2 (ld,%A0,X+) CR_TAB
1952 AS2 (ld,%B0,X) CR_TAB
1953 AS2 (sbiw,r26,%o1+1));
1956 if (reg_base == reg_dest)
1959 return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
1960 AS2 (ldd,%B0,%B1) CR_TAB
1961 AS2 (mov,%A0,__tmp_reg__));
1965 return (AS2 (ldd,%A0,%A1) CR_TAB
1968 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
1970 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1971 fatal_insn ("incorrect insn:", insn);
1974 return (AS2 (ld,%B0,%1) CR_TAB
1977 else if (GET_CODE (base) == POST_INC) /* (R++) */
1979 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1980 fatal_insn ("incorrect insn:", insn);
1983 return (AS2 (ld,%A0,%1) CR_TAB
1986 else if (CONSTANT_ADDRESS_P (base))
1988 if (avr_io_address_p (base, 2))
1991 return (AS2 (in,%A0,%A1-0x20) CR_TAB
1992 AS2 (in,%B0,%B1-0x20));
1995 return (AS2 (lds,%A0,%A1) CR_TAB
1999 fatal_insn ("unknown move insn:",insn);
2004 out_movsi_r_mr (insn, op, l)
2007 int *l; /* instruction length */
2011 rtx base = XEXP (src, 0);
2012 int reg_dest = true_regnum (dest);
2013 int reg_base = true_regnum (base);
2021 if (reg_base == REG_X) /* (R26) */
2023 if (reg_dest == REG_X)
2024 /* "ld r26,-X" is undefined */
2025 return *l=7, (AS2 (adiw,r26,3) CR_TAB
2026 AS2 (ld,r29,X) CR_TAB
2027 AS2 (ld,r28,-X) CR_TAB
2028 AS2 (ld,__tmp_reg__,-X) CR_TAB
2029 AS2 (sbiw,r26,1) CR_TAB
2030 AS2 (ld,r26,X) CR_TAB
2031 AS2 (mov,r27,__tmp_reg__));
2032 else if (reg_dest == REG_X - 2)
2033 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2034 AS2 (ld,%B0,X+) CR_TAB
2035 AS2 (ld,__tmp_reg__,X+) CR_TAB
2036 AS2 (ld,%D0,X) CR_TAB
2037 AS2 (mov,%C0,__tmp_reg__));
2038 else if (reg_unused_after (insn, base))
2039 return *l=4, (AS2 (ld,%A0,X+) CR_TAB
2040 AS2 (ld,%B0,X+) CR_TAB
2041 AS2 (ld,%C0,X+) CR_TAB
2044 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2045 AS2 (ld,%B0,X+) CR_TAB
2046 AS2 (ld,%C0,X+) CR_TAB
2047 AS2 (ld,%D0,X) CR_TAB
2052 if (reg_dest == reg_base)
2053 return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
2054 AS2 (ldd,%C0,%1+2) CR_TAB
2055 AS2 (ldd,__tmp_reg__,%1+1) CR_TAB
2056 AS2 (ld,%A0,%1) CR_TAB
2057 AS2 (mov,%B0,__tmp_reg__));
2058 else if (reg_base == reg_dest + 2)
2059 return *l=5, (AS2 (ld ,%A0,%1) CR_TAB
2060 AS2 (ldd,%B0,%1+1) CR_TAB
2061 AS2 (ldd,__tmp_reg__,%1+2) CR_TAB
2062 AS2 (ldd,%D0,%1+3) CR_TAB
2063 AS2 (mov,%C0,__tmp_reg__));
2065 return *l=4, (AS2 (ld ,%A0,%1) CR_TAB
2066 AS2 (ldd,%B0,%1+1) CR_TAB
2067 AS2 (ldd,%C0,%1+2) CR_TAB
2068 AS2 (ldd,%D0,%1+3));
2071 else if (GET_CODE (base) == PLUS) /* (R + i) */
2073 int disp = INTVAL (XEXP (base, 1));
2075 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2077 if (REGNO (XEXP (base, 0)) != REG_Y)
2078 fatal_insn ("incorrect insn:",insn);
2080 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2081 return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2082 AS2 (ldd,%A0,Y+60) CR_TAB
2083 AS2 (ldd,%B0,Y+61) CR_TAB
2084 AS2 (ldd,%C0,Y+62) CR_TAB
2085 AS2 (ldd,%D0,Y+63) CR_TAB
2086 AS2 (sbiw,r28,%o1-60));
2088 return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2089 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2090 AS2 (ld,%A0,Y) CR_TAB
2091 AS2 (ldd,%B0,Y+1) CR_TAB
2092 AS2 (ldd,%C0,Y+2) CR_TAB
2093 AS2 (ldd,%D0,Y+3) CR_TAB
2094 AS2 (subi,r28,lo8(%o1)) CR_TAB
2095 AS2 (sbci,r29,hi8(%o1)));
2098 reg_base = true_regnum (XEXP (base, 0));
2099 if (reg_base == REG_X)
2102 if (reg_dest == REG_X)
2105 /* "ld r26,-X" is undefined */
2106 return (AS2 (adiw,r26,%o1+3) CR_TAB
2107 AS2 (ld,r29,X) CR_TAB
2108 AS2 (ld,r28,-X) CR_TAB
2109 AS2 (ld,__tmp_reg__,-X) CR_TAB
2110 AS2 (sbiw,r26,1) CR_TAB
2111 AS2 (ld,r26,X) CR_TAB
2112 AS2 (mov,r27,__tmp_reg__));
2115 if (reg_dest == REG_X - 2)
2116 return (AS2 (adiw,r26,%o1) CR_TAB
2117 AS2 (ld,r24,X+) CR_TAB
2118 AS2 (ld,r25,X+) CR_TAB
2119 AS2 (ld,__tmp_reg__,X+) CR_TAB
2120 AS2 (ld,r27,X) CR_TAB
2121 AS2 (mov,r26,__tmp_reg__));
2123 return (AS2 (adiw,r26,%o1) CR_TAB
2124 AS2 (ld,%A0,X+) CR_TAB
2125 AS2 (ld,%B0,X+) CR_TAB
2126 AS2 (ld,%C0,X+) CR_TAB
2127 AS2 (ld,%D0,X) CR_TAB
2128 AS2 (sbiw,r26,%o1+3));
2130 if (reg_dest == reg_base)
2131 return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2132 AS2 (ldd,%C0,%C1) CR_TAB
2133 AS2 (ldd,__tmp_reg__,%B1) CR_TAB
2134 AS2 (ldd,%A0,%A1) CR_TAB
2135 AS2 (mov,%B0,__tmp_reg__));
2136 else if (reg_dest == reg_base - 2)
2137 return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2138 AS2 (ldd,%B0,%B1) CR_TAB
2139 AS2 (ldd,__tmp_reg__,%C1) CR_TAB
2140 AS2 (ldd,%D0,%D1) CR_TAB
2141 AS2 (mov,%C0,__tmp_reg__));
2142 return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2143 AS2 (ldd,%B0,%B1) CR_TAB
2144 AS2 (ldd,%C0,%C1) CR_TAB
2147 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2148 return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2149 AS2 (ld,%C0,%1) CR_TAB
2150 AS2 (ld,%B0,%1) CR_TAB
2152 else if (GET_CODE (base) == POST_INC) /* (R++) */
2153 return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2154 AS2 (ld,%B0,%1) CR_TAB
2155 AS2 (ld,%C0,%1) CR_TAB
2157 else if (CONSTANT_ADDRESS_P (base))
2158 return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2159 AS2 (lds,%B0,%B1) CR_TAB
2160 AS2 (lds,%C0,%C1) CR_TAB
2163 fatal_insn ("unknown move insn:",insn);
2168 out_movsi_mr_r (insn, op, l)
2175 rtx base = XEXP (dest, 0);
2176 int reg_base = true_regnum (base);
2177 int reg_src = true_regnum (src);
2183 if (CONSTANT_ADDRESS_P (base))
2184 return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2185 AS2 (sts,%B0,%B1) CR_TAB
2186 AS2 (sts,%C0,%C1) CR_TAB
2188 if (reg_base > 0) /* (r) */
2190 if (reg_base == REG_X) /* (R26) */
2192 if (reg_src == REG_X)
2194 /* "st X+,r26" is undefined */
2195 if (reg_unused_after (insn, base))
2196 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2197 AS2 (st,X,r26) CR_TAB
2198 AS2 (adiw,r26,1) CR_TAB
2199 AS2 (st,X+,__tmp_reg__) CR_TAB
2200 AS2 (st,X+,r28) CR_TAB
2203 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2204 AS2 (st,X,r26) CR_TAB
2205 AS2 (adiw,r26,1) CR_TAB
2206 AS2 (st,X+,__tmp_reg__) CR_TAB
2207 AS2 (st,X+,r28) CR_TAB
2208 AS2 (st,X,r29) CR_TAB
2211 else if (reg_base == reg_src + 2)
2213 if (reg_unused_after (insn, base))
2214 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2215 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2216 AS2 (st,%0+,%A1) CR_TAB
2217 AS2 (st,%0+,%B1) CR_TAB
2218 AS2 (st,%0+,__zero_reg__) CR_TAB
2219 AS2 (st,%0,__tmp_reg__) CR_TAB
2220 AS1 (clr,__zero_reg__));
2222 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2223 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2224 AS2 (st,%0+,%A1) CR_TAB
2225 AS2 (st,%0+,%B1) CR_TAB
2226 AS2 (st,%0+,__zero_reg__) CR_TAB
2227 AS2 (st,%0,__tmp_reg__) CR_TAB
2228 AS1 (clr,__zero_reg__) CR_TAB
2231 return *l=5, (AS2 (st,%0+,%A1) CR_TAB
2232 AS2 (st,%0+,%B1) CR_TAB
2233 AS2 (st,%0+,%C1) CR_TAB
2234 AS2 (st,%0,%D1) CR_TAB
2238 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2239 AS2 (std,%0+1,%B1) CR_TAB
2240 AS2 (std,%0+2,%C1) CR_TAB
2241 AS2 (std,%0+3,%D1));
2243 else if (GET_CODE (base) == PLUS) /* (R + i) */
2245 int disp = INTVAL (XEXP (base, 1));
2246 reg_base = REGNO (XEXP (base, 0));
2247 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2249 if (reg_base != REG_Y)
2250 fatal_insn ("incorrect insn:",insn);
2252 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2253 return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2254 AS2 (std,Y+60,%A1) CR_TAB
2255 AS2 (std,Y+61,%B1) CR_TAB
2256 AS2 (std,Y+62,%C1) CR_TAB
2257 AS2 (std,Y+63,%D1) CR_TAB
2258 AS2 (sbiw,r28,%o0-60));
2260 return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2261 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2262 AS2 (st,Y,%A1) CR_TAB
2263 AS2 (std,Y+1,%B1) CR_TAB
2264 AS2 (std,Y+2,%C1) CR_TAB
2265 AS2 (std,Y+3,%D1) CR_TAB
2266 AS2 (subi,r28,lo8(%o0)) CR_TAB
2267 AS2 (sbci,r29,hi8(%o0)));
2269 if (reg_base == REG_X)
2272 if (reg_src == REG_X)
2275 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2276 AS2 (mov,__zero_reg__,r27) CR_TAB
2277 AS2 (adiw,r26,%o0) CR_TAB
2278 AS2 (st,X+,__tmp_reg__) CR_TAB
2279 AS2 (st,X+,__zero_reg__) CR_TAB
2280 AS2 (st,X+,r28) CR_TAB
2281 AS2 (st,X,r29) CR_TAB
2282 AS1 (clr,__zero_reg__) CR_TAB
2283 AS2 (sbiw,r26,%o0+3));
2285 else if (reg_src == REG_X - 2)
2288 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2289 AS2 (mov,__zero_reg__,r27) CR_TAB
2290 AS2 (adiw,r26,%o0) CR_TAB
2291 AS2 (st,X+,r24) CR_TAB
2292 AS2 (st,X+,r25) CR_TAB
2293 AS2 (st,X+,__tmp_reg__) CR_TAB
2294 AS2 (st,X,__zero_reg__) CR_TAB
2295 AS1 (clr,__zero_reg__) CR_TAB
2296 AS2 (sbiw,r26,%o0+3));
2299 return (AS2 (adiw,r26,%o0) CR_TAB
2300 AS2 (st,X+,%A1) CR_TAB
2301 AS2 (st,X+,%B1) CR_TAB
2302 AS2 (st,X+,%C1) CR_TAB
2303 AS2 (st,X,%D1) CR_TAB
2304 AS2 (sbiw,r26,%o0+3));
2306 return *l=4, (AS2 (std,%A0,%A1) CR_TAB
2307 AS2 (std,%B0,%B1) CR_TAB
2308 AS2 (std,%C0,%C1) CR_TAB
2311 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2312 return *l=4, (AS2 (st,%0,%D1) CR_TAB
2313 AS2 (st,%0,%C1) CR_TAB
2314 AS2 (st,%0,%B1) CR_TAB
2316 else if (GET_CODE (base) == POST_INC) /* (R++) */
2317 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2318 AS2 (st,%0,%B1) CR_TAB
2319 AS2 (st,%0,%C1) CR_TAB
2321 fatal_insn ("unknown move insn:",insn);
2326 output_movsisf(insn, operands, l)
2332 rtx dest = operands[0];
2333 rtx src = operands[1];
2339 if (register_operand (dest, VOIDmode))
2341 if (register_operand (src, VOIDmode)) /* mov r,r */
2343 if (true_regnum (dest) > true_regnum (src))
2348 return (AS2 (movw,%C0,%C1) CR_TAB
2349 AS2 (movw,%A0,%A1));
2352 return (AS2 (mov,%D0,%D1) CR_TAB
2353 AS2 (mov,%C0,%C1) CR_TAB
2354 AS2 (mov,%B0,%B1) CR_TAB
2362 return (AS2 (movw,%A0,%A1) CR_TAB
2363 AS2 (movw,%C0,%C1));
2366 return (AS2 (mov,%A0,%A1) CR_TAB
2367 AS2 (mov,%B0,%B1) CR_TAB
2368 AS2 (mov,%C0,%C1) CR_TAB
2372 else if (CONSTANT_P (src))
2374 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2376 if (byte_immediate_operand (src, SImode)
2377 && reg_was_0 (insn, dest))
2380 return (AS2 (ldi,%A0,lo8(%1) ; reg_was_0));
2384 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
2385 AS2 (ldi,%B0,hi8(%1)) CR_TAB
2386 AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2387 AS2 (ldi,%D0,hhi8(%1)));
2390 if (GET_CODE (src) == CONST_INT)
2392 const char *const clr_op0 =
2393 AVR_ENHANCED ? (AS1 (clr,%A0) CR_TAB
2394 AS1 (clr,%B0) CR_TAB
2396 : (AS1 (clr,%A0) CR_TAB
2397 AS1 (clr,%B0) CR_TAB
2398 AS1 (clr,%C0) CR_TAB
2401 if (src == const0_rtx) /* mov r,L */
2403 *l = AVR_ENHANCED ? 3 : 4;
2406 else if (src == const1_rtx)
2408 if (reg_was_0 (insn, dest))
2411 return AS1 (inc,%A0 ; reg_was_0);
2414 output_asm_insn (clr_op0, operands);
2415 *l = AVR_ENHANCED ? 4 : 5;
2416 return AS1 (inc,%A0);
2418 else if (src == constm1_rtx)
2420 /* Immediate constants -1 to any register */
2421 if (reg_was_0 (insn, dest))
2426 return (AS1 (dec,%A0) CR_TAB
2427 AS1 (dec,%B0) CR_TAB
2428 AS2 (movw,%C0,%A0));
2431 return (AS1 (dec,%D0 ; reg_was_0) CR_TAB
2432 AS1 (dec,%C0) CR_TAB
2433 AS1 (dec,%B0) CR_TAB
2439 return (AS1 (clr,%A0) CR_TAB
2440 AS1 (dec,%A0) CR_TAB
2441 AS2 (mov,%B0,%A0) CR_TAB
2442 AS2 (movw,%C0,%A0));
2445 return (AS1 (clr,%A0) CR_TAB
2446 AS1 (dec,%A0) CR_TAB
2447 AS2 (mov,%B0,%A0) CR_TAB
2448 AS2 (mov,%C0,%A0) CR_TAB
2453 int bit_nr = exact_log2 (INTVAL (src));
2457 if (reg_was_0 (insn, dest))
2461 output_asm_insn ("set ; reg_was_0", operands);
2465 *l = AVR_ENHANCED ? 5 : 6;
2468 output_asm_insn (clr_op0, operands);
2469 output_asm_insn ("set", operands);
2473 avr_output_bld (operands, bit_nr);
2480 /* Last resort, better than loading from memory. */
2482 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2483 AS2 (ldi,r31,lo8(%1)) CR_TAB
2484 AS2 (mov,%A0,r31) CR_TAB
2485 AS2 (ldi,r31,hi8(%1)) CR_TAB
2486 AS2 (mov,%B0,r31) CR_TAB
2487 AS2 (ldi,r31,hlo8(%1)) CR_TAB
2488 AS2 (mov,%C0,r31) CR_TAB
2489 AS2 (ldi,r31,hhi8(%1)) CR_TAB
2490 AS2 (mov,%D0,r31) CR_TAB
2491 AS2 (mov,r31,__tmp_reg__));
2493 else if (GET_CODE (src) == MEM)
2494 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2496 else if (GET_CODE (dest) == MEM)
2498 const char *template;
2500 if (src == const0_rtx)
2501 operands[1] = zero_reg_rtx;
2503 template = out_movsi_mr_r (insn, operands, real_l);
2506 output_asm_insn (template, operands);
2511 fatal_insn ("invalid insn:", insn);
2516 out_movqi_mr_r (insn, op, l)
2519 int *l; /* instruction length */
2523 rtx x = XEXP (dest, 0);
2529 if (CONSTANT_ADDRESS_P (x))
2531 if (avr_io_address_p (x, 1))
2534 return AS2 (out,%0-0x20,%1);
2537 return AS2 (sts,%0,%1);
2539 /* memory access by reg+disp */
2540 else if (GET_CODE (x) == PLUS
2541 && REG_P (XEXP (x,0))
2542 && GET_CODE (XEXP (x,1)) == CONST_INT)
2544 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2546 int disp = INTVAL (XEXP (x,1));
2547 if (REGNO (XEXP (x,0)) != REG_Y)
2548 fatal_insn ("incorrect insn:",insn);
2550 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2551 return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2552 AS2 (std,Y+63,%1) CR_TAB
2553 AS2 (sbiw,r28,%o0-63));
2555 return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2556 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2557 AS2 (st,Y,%1) CR_TAB
2558 AS2 (subi,r28,lo8(%o0)) CR_TAB
2559 AS2 (sbci,r29,hi8(%o0)));
2561 else if (REGNO (XEXP (x,0)) == REG_X)
2563 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2565 if (reg_unused_after (insn, XEXP (x,0)))
2566 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2567 AS2 (adiw,r26,%o0) CR_TAB
2568 AS2 (st,X,__tmp_reg__));
2570 return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2571 AS2 (adiw,r26,%o0) CR_TAB
2572 AS2 (st,X,__tmp_reg__) CR_TAB
2573 AS2 (sbiw,r26,%o0));
2577 if (reg_unused_after (insn, XEXP (x,0)))
2578 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2581 return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2582 AS2 (st,X,%1) CR_TAB
2583 AS2 (sbiw,r26,%o0));
2587 return AS2 (std,%0,%1);
2590 return AS2 (st,%0,%1);
2594 out_movhi_mr_r (insn, op, l)
2601 rtx base = XEXP (dest, 0);
2602 int reg_base = true_regnum (base);
2603 int reg_src = true_regnum (src);
2607 if (CONSTANT_ADDRESS_P (base))
2609 if (avr_io_address_p (base, 2))
2612 return (AS2 (out,%B0-0x20,%B1) CR_TAB
2613 AS2 (out,%A0-0x20,%A1));
2615 return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2620 if (reg_base == REG_X)
2622 if (reg_src == REG_X)
2624 /* "st X+,r26" is undefined */
2625 if (reg_unused_after (insn, src))
2626 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2627 AS2 (st,X,r26) CR_TAB
2628 AS2 (adiw,r26,1) CR_TAB
2629 AS2 (st,X,__tmp_reg__));
2631 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2632 AS2 (st,X,r26) CR_TAB
2633 AS2 (adiw,r26,1) CR_TAB
2634 AS2 (st,X,__tmp_reg__) CR_TAB
2639 if (reg_unused_after (insn, base))
2640 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2643 return *l=3, (AS2 (st ,X+,%A1) CR_TAB
2644 AS2 (st ,X,%B1) CR_TAB
2649 return *l=2, (AS2 (st ,%0,%A1) CR_TAB
2650 AS2 (std,%0+1,%B1));
2652 else if (GET_CODE (base) == PLUS)
2654 int disp = INTVAL (XEXP (base, 1));
2655 reg_base = REGNO (XEXP (base, 0));
2656 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2658 if (reg_base != REG_Y)
2659 fatal_insn ("incorrect insn:",insn);
2661 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2662 return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2663 AS2 (std,Y+62,%A1) CR_TAB
2664 AS2 (std,Y+63,%B1) CR_TAB
2665 AS2 (sbiw,r28,%o0-62));
2667 return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2668 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2669 AS2 (st,Y,%A1) CR_TAB
2670 AS2 (std,Y+1,%B1) CR_TAB
2671 AS2 (subi,r28,lo8(%o0)) CR_TAB
2672 AS2 (sbci,r29,hi8(%o0)));
2674 if (reg_base == REG_X)
2677 if (reg_src == REG_X)
2680 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2681 AS2 (mov,__zero_reg__,r27) CR_TAB
2682 AS2 (adiw,r26,%o0) CR_TAB
2683 AS2 (st,X+,__tmp_reg__) CR_TAB
2684 AS2 (st,X,__zero_reg__) CR_TAB
2685 AS1 (clr,__zero_reg__) CR_TAB
2686 AS2 (sbiw,r26,%o0+1));
2689 return (AS2 (adiw,r26,%o0) CR_TAB
2690 AS2 (st,X+,%A1) CR_TAB
2691 AS2 (st,X,%B1) CR_TAB
2692 AS2 (sbiw,r26,%o0+1));
2694 return *l=2, (AS2 (std,%A0,%A1) CR_TAB
2697 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2698 return *l=2, (AS2 (st,%0,%B1) CR_TAB
2700 else if (GET_CODE (base) == POST_INC) /* (R++) */
2701 return *l=2, (AS2 (st,%0,%A1) CR_TAB
2703 fatal_insn ("unknown move insn:",insn);
2707 /* Return 1 if frame pointer for current function required */
2710 frame_pointer_required_p ()
2712 return (current_function_calls_alloca
2713 || current_function_args_info.nregs == 0
2714 || current_function_varargs
2715 || get_frame_size () > 0);
2718 /* Returns the condition of compare insn INSN, or UNKNOWN. */
2721 compare_condition (insn)
2724 rtx next = next_real_insn (insn);
2725 RTX_CODE cond = UNKNOWN;
2726 if (next && GET_CODE (next) == JUMP_INSN)
2728 rtx pat = PATTERN (next);
2729 rtx src = SET_SRC (pat);
2730 rtx t = XEXP (src, 0);
2731 cond = GET_CODE (t);
2736 /* Returns nonzero if INSN is a tst insn that only tests the sign. */
2739 compare_sign_p (insn)
2742 RTX_CODE cond = compare_condition (insn);
2743 return (cond == GE || cond == LT);
2746 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
2747 that needs to be swapped (GT, GTU, LE, LEU). */
2750 compare_diff_p (insn)
2753 RTX_CODE cond = compare_condition (insn);
2754 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2757 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition. */
2763 RTX_CODE cond = compare_condition (insn);
2764 return (cond == EQ || cond == NE);
2768 /* Output test instruction for HImode */
2775 if (compare_sign_p (insn))
2778 return AS1 (tst,%B0);
2780 if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
2781 && compare_eq_p (insn))
2783 /* faster than sbiw if we can clobber the operand */
2785 return AS2 (or,%A0,%B0);
2787 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2790 return AS2 (sbiw,%0,0);
2793 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2794 AS2 (cpc,%B0,__zero_reg__));
2798 /* Output test instruction for SImode */
2805 if (compare_sign_p (insn))
2808 return AS1 (tst,%D0);
2810 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2813 return (AS2 (sbiw,%A0,0) CR_TAB
2814 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2815 AS2 (cpc,%D0,__zero_reg__));
2818 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2819 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2820 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2821 AS2 (cpc,%D0,__zero_reg__));
2825 /* Generate asm equivalent for various shifts.
2826 Shift count is a CONST_INT, MEM or REG.
2827 This only handles cases that are not already
2828 carefully hand-optimized in ?sh??i3_out. */
2831 out_shift_with_cnt (template, insn, operands, len, t_len)
2832 const char *template;
2836 int t_len; /* Length of template. */
2840 int second_label = 1;
2841 int saved_in_tmp = 0;
2842 int use_zero_reg = 0;
2844 op[0] = operands[0];
2845 op[1] = operands[1];
2846 op[2] = operands[2];
2847 op[3] = operands[3];
2853 if (GET_CODE (operands[2]) == CONST_INT)
2855 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2856 int count = INTVAL (operands[2]);
2857 int max_len = 10; /* If larger than this, always use a loop. */
2859 if (count < 8 && !scratch)
2863 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
2865 if (t_len * count <= max_len)
2867 /* Output shifts inline with no loop - faster. */
2869 *len = t_len * count;
2873 output_asm_insn (template, op);
2882 strcat (str, AS2 (ldi,%3,%2));
2884 else if (use_zero_reg)
2886 /* Hack to save one word: use __zero_reg__ as loop counter.
2887 Set one bit, then shift in a loop until it is 0 again. */
2889 op[3] = zero_reg_rtx;
2893 strcat (str, ("set" CR_TAB
2894 AS2 (bld,%3,%2-1)));
2898 /* No scratch register available, use one from LD_REGS (saved in
2899 __tmp_reg__) that doesn't overlap with registers to shift. */
2901 op[3] = gen_rtx (REG, QImode,
2902 ((true_regnum (operands[0]) - 1) & 15) + 16);
2903 op[4] = tmp_reg_rtx;
2907 *len = 3; /* Includes "mov %3,%4" after the loop. */
2909 strcat (str, (AS2 (mov,%4,%3) CR_TAB
2915 else if (GET_CODE (operands[2]) == MEM)
2919 op[3] = op_mov[0] = tmp_reg_rtx;
2923 out_movqi_r_mr (insn, op_mov, len);
2925 output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2927 else if (register_operand (operands[2], QImode))
2929 if (reg_unused_after (insn, operands[2]))
2933 op[3] = tmp_reg_rtx;
2935 strcat (str, (AS2 (mov,%3,%2) CR_TAB));
2939 fatal_insn ("bad shift insn:", insn);
2946 strcat (str, AS1 (rjmp,2f));
2950 *len += t_len + 2; /* template + dec + brXX */
2953 strcat (str, "\n1:\t");
2954 strcat (str, template);
2955 strcat (str, second_label ? "\n2:\t" : "\n\t");
2956 strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
2957 strcat (str, CR_TAB);
2958 strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
2960 strcat (str, (CR_TAB AS2 (mov,%3,%4)));
2961 output_asm_insn (str, op);
2966 /* 8bit shift left ((char)x << i) */
2969 ashlqi3_out (insn, operands, len)
2972 int *len; /* insn length (may be NULL) */
2974 if (GET_CODE (operands[2]) == CONST_INT)
2981 switch (INTVAL (operands[2]))
2985 return AS1 (clr,%0);
2989 return AS1 (lsl,%0);
2993 return (AS1 (lsl,%0) CR_TAB
2998 return (AS1 (lsl,%0) CR_TAB
3003 if (test_hard_reg_class (LD_REGS, operands[0]))
3006 return (AS1 (swap,%0) CR_TAB
3007 AS2 (andi,%0,0xf0));
3010 return (AS1 (lsl,%0) CR_TAB
3016 if (test_hard_reg_class (LD_REGS, operands[0]))
3019 return (AS1 (swap,%0) CR_TAB
3021 AS2 (andi,%0,0xe0));
3024 return (AS1 (lsl,%0) CR_TAB
3031 if (test_hard_reg_class (LD_REGS, operands[0]))
3034 return (AS1 (swap,%0) CR_TAB
3037 AS2 (andi,%0,0xc0));
3040 return (AS1 (lsl,%0) CR_TAB
3049 return (AS1 (ror,%0) CR_TAB
3054 else if (CONSTANT_P (operands[2]))
3055 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3057 out_shift_with_cnt (AS1 (lsl,%0),
3058 insn, operands, len, 1);
3063 /* 16bit shift left ((short)x << i) */
3066 ashlhi3_out (insn, operands, len)
3071 if (GET_CODE (operands[2]) == CONST_INT)
3073 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3074 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3081 switch (INTVAL (operands[2]))
3084 if (optimize_size && scratch)
3089 return (AS1 (swap,%A0) CR_TAB
3090 AS1 (swap,%B0) CR_TAB
3091 AS2 (andi,%B0,0xf0) CR_TAB
3092 AS2 (eor,%B0,%A0) CR_TAB
3093 AS2 (andi,%A0,0xf0) CR_TAB
3099 return (AS1 (swap,%A0) CR_TAB
3100 AS1 (swap,%B0) CR_TAB
3101 AS2 (ldi,%3,0xf0) CR_TAB
3102 AS2 (and,%B0,%3) CR_TAB
3103 AS2 (eor,%B0,%A0) CR_TAB
3104 AS2 (and,%A0,%3) CR_TAB
3107 break; /* optimize_size ? 6 : 8 */
3111 break; /* scratch ? 5 : 6 */
3115 return (AS1 (lsl,%A0) CR_TAB
3116 AS1 (rol,%B0) CR_TAB
3117 AS1 (swap,%A0) CR_TAB
3118 AS1 (swap,%B0) CR_TAB
3119 AS2 (andi,%B0,0xf0) CR_TAB
3120 AS2 (eor,%B0,%A0) CR_TAB
3121 AS2 (andi,%A0,0xf0) CR_TAB
3127 return (AS1 (lsl,%A0) CR_TAB
3128 AS1 (rol,%B0) CR_TAB
3129 AS1 (swap,%A0) CR_TAB
3130 AS1 (swap,%B0) CR_TAB
3131 AS2 (ldi,%3,0xf0) CR_TAB
3132 AS2 (and,%B0,%3) CR_TAB
3133 AS2 (eor,%B0,%A0) CR_TAB
3134 AS2 (and,%A0,%3) CR_TAB
3141 break; /* scratch ? 5 : 6 */
3143 return (AS1 (clr,__tmp_reg__) CR_TAB
3144 AS1 (lsr,%B0) CR_TAB
3145 AS1 (ror,%A0) CR_TAB
3146 AS1 (ror,__tmp_reg__) CR_TAB
3147 AS1 (lsr,%B0) CR_TAB
3148 AS1 (ror,%A0) CR_TAB
3149 AS1 (ror,__tmp_reg__) CR_TAB
3150 AS2 (mov,%B0,%A0) CR_TAB
3151 AS2 (mov,%A0,__tmp_reg__));
3155 return (AS1 (lsr,%B0) CR_TAB
3156 AS2 (mov,%B0,%A0) CR_TAB
3157 AS1 (clr,%A0) CR_TAB
3158 AS1 (ror,%B0) CR_TAB
3162 if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
3163 return *len = 1, AS1 (clr,%A0);
3165 return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3170 return (AS2 (mov,%B0,%A0) CR_TAB
3171 AS1 (clr,%A0) CR_TAB
3176 return (AS2 (mov,%B0,%A0) CR_TAB
3177 AS1 (clr,%A0) CR_TAB
3178 AS1 (lsl,%B0) CR_TAB
3183 return (AS2 (mov,%B0,%A0) CR_TAB
3184 AS1 (clr,%A0) CR_TAB
3185 AS1 (lsl,%B0) CR_TAB
3186 AS1 (lsl,%B0) CR_TAB
3193 return (AS2 (mov,%B0,%A0) CR_TAB
3194 AS1 (clr,%A0) CR_TAB
3195 AS1 (swap,%B0) CR_TAB
3196 AS2 (andi,%B0,0xf0));
3201 return (AS2 (mov,%B0,%A0) CR_TAB
3202 AS1 (clr,%A0) CR_TAB
3203 AS1 (swap,%B0) CR_TAB
3204 AS2 (ldi,%3,0xf0) CR_TAB
3208 return (AS2 (mov,%B0,%A0) CR_TAB
3209 AS1 (clr,%A0) CR_TAB
3210 AS1 (lsl,%B0) CR_TAB
3211 AS1 (lsl,%B0) CR_TAB
3212 AS1 (lsl,%B0) CR_TAB
3219 return (AS2 (mov,%B0,%A0) CR_TAB
3220 AS1 (clr,%A0) CR_TAB
3221 AS1 (swap,%B0) CR_TAB
3222 AS1 (lsl,%B0) CR_TAB
3223 AS2 (andi,%B0,0xe0));
3225 if (AVR_ENHANCED && scratch)
3228 return (AS2 (ldi,%3,0x20) CR_TAB
3229 AS2 (mul,%A0,%3) CR_TAB
3230 AS2 (mov,%B0,r0) CR_TAB
3231 AS1 (clr,%A0) CR_TAB
3232 AS1 (clr,__zero_reg__));
3234 if (optimize_size && scratch)
3239 return (AS2 (mov,%B0,%A0) CR_TAB
3240 AS1 (clr,%A0) CR_TAB
3241 AS1 (swap,%B0) CR_TAB
3242 AS1 (lsl,%B0) CR_TAB
3243 AS2 (ldi,%3,0xe0) CR_TAB
3249 return ("set" CR_TAB
3250 AS2 (bld,r1,5) CR_TAB
3251 AS2 (mul,%A0,r1) CR_TAB
3252 AS2 (mov,%B0,r0) CR_TAB
3253 AS1 (clr,%A0) CR_TAB
3254 AS1 (clr,__zero_reg__));
3257 return (AS2 (mov,%B0,%A0) CR_TAB
3258 AS1 (clr,%A0) CR_TAB
3259 AS1 (lsl,%B0) CR_TAB
3260 AS1 (lsl,%B0) CR_TAB
3261 AS1 (lsl,%B0) CR_TAB
3262 AS1 (lsl,%B0) CR_TAB
3266 if (AVR_ENHANCED && ldi_ok)
3269 return (AS2 (ldi,%B0,0x40) CR_TAB
3270 AS2 (mul,%A0,%B0) CR_TAB
3271 AS2 (mov,%B0,r0) CR_TAB
3272 AS1 (clr,%A0) CR_TAB
3273 AS1 (clr,__zero_reg__));
3275 if (AVR_ENHANCED && scratch)
3278 return (AS2 (ldi,%3,0x40) CR_TAB
3279 AS2 (mul,%A0,%3) CR_TAB
3280 AS2 (mov,%B0,r0) CR_TAB
3281 AS1 (clr,%A0) CR_TAB
3282 AS1 (clr,__zero_reg__));
3284 if (optimize_size && ldi_ok)
3287 return (AS2 (mov,%B0,%A0) CR_TAB
3288 AS2 (ldi,%A0,6) "\n1:\t"
3289 AS1 (lsl,%B0) CR_TAB
3290 AS1 (dec,%A0) CR_TAB
3293 if (optimize_size && scratch)
3296 return (AS1 (clr,%B0) CR_TAB
3297 AS1 (lsr,%A0) CR_TAB
3298 AS1 (ror,%B0) CR_TAB
3299 AS1 (lsr,%A0) CR_TAB
3300 AS1 (ror,%B0) CR_TAB
3305 return (AS1 (clr,%B0) CR_TAB
3306 AS1 (lsr,%A0) CR_TAB
3307 AS1 (ror,%B0) CR_TAB
3312 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3314 insn, operands, len, 2);
3319 /* 32bit shift left ((long)x << i) */
3322 ashlsi3_out (insn, operands, len)
3327 if (GET_CODE (operands[2]) == CONST_INT)
3335 switch (INTVAL (operands[2]))
3339 int reg0 = true_regnum (operands[0]);
3340 int reg1 = true_regnum (operands[1]);
3343 return (AS2 (mov,%D0,%C1) CR_TAB
3344 AS2 (mov,%C0,%B1) CR_TAB
3345 AS2 (mov,%B0,%A1) CR_TAB
3347 else if (reg0 + 1 == reg1)
3350 return AS1 (clr,%A0);
3353 return (AS1 (clr,%A0) CR_TAB
3354 AS2 (mov,%B0,%A1) CR_TAB
3355 AS2 (mov,%C0,%B1) CR_TAB
3361 int reg0 = true_regnum (operands[0]);
3362 int reg1 = true_regnum (operands[1]);
3364 if (AVR_ENHANCED && (reg0 + 2 != reg1))
3367 return (AS2 (movw,%C0,%A1) CR_TAB
3368 AS1 (clr,%B0) CR_TAB
3371 if (reg0 + 1 >= reg1)
3372 return (AS2 (mov,%D0,%B1) CR_TAB
3373 AS2 (mov,%C0,%A1) CR_TAB
3374 AS1 (clr,%B0) CR_TAB
3376 if (reg0 + 2 == reg1)
3379 return (AS1 (clr,%B0) CR_TAB
3383 return (AS2 (mov,%C0,%A1) CR_TAB
3384 AS2 (mov,%D0,%B1) CR_TAB
3385 AS1 (clr,%B0) CR_TAB
3391 if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
3392 return (AS2 (mov,%D0,%A1) CR_TAB
3393 AS1 (clr,%C0) CR_TAB
3394 AS1 (clr,%B0) CR_TAB
3399 return (AS1 (clr,%C0) CR_TAB
3400 AS1 (clr,%B0) CR_TAB
3406 return (AS1 (clr,%D0) CR_TAB
3407 AS1 (lsr,%A0) CR_TAB
3408 AS1 (ror,%D0) CR_TAB
3409 AS1 (clr,%C0) CR_TAB
3410 AS1 (clr,%B0) CR_TAB
3415 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3416 AS1 (rol,%B0) CR_TAB
3417 AS1 (rol,%C0) CR_TAB
3419 insn, operands, len, 4);
3423 /* 8bit arithmetic shift right ((signed char)x >> i) */
3426 ashrqi3_out (insn, operands, len)
3429 int *len; /* insn length */
3431 if (GET_CODE (operands[2]) == CONST_INT)
3438 switch (INTVAL (operands[2]))
3442 return AS1 (asr,%0);
3446 return (AS1 (asr,%0) CR_TAB
3451 return (AS1 (asr,%0) CR_TAB
3457 return (AS1 (asr,%0) CR_TAB
3464 return (AS1 (asr,%0) CR_TAB
3472 return (AS2 (bst,%0,6) CR_TAB
3474 AS2 (sbc,%0,%0) CR_TAB
3480 return (AS1 (lsl,%0) CR_TAB
3484 else if (CONSTANT_P (operands[2]))
3485 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3487 out_shift_with_cnt (AS1 (asr,%0),
3488 insn, operands, len, 1);
3493 /* 16bit arithmetic shift right ((signed short)x >> i) */
3496 ashrhi3_out (insn, operands, len)
3501 if (GET_CODE (operands[2]) == CONST_INT)
3503 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3504 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3511 switch (INTVAL (operands[2]))
3515 /* XXX try to optimize this too? */
3520 break; /* scratch ? 5 : 6 */
3522 return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3523 AS2 (mov,%A0,%B0) CR_TAB
3524 AS1 (lsl,__tmp_reg__) CR_TAB
3525 AS1 (rol,%A0) CR_TAB
3526 AS2 (sbc,%B0,%B0) CR_TAB
3527 AS1 (lsl,__tmp_reg__) CR_TAB
3528 AS1 (rol,%A0) CR_TAB
3533 return (AS1 (lsl,%A0) CR_TAB
3534 AS2 (mov,%A0,%B0) CR_TAB
3535 AS1 (rol,%A0) CR_TAB
3540 int reg0 = true_regnum (operands[0]);
3541 int reg1 = true_regnum (operands[1]);
3544 return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3545 AS1 (lsl,%B0) CR_TAB
3547 else if (reg0 == reg1 + 1)
3548 return *len = 3, (AS1 (clr,%B0) CR_TAB
3549 AS2 (sbrc,%A0,7) CR_TAB
3552 return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3553 AS1 (clr,%B0) CR_TAB
3554 AS2 (sbrc,%A0,7) CR_TAB
3560 return (AS2 (mov,%A0,%B0) CR_TAB
3561 AS1 (lsl,%B0) CR_TAB
3562 AS2 (sbc,%B0,%B0) CR_TAB
3567 return (AS2 (mov,%A0,%B0) CR_TAB
3568 AS1 (lsl,%B0) CR_TAB
3569 AS2 (sbc,%B0,%B0) CR_TAB
3570 AS1 (asr,%A0) CR_TAB
3574 if (AVR_ENHANCED && ldi_ok)
3577 return (AS2 (ldi,%A0,0x20) CR_TAB
3578 AS2 (muls,%B0,%A0) CR_TAB
3579 AS2 (mov,%A0,r1) CR_TAB
3580 AS2 (sbc,%B0,%B0) CR_TAB
3581 AS1 (clr,__zero_reg__));
3583 if (optimize_size && scratch)
3586 return (AS2 (mov,%A0,%B0) CR_TAB
3587 AS1 (lsl,%B0) CR_TAB
3588 AS2 (sbc,%B0,%B0) CR_TAB
3589 AS1 (asr,%A0) CR_TAB
3590 AS1 (asr,%A0) CR_TAB
3594 if (AVR_ENHANCED && ldi_ok)
3597 return (AS2 (ldi,%A0,0x10) CR_TAB
3598 AS2 (muls,%B0,%A0) CR_TAB
3599 AS2 (mov,%A0,r1) CR_TAB
3600 AS2 (sbc,%B0,%B0) CR_TAB
3601 AS1 (clr,__zero_reg__));
3603 if (optimize_size && scratch)
3606 return (AS2 (mov,%A0,%B0) CR_TAB
3607 AS1 (lsl,%B0) CR_TAB
3608 AS2 (sbc,%B0,%B0) CR_TAB
3609 AS1 (asr,%A0) CR_TAB
3610 AS1 (asr,%A0) CR_TAB
3611 AS1 (asr,%A0) CR_TAB
3615 if (AVR_ENHANCED && ldi_ok)
3618 return (AS2 (ldi,%A0,0x08) CR_TAB
3619 AS2 (muls,%B0,%A0) CR_TAB
3620 AS2 (mov,%A0,r1) CR_TAB
3621 AS2 (sbc,%B0,%B0) CR_TAB
3622 AS1 (clr,__zero_reg__));
3625 break; /* scratch ? 5 : 7 */
3627 return (AS2 (mov,%A0,%B0) CR_TAB
3628 AS1 (lsl,%B0) CR_TAB
3629 AS2 (sbc,%B0,%B0) CR_TAB
3630 AS1 (asr,%A0) CR_TAB
3631 AS1 (asr,%A0) CR_TAB
3632 AS1 (asr,%A0) CR_TAB
3633 AS1 (asr,%A0) CR_TAB
3638 return (AS1 (lsl,%B0) CR_TAB
3639 AS2 (sbc,%A0,%A0) CR_TAB
3640 AS1 (lsl,%B0) CR_TAB
3641 AS2 (mov,%B0,%A0) CR_TAB
3645 return *len = 3, (AS1 (lsl,%B0) CR_TAB
3646 AS2 (sbc,%A0,%A0) CR_TAB
3651 out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3653 insn, operands, len, 2);
3658 /* 32bit arithmetic shift right ((signed long)x >> i) */
3661 ashrsi3_out (insn, operands, len)
3666 if (GET_CODE (operands[2]) == CONST_INT)
3674 switch (INTVAL (operands[2]))
3678 int reg0 = true_regnum (operands[0]);
3679 int reg1 = true_regnum (operands[1]);
3682 return (AS2 (mov,%A0,%B1) CR_TAB
3683 AS2 (mov,%B0,%C1) CR_TAB
3684 AS2 (mov,%C0,%D1) CR_TAB
3685 AS1 (clr,%D0) CR_TAB
3686 AS2 (sbrc,%C0,7) CR_TAB
3688 else if (reg0 == reg1 + 1)
3691 return (AS1 (clr,%D0) CR_TAB
3692 AS2 (sbrc,%C0,7) CR_TAB
3696 return (AS1 (clr,%D0) CR_TAB
3697 AS2 (sbrc,%D1,7) CR_TAB
3698 AS1 (dec,%D0) CR_TAB
3699 AS2 (mov,%C0,%D1) CR_TAB
3700 AS2 (mov,%B0,%C1) CR_TAB
3706 int reg0 = true_regnum (operands[0]);
3707 int reg1 = true_regnum (operands[1]);
3709 if (AVR_ENHANCED && (reg0 != reg1 + 2))
3712 return (AS2 (movw,%A0,%C1) CR_TAB
3713 AS1 (clr,%D0) CR_TAB
3714 AS2 (sbrc,%B0,7) CR_TAB
3715 AS1 (com,%D0) CR_TAB
3718 if (reg0 <= reg1 + 1)
3719 return (AS2 (mov,%A0,%C1) CR_TAB
3720 AS2 (mov,%B0,%D1) CR_TAB
3721 AS1 (clr,%D0) CR_TAB
3722 AS2 (sbrc,%B0,7) CR_TAB
3723 AS1 (com,%D0) CR_TAB
3725 else if (reg0 == reg1 + 2)
3726 return *len = 4, (AS1 (clr,%D0) CR_TAB
3727 AS2 (sbrc,%B0,7) CR_TAB
3728 AS1 (com,%D0) CR_TAB
3731 return (AS2 (mov,%B0,%D1) CR_TAB
3732 AS2 (mov,%A0,%C1) CR_TAB
3733 AS1 (clr,%D0) CR_TAB
3734 AS2 (sbrc,%B0,7) CR_TAB
3735 AS1 (com,%D0) CR_TAB
3740 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3741 return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3742 AS1 (clr,%D0) CR_TAB
3743 AS2 (sbrc,%A0,7) CR_TAB
3744 AS1 (com,%D0) CR_TAB
3745 AS2 (mov,%B0,%D0) CR_TAB
3748 return *len = 5, (AS1 (clr,%D0) CR_TAB
3749 AS2 (sbrc,%A0,7) CR_TAB
3750 AS1 (com,%D0) CR_TAB
3751 AS2 (mov,%B0,%D0) CR_TAB
3756 return *len = 4, (AS1 (lsl,%D0) CR_TAB
3757 AS2 (sbc,%A0,%A0) CR_TAB
3758 AS2 (mov,%B0,%A0) CR_TAB
3759 AS2 (movw,%C0,%A0));
3761 return *len = 5, (AS1 (lsl,%D0) CR_TAB
3762 AS2 (sbc,%A0,%A0) CR_TAB
3763 AS2 (mov,%B0,%A0) CR_TAB
3764 AS2 (mov,%C0,%A0) CR_TAB
3769 out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
3770 AS1 (ror,%C0) CR_TAB
3771 AS1 (ror,%B0) CR_TAB
3773 insn, operands, len, 4);
3777 /* 8bit logic shift right ((unsigned char)x >> i) */
3780 lshrqi3_out (insn, operands, len)
3785 if (GET_CODE (operands[2]) == CONST_INT)
3792 switch (INTVAL (operands[2]))
3796 return AS1 (clr,%0);
3800 return AS1 (lsr,%0);
3804 return (AS1 (lsr,%0) CR_TAB
3808 return (AS1 (lsr,%0) CR_TAB
3813 if (test_hard_reg_class (LD_REGS, operands[0]))
3816 return (AS1 (swap,%0) CR_TAB
3817 AS2 (andi,%0,0x0f));
3820 return (AS1 (lsr,%0) CR_TAB
3826 if (test_hard_reg_class (LD_REGS, operands[0]))
3829 return (AS1 (swap,%0) CR_TAB
3834 return (AS1 (lsr,%0) CR_TAB
3841 if (test_hard_reg_class (LD_REGS, operands[0]))
3844 return (AS1 (swap,%0) CR_TAB
3850 return (AS1 (lsr,%0) CR_TAB
3859 return (AS1 (rol,%0) CR_TAB
3864 else if (CONSTANT_P (operands[2]))
3865 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3867 out_shift_with_cnt (AS1 (lsr,%0),
3868 insn, operands, len, 1);
3872 /* 16bit logic shift right ((unsigned short)x >> i) */
3875 lshrhi3_out (insn, operands, len)
3880 if (GET_CODE (operands[2]) == CONST_INT)
3882 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3883 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3890 switch (INTVAL (operands[2]))
3893 if (optimize_size && scratch)
3898 return (AS1 (swap,%B0) CR_TAB
3899 AS1 (swap,%A0) CR_TAB
3900 AS2 (andi,%A0,0x0f) CR_TAB
3901 AS2 (eor,%A0,%B0) CR_TAB
3902 AS2 (andi,%B0,0x0f) CR_TAB
3908 return (AS1 (swap,%B0) CR_TAB
3909 AS1 (swap,%A0) CR_TAB
3910 AS2 (ldi,%3,0x0f) CR_TAB
3911 AS2 (and,%A0,%3) CR_TAB
3912 AS2 (eor,%A0,%B0) CR_TAB
3913 AS2 (and,%B0,%3) CR_TAB
3916 break; /* optimize_size ? 6 : 8 */
3920 break; /* scratch ? 5 : 6 */
3924 return (AS1 (lsr,%B0) CR_TAB
3925 AS1 (ror,%A0) CR_TAB
3926 AS1 (swap,%B0) CR_TAB
3927 AS1 (swap,%A0) CR_TAB
3928 AS2 (andi,%A0,0x0f) CR_TAB
3929 AS2 (eor,%A0,%B0) CR_TAB
3930 AS2 (andi,%B0,0x0f) CR_TAB
3936 return (AS1 (lsr,%B0) CR_TAB
3937 AS1 (ror,%A0) CR_TAB
3938 AS1 (swap,%B0) CR_TAB
3939 AS1 (swap,%A0) CR_TAB
3940 AS2 (ldi,%3,0x0f) CR_TAB
3941 AS2 (and,%A0,%3) CR_TAB
3942 AS2 (eor,%A0,%B0) CR_TAB
3943 AS2 (and,%B0,%3) CR_TAB
3950 break; /* scratch ? 5 : 6 */
3952 return (AS1 (clr,__tmp_reg__) CR_TAB
3953 AS1 (lsl,%A0) CR_TAB
3954 AS1 (rol,%B0) CR_TAB
3955 AS1 (rol,__tmp_reg__) CR_TAB
3956 AS1 (lsl,%A0) CR_TAB
3957 AS1 (rol,%B0) CR_TAB
3958 AS1 (rol,__tmp_reg__) CR_TAB
3959 AS2 (mov,%A0,%B0) CR_TAB
3960 AS2 (mov,%B0,__tmp_reg__));
3964 return (AS1 (lsl,%A0) CR_TAB
3965 AS2 (mov,%A0,%B0) CR_TAB
3966 AS1 (rol,%A0) CR_TAB
3967 AS2 (sbc,%B0,%B0) CR_TAB
3971 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
3972 return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
3975 return *len = 1, AS1 (clr,%B0);
3979 return (AS2 (mov,%A0,%B0) CR_TAB
3980 AS1 (clr,%B0) CR_TAB
3985 return (AS2 (mov,%A0,%B0) CR_TAB
3986 AS1 (clr,%B0) CR_TAB
3987 AS1 (lsr,%A0) CR_TAB
3992 return (AS2 (mov,%A0,%B0) CR_TAB
3993 AS1 (clr,%B0) CR_TAB
3994 AS1 (lsr,%A0) CR_TAB
3995 AS1 (lsr,%A0) CR_TAB
4002 return (AS2 (mov,%A0,%B0) CR_TAB
4003 AS1 (clr,%B0) CR_TAB
4004 AS1 (swap,%A0) CR_TAB
4005 AS2 (andi,%A0,0x0f));
4010 return (AS2 (mov,%A0,%B0) CR_TAB
4011 AS1 (clr,%B0) CR_TAB
4012 AS1 (swap,%A0) CR_TAB
4013 AS2 (ldi,%3,0x0f) CR_TAB
4017 return (AS2 (mov,%A0,%B0) CR_TAB
4018 AS1 (clr,%B0) CR_TAB
4019 AS1 (lsr,%A0) CR_TAB
4020 AS1 (lsr,%A0) CR_TAB
4021 AS1 (lsr,%A0) CR_TAB
4028 return (AS2 (mov,%A0,%B0) CR_TAB
4029 AS1 (clr,%B0) CR_TAB
4030 AS1 (swap,%A0) CR_TAB
4031 AS1 (lsr,%A0) CR_TAB
4032 AS2 (andi,%A0,0x07));
4034 if (AVR_ENHANCED && scratch)
4037 return (AS2 (ldi,%3,0x08) CR_TAB
4038 AS2 (mul,%B0,%3) CR_TAB
4039 AS2 (mov,%A0,r1) CR_TAB
4040 AS1 (clr,%B0) CR_TAB
4041 AS1 (clr,__zero_reg__));
4043 if (optimize_size && scratch)
4048 return (AS2 (mov,%A0,%B0) CR_TAB
4049 AS1 (clr,%B0) CR_TAB
4050 AS1 (swap,%A0) CR_TAB
4051 AS1 (lsr,%A0) CR_TAB
4052 AS2 (ldi,%3,0x07) CR_TAB
4058 return ("set" CR_TAB
4059 AS2 (bld,r1,3) CR_TAB
4060 AS2 (mul,%B0,r1) CR_TAB
4061 AS2 (mov,%A0,r1) CR_TAB
4062 AS1 (clr,%B0) CR_TAB
4063 AS1 (clr,__zero_reg__));
4066 return (AS2 (mov,%A0,%B0) CR_TAB
4067 AS1 (clr,%B0) CR_TAB
4068 AS1 (lsr,%A0) CR_TAB
4069 AS1 (lsr,%A0) CR_TAB
4070 AS1 (lsr,%A0) CR_TAB
4071 AS1 (lsr,%A0) CR_TAB
4075 if (AVR_ENHANCED && ldi_ok)
4078 return (AS2 (ldi,%A0,0x04) CR_TAB
4079 AS2 (mul,%B0,%A0) CR_TAB
4080 AS2 (mov,%A0,r1) CR_TAB
4081 AS1 (clr,%B0) CR_TAB
4082 AS1 (clr,__zero_reg__));
4084 if (AVR_ENHANCED && scratch)
4087 return (AS2 (ldi,%3,0x04) CR_TAB
4088 AS2 (mul,%B0,%3) CR_TAB
4089 AS2 (mov,%A0,r1) CR_TAB
4090 AS1 (clr,%B0) CR_TAB
4091 AS1 (clr,__zero_reg__));
4093 if (optimize_size && ldi_ok)
4096 return (AS2 (mov,%A0,%B0) CR_TAB
4097 AS2 (ldi,%B0,6) "\n1:\t"
4098 AS1 (lsr,%A0) CR_TAB
4099 AS1 (dec,%B0) CR_TAB
4102 if (optimize_size && scratch)
4105 return (AS1 (clr,%A0) CR_TAB
4106 AS1 (lsl,%B0) CR_TAB
4107 AS1 (rol,%A0) CR_TAB
4108 AS1 (lsl,%B0) CR_TAB
4109 AS1 (rol,%A0) CR_TAB
4114 return (AS1 (clr,%A0) CR_TAB
4115 AS1 (lsl,%B0) CR_TAB
4116 AS1 (rol,%A0) CR_TAB
4121 out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
4123 insn, operands, len, 2);
4127 /* 32bit logic shift right ((unsigned int)x >> i) */
4130 lshrsi3_out (insn, operands, len)
4135 if (GET_CODE (operands[2]) == CONST_INT)
4143 switch (INTVAL (operands[2]))
4147 int reg0 = true_regnum (operands[0]);
4148 int reg1 = true_regnum (operands[1]);
4151 return (AS2 (mov,%A0,%B1) CR_TAB
4152 AS2 (mov,%B0,%C1) CR_TAB
4153 AS2 (mov,%C0,%D1) CR_TAB
4155 else if (reg0 == reg1 + 1)
4156 return *len = 1, AS1 (clr,%D0);
4158 return (AS1 (clr,%D0) CR_TAB
4159 AS2 (mov,%C0,%D1) CR_TAB
4160 AS2 (mov,%B0,%C1) CR_TAB
4166 int reg0 = true_regnum (operands[0]);
4167 int reg1 = true_regnum (operands[1]);
4169 if (AVR_ENHANCED && (reg0 != reg1 + 2))
4172 return (AS2 (movw,%A0,%C1) CR_TAB
4173 AS1 (clr,%C0) CR_TAB
4176 if (reg0 <= reg1 + 1)
4177 return (AS2 (mov,%A0,%C1) CR_TAB
4178 AS2 (mov,%B0,%D1) CR_TAB
4179 AS1 (clr,%C0) CR_TAB
4181 else if (reg0 == reg1 + 2)
4182 return *len = 2, (AS1 (clr,%C0) CR_TAB
4185 return (AS2 (mov,%B0,%D1) CR_TAB
4186 AS2 (mov,%A0,%C1) CR_TAB
4187 AS1 (clr,%C0) CR_TAB
4192 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
4193 return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4194 AS1 (clr,%B0) CR_TAB
4195 AS1 (clr,%C0) CR_TAB
4198 return *len = 3, (AS1 (clr,%B0) CR_TAB
4199 AS1 (clr,%C0) CR_TAB
4204 return (AS1 (clr,%A0) CR_TAB
4205 AS2 (sbrc,%D0,7) CR_TAB
4206 AS1 (inc,%A0) CR_TAB
4207 AS1 (clr,%B0) CR_TAB
4208 AS1 (clr,%C0) CR_TAB
4213 out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4214 AS1 (ror,%C0) CR_TAB
4215 AS1 (ror,%B0) CR_TAB
4217 insn, operands, len, 4);
4221 /* Modifies the length assigned to instruction INSN
4222 LEN is the initially computed length of the insn. */
4225 adjust_insn_length (insn, len)
4229 rtx patt = PATTERN (insn);
4232 if (GET_CODE (patt) == SET)
4235 op[1] = SET_SRC (patt);
4236 op[0] = SET_DEST (patt);
4237 if (general_operand (op[1], VOIDmode)
4238 && general_operand (op[0], VOIDmode))
4240 switch (GET_MODE (op[0]))
4243 output_movqi (insn, op, &len);
4246 output_movhi (insn, op, &len);
4250 output_movsisf (insn, op, &len);
4256 else if (op[0] == cc0_rtx && REG_P (op[1]))
4258 switch (GET_MODE (op[1]))
4260 case HImode: out_tsthi (insn,&len); break;
4261 case SImode: out_tstsi (insn,&len); break;
4265 else if (GET_CODE (op[1]) == AND)
4267 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4269 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4270 if (GET_MODE (op[1]) == SImode)
4271 len = (((mask & 0xff) != 0xff)
4272 + ((mask & 0xff00) != 0xff00)
4273 + ((mask & 0xff0000L) != 0xff0000L)
4274 + ((mask & 0xff000000L) != 0xff000000L));
4275 else if (GET_MODE (op[1]) == HImode)
4276 len = (((mask & 0xff) != 0xff)
4277 + ((mask & 0xff00) != 0xff00));
4280 else if (GET_CODE (op[1]) == IOR)
4282 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4284 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4285 if (GET_MODE (op[1]) == SImode)
4286 len = (((mask & 0xff) != 0)
4287 + ((mask & 0xff00) != 0)
4288 + ((mask & 0xff0000L) != 0)
4289 + ((mask & 0xff000000L) != 0));
4290 else if (GET_MODE (op[1]) == HImode)
4291 len = (((mask & 0xff) != 0)
4292 + ((mask & 0xff00) != 0));
4296 set = single_set (insn);
4301 op[1] = SET_SRC (set);
4302 op[0] = SET_DEST (set);
4304 if (GET_CODE (patt) == PARALLEL
4305 && general_operand (op[1], VOIDmode)
4306 && general_operand (op[0], VOIDmode))
4308 if (XVECLEN (patt, 0) == 2)
4309 op[2] = XVECEXP (patt, 0, 1);
4311 switch (GET_MODE (op[0]))
4317 output_reload_inhi (insn, op, &len);
4321 output_reload_insisf (insn, op, &len);
4327 else if (GET_CODE (op[1]) == ASHIFT
4328 || GET_CODE (op[1]) == ASHIFTRT
4329 || GET_CODE (op[1]) == LSHIFTRT)
4333 ops[1] = XEXP (op[1],0);
4334 ops[2] = XEXP (op[1],1);
4335 switch (GET_CODE (op[1]))
4338 switch (GET_MODE (op[0]))
4340 case QImode: ashlqi3_out (insn,ops,&len); break;
4341 case HImode: ashlhi3_out (insn,ops,&len); break;
4342 case SImode: ashlsi3_out (insn,ops,&len); break;
4347 switch (GET_MODE (op[0]))
4349 case QImode: ashrqi3_out (insn,ops,&len); break;
4350 case HImode: ashrhi3_out (insn,ops,&len); break;
4351 case SImode: ashrsi3_out (insn,ops,&len); break;
4356 switch (GET_MODE (op[0]))
4358 case QImode: lshrqi3_out (insn,ops,&len); break;
4359 case HImode: lshrhi3_out (insn,ops,&len); break;
4360 case SImode: lshrsi3_out (insn,ops,&len); break;
4372 /* Return non-zero if register REG dead after INSN */
4375 reg_unused_after (insn, reg)
4379 return (dead_or_set_p (insn, reg)
4380 || (REG_P(reg) && _reg_unused_after (insn, reg)));
4383 /* Return non-zero if REG is not used after INSN.
4384 We assume REG is a reload reg, and therefore does
4385 not live past labels. It may live past calls or jumps though. */
4388 _reg_unused_after (insn, reg)
4395 /* If the reg is set by this instruction, then it is safe for our
4396 case. Disregard the case where this is a store to memory, since
4397 we are checking a register used in the store address. */
4398 set = single_set (insn);
4399 if (set && GET_CODE (SET_DEST (set)) != MEM
4400 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4403 while ((insn = NEXT_INSN (insn)))
4405 code = GET_CODE (insn);
4408 /* If this is a label that existed before reload, then the register
4409 if dead here. However, if this is a label added by reorg, then
4410 the register may still be live here. We can't tell the difference,
4411 so we just ignore labels completely. */
4412 if (code == CODE_LABEL)
4417 if (code == JUMP_INSN)
4420 /* If this is a sequence, we must handle them all at once.
4421 We could have for instance a call that sets the target register,
4422 and an insn in a delay slot that uses the register. In this case,
4423 we must return 0. */
4424 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
4429 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
4431 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
4432 rtx set = single_set (this_insn);
4434 if (GET_CODE (this_insn) == CALL_INSN)
4436 else if (GET_CODE (this_insn) == JUMP_INSN)
4438 if (INSN_ANNULLED_BRANCH_P (this_insn))
4443 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4445 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4447 if (GET_CODE (SET_DEST (set)) != MEM)
4453 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
4458 else if (code == JUMP_INSN)
4462 if (code == CALL_INSN)
4465 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4466 if (GET_CODE (XEXP (tem, 0)) == USE
4467 && REG_P (XEXP (XEXP (tem, 0), 0))
4468 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
4470 if (call_used_regs[REGNO (reg)])
4474 if (GET_RTX_CLASS (code) == 'i')
4476 rtx set = single_set (insn);
4478 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4480 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4481 return GET_CODE (SET_DEST (set)) != MEM;
4482 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
4489 /* Target hook for assembling integer objects. The AVR version needs
4490 special handling for references to certain labels. */
4493 avr_assemble_integer (x, size, aligned_p)
4498 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
4499 && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FLAG (x))
4500 || GET_CODE (x) == LABEL_REF))
4502 fputs ("\t.word\tpm(", asm_out_file);
4503 output_addr_const (asm_out_file, x);
4504 fputs (")\n", asm_out_file);
4507 return default_assemble_integer (x, size, aligned_p);
4510 /* Sets section name for declaration DECL */
4513 avr_unique_section (decl, reloc)
4515 int reloc ATTRIBUTE_UNUSED;
4518 const char *name, *prefix;
4520 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
4521 /* Strip off any encoding in name. */
4522 STRIP_NAME_ENCODING (name, name);
4524 if (TREE_CODE (decl) == FUNCTION_DECL)
4526 if (flag_function_sections)
4534 if (flag_function_sections)
4536 len = strlen (name) + strlen (prefix);
4537 string = alloca (len + 1);
4538 sprintf (string, "%s%s", prefix, name);
4539 DECL_SECTION_NAME (decl) = build_string (len, string);
4544 /* The routine used to output NUL terminated strings. We use a special
4545 version of this for most svr4 targets because doing so makes the
4546 generated assembly code more compact (and thus faster to assemble)
4547 as well as more readable, especially for targets like the i386
4548 (where the only alternative is to output character sequences as
4549 comma separated lists of numbers). */
4552 gas_output_limited_string(file, str)
4556 const unsigned char *_limited_str = (unsigned char *) str;
4558 fprintf (file, "%s\"", STRING_ASM_OP);
4559 for (; (ch = *_limited_str); _limited_str++)
4562 switch (escape = ESCAPES[ch])
4568 fprintf (file, "\\%03o", ch);
4572 putc (escape, file);
4576 fprintf (file, "\"\n");
4579 /* The routine used to output sequences of byte values. We use a special
4580 version of this for most svr4 targets because doing so makes the
4581 generated assembly code more compact (and thus faster to assemble)
4582 as well as more readable. Note that if we find subparts of the
4583 character sequence which end with NUL (and which are shorter than
4584 STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
4587 gas_output_ascii(file, str, length)
4592 const unsigned char *_ascii_bytes = (const unsigned char *) str;
4593 const unsigned char *limit = _ascii_bytes + length;
4594 unsigned bytes_in_chunk = 0;
4595 for (; _ascii_bytes < limit; _ascii_bytes++)
4597 const unsigned char *p;
4598 if (bytes_in_chunk >= 60)
4600 fprintf (file, "\"\n");
4603 for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
4605 if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
4607 if (bytes_in_chunk > 0)
4609 fprintf (file, "\"\n");
4612 gas_output_limited_string (file, (char*)_ascii_bytes);
4619 if (bytes_in_chunk == 0)
4620 fprintf (file, "\t.ascii\t\"");
4621 switch (escape = ESCAPES[ch = *_ascii_bytes])
4628 fprintf (file, "\\%03o", ch);
4629 bytes_in_chunk += 4;
4633 putc (escape, file);
4634 bytes_in_chunk += 2;
4639 if (bytes_in_chunk > 0)
4640 fprintf (file, "\"\n");
4643 /* Return value is nonzero if pseudos that have been
4644 assigned to registers of class CLASS would likely be spilled
4645 because registers of CLASS are needed for spill registers. */
4648 class_likely_spilled_p (c)
4651 return (c != ALL_REGS && c != ADDW_REGS);
4654 /* Valid attributes:
4655 progmem - put data to program memory;
4656 signal - make a function to be hardware interrupt. After function
4657 prologue interrupts are disabled;
4658 interrupt - make a function to be hardware interrupt. After function
4659 prologue interrupts are enabled;
4660 naked - don't generate function prologue/epilogue and `ret' command.
4662 Only `progmem' attribute valid for type. */
4664 const struct attribute_spec avr_attribute_table[] =
4666 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
4667 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute },
4668 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4669 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4670 { "naked", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4671 { NULL, 0, 0, false, false, false, NULL }
4674 /* Handle a "progmem" attribute; arguments as in
4675 struct attribute_spec.handler. */
4677 avr_handle_progmem_attribute (node, name, args, flags, no_add_attrs)
4680 tree args ATTRIBUTE_UNUSED;
4681 int flags ATTRIBUTE_UNUSED;
4686 if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
4688 if (DECL_INITIAL (*node) == NULL_TREE && !DECL_EXTERNAL (*node))
4690 warning ("only initialized variables can be placed into "
4691 "program memory area");
4692 *no_add_attrs = true;
4697 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
4698 *no_add_attrs = true;
4705 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
4706 struct attribute_spec.handler. */
4708 avr_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
4711 tree args ATTRIBUTE_UNUSED;
4712 int flags ATTRIBUTE_UNUSED;
4715 if (TREE_CODE (*node) != FUNCTION_DECL)
4717 warning ("`%s' attribute only applies to functions",
4718 IDENTIFIER_POINTER (name));
4719 *no_add_attrs = true;
4725 /* Look for attribute `progmem' in DECL
4726 if found return 1, otherwise 0. */
4729 avr_progmem_p (decl)
4734 if (TREE_CODE (decl) != VAR_DECL)
4738 != lookup_attribute ("progmem", DECL_ATTRIBUTES (decl)))
4744 while (TREE_CODE (a) == ARRAY_TYPE);
4746 if (a == error_mark_node)
4749 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
4755 /* Encode section information about tree DECL. */
4758 avr_encode_section_info (decl, first)
4762 if (TREE_CODE (decl) == FUNCTION_DECL)
4763 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
4765 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
4766 && TREE_CODE (decl) == VAR_DECL
4767 && avr_progmem_p (decl))
4769 static const char *const dsec = ".progmem.data";
4770 DECL_SECTION_NAME (decl) = build_string (strlen (dsec), dsec);
4771 TREE_READONLY (decl) = 1;
4775 /* Outputs to the stdio stream FILE some
4776 appropriate text to go at the start of an assembler file. */
4779 asm_file_start (file)
4782 output_file_directive (file, main_input_filename);
4783 fprintf (file, "\t.arch %s\n", avr_mcu_name);
4784 fputs ("__SREG__ = 0x3f\n"
4786 "__SP_L__ = 0x3d\n", file);
4788 fputs ("__tmp_reg__ = 0\n"
4789 "__zero_reg__ = 1\n"
4790 "_PC_ = 2\n", file);
4792 commands_in_file = 0;
4793 commands_in_prologues = 0;
4794 commands_in_epilogues = 0;
4797 /* Outputs to the stdio stream FILE some
4798 appropriate text to go at the end of an assembler file. */
4805 "/* File %s: code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
4806 main_input_filename,
4809 commands_in_file - commands_in_prologues - commands_in_epilogues,
4810 commands_in_prologues, commands_in_epilogues);
4813 /* Choose the order in which to allocate hard registers for
4814 pseudo-registers local to a basic block.
4816 Store the desired register order in the array `reg_alloc_order'.
4817 Element 0 should be the register to allocate first; element 1, the
4818 next register; and so on. */
4821 order_regs_for_local_alloc ()
4824 static const int order_0[] = {
4832 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4836 static const int order_1[] = {
4844 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4848 static const int order_2[] = {
4857 15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4862 const int *order = (TARGET_ORDER_1 ? order_1 :
4863 TARGET_ORDER_2 ? order_2 :
4865 for (i=0; i < ARRAY_SIZE (order_0); ++i)
4866 reg_alloc_order[i] = order[i];
4869 /* Calculate the cost of X code of the expression in which it is contained,
4870 found in OUTER_CODE */
4873 default_rtx_costs (X, code, outer_code)
4876 enum rtx_code outer_code;
4883 cost = 2 * GET_MODE_SIZE (GET_MODE (X));
4886 if (outer_code != SET)
4888 if (GET_CODE (XEXP (X,0)) == SYMBOL_REF)
4889 cost += 2 * GET_MODE_SIZE (GET_MODE (X));
4891 cost += GET_MODE_SIZE (GET_MODE (X));
4897 if (outer_code == SET)
4898 cost = GET_MODE_SIZE (GET_MODE (X));
4900 cost = -GET_MODE_SIZE (GET_MODE (X));
4903 if (outer_code == SET)
4904 cost = GET_MODE_SIZE (GET_MODE (X));
4910 if (outer_code == SET)
4912 if (X == stack_pointer_rtx)
4914 else if (GET_CODE (XEXP (X,1)) == CONST_INT)
4915 cost = (INTVAL (XEXP (X,1)) <= 63 ? 1 :
4916 GET_MODE_SIZE (GET_MODE (X)));
4918 cost = GET_MODE_SIZE (GET_MODE (X));
4922 if (GET_CODE (XEXP (X,1)) == CONST_INT)
4923 cost = GET_MODE_SIZE (GET_MODE (XEXP (X,0)));
4931 /* Calculate the cost of a memory address */
4934 avr_address_cost (x)
4937 if (GET_CODE (x) == PLUS
4938 && GET_CODE (XEXP (x,1)) == CONST_INT
4939 && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
4940 && INTVAL (XEXP (x,1)) >= 61)
4942 if (CONSTANT_ADDRESS_P (x))
4944 if (avr_io_address_p (x, 1))
4951 /* EXTRA_CONSTRAINT helper */
4954 extra_constraint (x, c)
4959 && GET_CODE (x) == MEM
4960 && GET_CODE (XEXP (x,0)) == PLUS)
4962 if (TARGET_ALL_DEBUG)
4964 fprintf (stderr, ("extra_constraint:\n"
4965 "reload_completed: %d\n"
4966 "reload_in_progress: %d\n"),
4967 reload_completed, reload_in_progress);
4970 if (GET_CODE (x) == MEM
4971 && GET_CODE (XEXP (x,0)) == PLUS
4972 && REG_P (XEXP (XEXP (x,0), 0))
4973 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
4974 && (INTVAL (XEXP (XEXP (x,0), 1))
4975 <= MAX_LD_OFFSET (GET_MODE (x))))
4977 rtx xx = XEXP (XEXP (x,0), 0);
4978 int regno = REGNO (xx);
4979 if (TARGET_ALL_DEBUG)
4981 fprintf (stderr, ("extra_constraint:\n"
4982 "reload_completed: %d\n"
4983 "reload_in_progress: %d\n"),
4984 reload_completed, reload_in_progress);
4987 if (regno >= FIRST_PSEUDO_REGISTER)
4988 return 1; /* allocate pseudos */
4989 else if (regno == REG_Z || regno == REG_Y)
4990 return 1; /* strictly check */
4991 else if (xx == frame_pointer_rtx
4992 || xx == arg_pointer_rtx)
4993 return 1; /* XXX frame & arg pointer checks */
4999 /* Convert condition code CONDITION to the valid AVR condition code */
5002 avr_normalize_condition (condition)
5020 /* This fnction optimizes conditional jumps */
5023 machine_dependent_reorg (first_insn)
5028 for (insn = first_insn; insn; insn = NEXT_INSN (insn))
5030 if (! (GET_CODE (insn) == INSN
5031 || GET_CODE (insn) == CALL_INSN
5032 || GET_CODE (insn) == JUMP_INSN)
5033 || !single_set (insn))
5036 pattern = PATTERN (insn);
5038 if (GET_CODE (pattern) == PARALLEL)
5039 pattern = XVECEXP (pattern, 0, 0);
5040 if (GET_CODE (pattern) == SET
5041 && SET_DEST (pattern) == cc0_rtx
5042 && compare_diff_p (insn))
5044 if (GET_CODE (SET_SRC (pattern)) == COMPARE)
5046 /* Now we work under compare insn */
5048 pattern = SET_SRC (pattern);
5049 if (true_regnum (XEXP (pattern,0)) >= 0
5050 && true_regnum (XEXP (pattern,1)) >= 0 )
5052 rtx x = XEXP (pattern,0);
5053 rtx next = next_real_insn (insn);
5054 rtx pat = PATTERN (next);
5055 rtx src = SET_SRC (pat);
5056 rtx t = XEXP (src,0);
5057 PUT_CODE (t, swap_condition (GET_CODE (t)));
5058 XEXP (pattern,0) = XEXP (pattern,1);
5059 XEXP (pattern,1) = x;
5060 INSN_CODE (next) = -1;
5062 else if (true_regnum (XEXP (pattern,0)) >= 0
5063 && GET_CODE (XEXP (pattern,1)) == CONST_INT)
5065 rtx x = XEXP (pattern,1);
5066 rtx next = next_real_insn (insn);
5067 rtx pat = PATTERN (next);
5068 rtx src = SET_SRC (pat);
5069 rtx t = XEXP (src,0);
5071 if (avr_simplify_comparision_p (GET_MODE (XEXP (pattern,0)),
5074 XEXP (pattern,1) = GEN_INT (INTVAL (x)+1);
5075 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
5076 INSN_CODE (next) = -1;
5077 INSN_CODE (insn) = -1;
5081 else if (true_regnum (SET_SRC (pattern)) >= 0)
5083 /* This is a tst insn */
5084 rtx next = next_real_insn (insn);
5085 rtx pat = PATTERN (next);
5086 rtx src = SET_SRC (pat);
5087 rtx t = XEXP (src,0);
5089 PUT_CODE (t, swap_condition (GET_CODE (t)));
5090 SET_SRC (pattern) = gen_rtx (NEG,
5091 GET_MODE (SET_SRC (pattern)),
5093 INSN_CODE (next) = -1;
5094 INSN_CODE (insn) = -1;
5100 /* Returns register number for function return value.*/
5108 /* Ceate an RTX representing the place where a
5109 library function returns a value of mode MODE. */
5112 avr_libcall_value (mode)
5113 enum machine_mode mode;
5115 int offs = GET_MODE_SIZE (mode);
5118 return gen_rtx (REG, mode, RET_REGISTER + 2 - offs);
5121 /* Create an RTX representing the place where a
5122 function returns a value of data type VALTYPE. */
5125 avr_function_value (type, func)
5127 tree func ATTRIBUTE_UNUSED;
5131 if (TYPE_MODE (type) != BLKmode)
5132 return avr_libcall_value (TYPE_MODE (type));
5134 offs = int_size_in_bytes (type);
5137 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
5138 offs = GET_MODE_SIZE (SImode);
5139 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
5140 offs = GET_MODE_SIZE (DImode);
5142 return gen_rtx (REG, BLKmode, RET_REGISTER + 2 - offs);
5145 /* Returns non-zero if the number MASK has only one bit set. */
5148 mask_one_bit_p (mask)
5152 unsigned HOST_WIDE_INT n=mask;
5153 for (i = 0; i < 32; ++i)
5155 if (n & 0x80000000L)
5157 if (n & 0x7fffffffL)
5168 /* Places additional restrictions on the register class to
5169 use when it is necessary to copy value X into a register
5173 preferred_reload_class (x, class)
5174 rtx x ATTRIBUTE_UNUSED;
5175 enum reg_class class;
5181 test_hard_reg_class (class, x)
5182 enum reg_class class;
5185 int regno = true_regnum (x);
5188 return TEST_HARD_REG_CLASS (class, regno);
5192 debug_hard_reg_set (set)
5196 for (i=0; i < FIRST_PSEUDO_REGISTER; ++i)
5198 if (TEST_HARD_REG_BIT (set, i))
5200 fprintf (stderr, "r%-2d ", i);
5203 fprintf (stderr, "\n");
5207 jump_over_one_insn_p (insn, dest)
5211 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
5214 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
5215 int dest_addr = INSN_ADDRESSES (uid);
5216 return dest_addr - jump_addr == 2;
5219 /* Returns 1 if a value of mode MODE can be stored starting with hard
5220 register number REGNO. On the enhanced core, anything larger than
5221 1 byte must start in even numbered register for "movw" to work
5222 (this way we don't have to check for odd registers everywhere). */
5225 avr_hard_regno_mode_ok (regno, mode)
5227 enum machine_mode mode;
5229 /* Bug workaround: recog.c (peep2_find_free_register) and probably
5230 a few other places assume that the frame pointer is a single hard
5231 register, so r29 may be allocated and overwrite the high byte of
5232 the frame pointer. Do not allow any value to start in r29. */
5233 if (regno == REG_Y + 1)
5238 /* if (regno < 24 && !AVR_ENHANCED)
5240 return !(regno & 1);
5243 /* Returns 1 if we know register operand OP was 0 before INSN. */
5246 reg_was_0 (insn, op)
5251 return (optimize > 0 && insn && op && REG_P (op)
5252 && (link = find_reg_note (insn, REG_WAS_0, 0))
5253 /* Make sure the insn that stored the 0 is still present. */
5254 && ! INSN_DELETED_P (XEXP (link, 0))
5255 && GET_CODE (XEXP (link, 0)) != NOTE
5256 /* Make sure cross jumping didn't happen here. */
5257 && no_labels_between_p (XEXP (link, 0), insn)
5258 /* Make sure the reg hasn't been clobbered. */
5259 && ! reg_set_between_p (op, XEXP (link, 0), insn));
5262 /* Returns 1 if X is a valid address for an I/O register of size SIZE
5263 (1 or 2). Used for lds/sts -> in/out optimization. Add 0x20 to SIZE
5264 to check for the lower half of I/O space (for cbi/sbi/sbic/sbis). */
5267 avr_io_address_p (x, size)
5271 return (optimize > 0 && GET_CODE (x) == CONST_INT
5272 && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size);
5275 /* Returns nonzero (bit number + 1) if X, or -X, is a constant power of 2. */
5278 const_int_pow2_p (x)
5281 if (GET_CODE (x) == CONST_INT)
5283 HOST_WIDE_INT d = INTVAL (x);
5284 HOST_WIDE_INT abs_d = (d >= 0) ? d : -d;
5285 return exact_log2 (abs_d) + 1;
5291 output_reload_inhi (insn, operands, len)
5292 rtx insn ATTRIBUTE_UNUSED;
5300 if (GET_CODE (operands[1]) == CONST_INT)
5302 int val = INTVAL (operands[1]);
5303 if ((val & 0xff) == 0)
5306 return (AS2 (mov,%A0,__zero_reg__) CR_TAB
5307 AS2 (ldi,%2,hi8(%1)) CR_TAB
5310 else if ((val & 0xff00) == 0)
5313 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5314 AS2 (mov,%A0,%2) CR_TAB
5315 AS2 (mov,%B0,__zero_reg__));
5317 else if ((val & 0xff) == ((val & 0xff00) >> 8))
5320 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5321 AS2 (mov,%A0,%2) CR_TAB
5326 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5327 AS2 (mov,%A0,%2) CR_TAB
5328 AS2 (ldi,%2,hi8(%1)) CR_TAB
5334 output_reload_insisf (insn, operands, len)
5335 rtx insn ATTRIBUTE_UNUSED;
5339 rtx src = operands[1];
5340 int cnst = (GET_CODE (src) == CONST_INT);
5345 *len = 4 + ((INTVAL (src) & 0xff) != 0)
5346 + ((INTVAL (src) & 0xff00) != 0)
5347 + ((INTVAL (src) & 0xff0000) != 0)
5348 + ((INTVAL (src) & 0xff000000) != 0);
5355 if (cnst && ((INTVAL (src) & 0xff) == 0))
5356 output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
5359 output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
5360 output_asm_insn (AS2 (mov, %A0, %2), operands);
5362 if (cnst && ((INTVAL (src) & 0xff00) == 0))
5363 output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
5366 output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
5367 output_asm_insn (AS2 (mov, %B0, %2), operands);
5369 if (cnst && ((INTVAL (src) & 0xff0000) == 0))
5370 output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
5373 output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
5374 output_asm_insn (AS2 (mov, %C0, %2), operands);
5376 if (cnst && ((INTVAL (src) & 0xff000000) == 0))
5377 output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
5380 output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
5381 output_asm_insn (AS2 (mov, %D0, %2), operands);
5387 avr_output_bld (operands, bit_nr)
5391 static char s[] = "bld %A0,0";
5393 s[5] = 'A' + (bit_nr >> 3);
5394 s[8] = '0' + (bit_nr & 7);
5395 output_asm_insn (s, operands);
5399 avr_output_addr_vec_elt (stream, value)
5404 fprintf (stream, "\t.word pm(.L%d)\n", value);
5406 fprintf (stream, "\trjmp .L%d\n", value);
5411 /* Returns 1 if SCRATCH are safe to be allocated as a scratch
5412 registers (for a define_peephole2) in the current function. */
5415 avr_peep2_scratch_safe (scratch)
5418 if ((interrupt_function_p (current_function_decl)
5419 || signal_function_p (current_function_decl))
5420 && leaf_function_p ())
5422 int first_reg = true_regnum (scratch);
5423 int last_reg = first_reg + GET_MODE_SIZE (GET_MODE (scratch)) - 1;
5426 for (reg = first_reg; reg <= last_reg; reg++)
5428 if (!regs_ever_live[reg])