1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2 Copyright (C) 1998, 1999, 2000 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"
30 #include "insn-flags.h"
32 #include "insn-attr.h"
43 /* Maximal allowed offset for an address in the LD command */
44 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
46 static int avr_naked_function_p PARAMS ((tree));
47 static int interrupt_function_p PARAMS ((tree));
48 static int signal_function_p PARAMS ((tree));
49 static int sequent_regs_live PARAMS ((void));
50 static const char * ptrreg_to_str PARAMS ((int));
51 static const char * cond_string PARAMS ((enum rtx_code));
52 static int avr_num_arg_regs PARAMS ((enum machine_mode, tree));
53 static int out_adj_frame_ptr PARAMS ((FILE *, int));
54 static int out_set_stack_ptr PARAMS ((FILE *, int, int));
55 static int reg_was_0 PARAMS ((rtx insn, rtx op));
56 static int io_address_p PARAMS ((rtx x, int size));
57 void debug_hard_reg_set PARAMS ((HARD_REG_SET set));
59 /* Allocate registers from r25 to r8 for parameters for function calls */
60 #define FIRST_CUM_REG 26
62 /* Temporary register RTX (gen_rtx (REG,QImode,TMP_REGNO)) */
65 /* Zeroed register RTX (gen_rtx (REG,QImode,ZERO_REGNO)) */
68 /* RTX for register which will be used for loading immediate values to
72 /* AVR register names {"r0", "r1", ..., "r31"} */
73 const char * avr_regnames[] = REGISTER_NAMES;
75 /* This holds the last insn address. */
76 static int last_insn_address = 0;
78 /* Commands count in the compiled file */
79 static int commands_in_file;
81 /* Commands in the functions prologues in the compiled file */
82 static int commands_in_prologues;
84 /* Commands in the functions epilogues in the compiled file */
85 static int commands_in_epilogues;
87 /* Prologue/Epilogue size in words */
88 static int prologue_size;
89 static int epilogue_size;
91 /* Initial stack value specified by the `-minit-stack=' option */
92 const char *avr_init_stack = "__stack";
94 /* Default MCU name */
95 const char *avr_mcu_name = "avr2";
97 /* More than 8K of program memory: use "call" and "jmp". */
100 /* Enhanced core: use "movw", "mul", ... */
101 int avr_enhanced_p = 0;
116 /* List of all known AVR MCU types - if updated, it has to be kept
117 in sync in several places (FIXME: is there a better way?):
119 - avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
120 - t-avr (MULTILIB_MATCHES)
121 - gas/config/tc-avr.c
124 static const struct mcu_type_s avr_mcu_types[] = {
125 /* Classic, <= 8K. */
127 { "at90s2313", AVR2 },
128 { "at90s2323", AVR2 },
129 { "attiny22", AVR2 },
130 { "at90s2333", AVR2 },
131 { "at90s2343", AVR2 },
132 { "at90s4414", AVR2 },
133 { "at90s4433", AVR2 },
134 { "at90s4434", AVR2 },
135 { "at90s8515", AVR2 },
136 { "at90c8534", AVR2 },
137 { "at90s8535", AVR2 },
140 { "atmega103", AVR3 },
141 { "atmega603", AVR3 },
142 /* Enhanced, <= 8K. */
144 { "atmega83", AVR4 },
145 { "atmega85", AVR4 },
146 /* Enhanced, > 8K. */
148 { "atmega161", AVR5 },
149 { "atmega163", AVR5 },
150 { "atmega32", AVR5 },
152 /* Assembler only. */
154 { "at90s1200", AVR1 },
155 { "attiny10", AVR1 },
156 { "attiny11", AVR1 },
157 { "attiny12", AVR1 },
158 { "attiny15", AVR1 },
159 { "attiny28", AVR1 },
164 avr_override_options ()
166 const struct mcu_type_s *t;
168 for (t = avr_mcu_types; t->name; t++)
169 if (strcmp (t->name, avr_mcu_name) == 0)
174 fprintf (stderr, "Unknown MCU `%s' specified\nKnown MCU names:\n",
176 for (t = avr_mcu_types; t->name; t++)
177 fprintf (stderr," %s\n", t->name);
178 fatal ("select right MCU name");
185 fatal ("MCU `%s' not supported", avr_mcu_name);
186 case AVR2: avr_enhanced_p = 0; avr_mega_p = 0; break;
187 case AVR3: avr_enhanced_p = 0; avr_mega_p = 1; break;
188 case AVR4: avr_enhanced_p = 1; avr_mega_p = 0; break;
189 case AVR5: avr_enhanced_p = 1; avr_mega_p = 1; break;
194 /* Initialize TMP_REG_RTX and ZERO_REG_RTX */
198 tmp_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
199 memset (tmp_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
200 PUT_CODE (tmp_reg_rtx, REG);
201 PUT_MODE (tmp_reg_rtx, QImode);
202 XINT (tmp_reg_rtx, 0) = TMP_REGNO;
204 zero_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
205 memset (zero_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
206 PUT_CODE (zero_reg_rtx, REG);
207 PUT_MODE (zero_reg_rtx, QImode);
208 XINT (zero_reg_rtx, 0) = ZERO_REGNO;
210 ldi_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
211 memset (ldi_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
212 PUT_CODE (ldi_reg_rtx, REG);
213 PUT_MODE (ldi_reg_rtx, QImode);
214 XINT (ldi_reg_rtx, 0) = LDI_REG_REGNO;
217 /* return register class from register number */
219 static int reg_class_tab[]={
220 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
221 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
222 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
223 GENERAL_REGS, /* r0 - r15 */
224 LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
225 LD_REGS, /* r16 - 23 */
226 ADDW_REGS,ADDW_REGS, /* r24,r25 */
227 POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
228 POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
229 POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
230 STACK_REG,STACK_REG /* SPL,SPH */
233 /* Return register class for register R */
236 avr_regno_reg_class (r)
240 return reg_class_tab[r];
245 /* A C expression which defines the machine-dependent operand
246 constraint letters for register classes. If C is such a
247 letter, the value should be the register class corresponding to
248 it. Otherwise, the value should be `NO_REGS'. The register
249 letter `r', corresponding to class `GENERAL_REGS', will not be
250 passed to this macro; you do not need to handle it. */
253 avr_reg_class_from_letter (c)
258 case 't' : return R0_REG;
259 case 'b' : return BASE_POINTER_REGS;
260 case 'e' : return POINTER_REGS;
261 case 'w' : return ADDW_REGS;
262 case 'd' : return LD_REGS;
263 case 'l' : return NO_LD_REGS;
264 case 'a' : return SIMPLE_LD_REGS;
265 case 'x' : return POINTER_X_REGS;
266 case 'y' : return POINTER_Y_REGS;
267 case 'z' : return POINTER_Z_REGS;
268 case 'q' : return STACK_REG;
274 /* Return non-zero if FUNC is a naked function. */
277 avr_naked_function_p (func)
282 if (TREE_CODE (func) != FUNCTION_DECL)
285 a = lookup_attribute ("naked", DECL_MACHINE_ATTRIBUTES (func));
286 return a != NULL_TREE;
289 /* Return nonzero if FUNC is an interrupt function as specified
290 by the "interrupt" attribute. */
293 interrupt_function_p (func)
298 if (TREE_CODE (func) != FUNCTION_DECL)
301 a = lookup_attribute ("interrupt", DECL_MACHINE_ATTRIBUTES (func));
302 return a != NULL_TREE;
305 /* Return nonzero if FUNC is a signal function as specified
306 by the "signal" attribute. */
309 signal_function_p (func)
314 if (TREE_CODE (func) != FUNCTION_DECL)
317 a = lookup_attribute ("signal", DECL_MACHINE_ATTRIBUTES (func));
318 return a != NULL_TREE;
321 /* Compute offset between arg_pointer and frame_pointer */
324 initial_elimination_offset (from, to)
329 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
333 int interrupt_func_p = interrupt_function_p (current_function_decl);
334 int signal_func_p = signal_function_p (current_function_decl);
335 int leaf_func_p = leaf_function_p ();
336 int offset= frame_pointer_needed ? 2 : 0;
338 for (reg = 0; reg < 32; ++reg)
340 if ((!leaf_func_p && (call_used_regs[reg]
341 && (interrupt_func_p || signal_func_p)))
342 || (regs_ever_live[reg]
343 && (!call_used_regs[reg] || interrupt_func_p || signal_func_p)
344 && ! (frame_pointer_needed
345 && (reg == REG_Y || reg == (REG_Y+1)))))
350 return get_frame_size () + 2 + 1 + offset;
355 /* This function checks sequence of live registers */
364 for (reg = 0; reg < 18; ++reg)
366 if (!call_used_regs[reg])
368 if (regs_ever_live[reg])
378 if (!frame_pointer_needed)
380 if (regs_ever_live[REG_Y])
388 if (regs_ever_live[REG_Y+1])
401 return (cur_seq == live_seq) ? live_seq : 0;
405 /* Output to FILE the asm instructions to adjust the frame pointer by
406 ADJ (r29:r28 -= ADJ;) which can be positive (prologue) or negative
407 (epilogue). Returns the number of instructions generated. */
410 out_adj_frame_ptr (file, adj)
418 if (TARGET_TINY_STACK)
420 if (adj < -63 || adj > 63)
421 warning ("large frame pointer change (%d) with -mtiny-stack", adj);
423 /* The high byte (r29) doesn't change - prefer "subi" (1 cycle)
424 over "sbiw" (2 cycles, same size). */
426 fprintf (file, (AS2 (subi, r28, %d) CR_TAB), adj);
429 else if (adj < -63 || adj > 63)
431 fprintf (file, (AS2 (subi, r28, lo8(%d)) CR_TAB
432 AS2 (sbci, r29, hi8(%d)) CR_TAB),
438 fprintf (file, (AS2 (adiw, r28, %d) CR_TAB), -adj);
443 fprintf (file, (AS2 (sbiw, r28, %d) CR_TAB), adj);
451 /* Output to FILE the asm instructions to copy r29:r28 to SPH:SPL,
452 handling various cases of interrupt enable flag state BEFORE and AFTER
453 (0=disabled, 1=enabled, -1=unknown/unchanged) and target_flags.
454 Returns the number of instructions generated. */
457 out_set_stack_ptr (file, before, after)
462 int do_sph, do_cli, do_save, do_sei, lock_sph, size;
464 /* The logic here is so that -mno-interrupts actually means
465 "it is safe to write SPH in one instruction, then SPL in the
466 next instruction, without disabling interrupts first".
467 The after != -1 case (interrupt/signal) is not affected. */
469 do_sph = !TARGET_TINY_STACK;
470 lock_sph = do_sph && !TARGET_NO_INTERRUPTS;
471 do_cli = (before != 0 && (after == 0 || lock_sph));
472 do_save = (do_cli && before == -1 && after == -1);
473 do_sei = ((do_cli || before != 1) && after == 1);
478 fprintf (file, AS2 (in, __tmp_reg__, __SREG__) CR_TAB);
484 fprintf (file, "cli" CR_TAB);
488 /* Do SPH first - maybe this will disable interrupts for one instruction
489 someday (a suggestion has been sent to avr@atmel.com for consideration
490 in future devices - that would make -mno-interrupts always safe). */
493 fprintf (file, AS2 (out, __SP_H__, r29) CR_TAB);
497 /* Set/restore the I flag now - interrupts will be really enabled only
498 after the next instruction starts. This was not clearly documented.
499 XXX - verify this on the new devices with enhanced AVR core. */
502 fprintf (file, AS2 (out, __SREG__, __tmp_reg__) CR_TAB);
507 fprintf (file, "sei" CR_TAB);
511 fprintf (file, AS2 (out, __SP_L__, r28) "\n");
517 /* Output function prologue */
520 function_prologue (file, size)
525 int interrupt_func_p;
532 if (avr_naked_function_p (current_function_decl))
534 fprintf (file, "/* prologue: naked */\n");
538 interrupt_func_p = interrupt_function_p (current_function_decl);
539 signal_func_p = signal_function_p (current_function_decl);
540 leaf_func_p = leaf_function_p ();
541 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
542 live_seq = sequent_regs_live ();
543 minimize = (TARGET_CALL_PROLOGUES
544 && !interrupt_func_p && !signal_func_p && live_seq);
546 last_insn_address = 0;
548 fprintf (file, "/* prologue: frame size=%d */\n", size);
550 if (interrupt_func_p)
552 fprintf (file,"\tsei\n");
555 if (interrupt_func_p | signal_func_p)
558 AS1 (push,__zero_reg__) CR_TAB
559 AS1 (push,__tmp_reg__) CR_TAB
560 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
561 AS1 (push,__tmp_reg__) CR_TAB
562 AS1 (clr,__zero_reg__) "\n");
568 AS2 (ldi,r28,lo8(%s - %d)) CR_TAB
569 AS2 (ldi,r29,hi8(%s - %d)) CR_TAB
570 AS2 (out,__SP_H__,r29) CR_TAB
571 AS2 (out,__SP_L__,r28) "\n"),
572 avr_init_stack, size, avr_init_stack, size);
576 else if (minimize && (frame_pointer_needed || live_seq > 6))
579 AS2 (ldi, r26, lo8(%d)) CR_TAB
580 AS2 (ldi, r27, hi8(%d)) CR_TAB), size, size);
582 fprintf (file, (AS2 (ldi, r30, pm_lo8(.L_%s_body)) CR_TAB
583 AS2 (ldi, r31, pm_hi8(.L_%s_body)) CR_TAB)
584 ,current_function_name, current_function_name);
590 fprintf (file, AS1 (jmp,__prologue_saves__+%d) "\n",
591 (18 - live_seq) * 2);
596 fprintf (file, AS1 (rjmp,__prologue_saves__+%d) "\n",
597 (18 - live_seq) * 2);
600 fprintf (file, ".L_%s_body:\n", current_function_name);
604 for (reg = 0; reg < 32; ++reg)
607 && (call_used_regs[reg]
608 && (interrupt_func_p || signal_func_p)
609 && !(reg == TMP_REGNO || reg == ZERO_REGNO)))
610 || (regs_ever_live[reg]
611 && (!call_used_regs[reg]
612 || interrupt_func_p || signal_func_p)
613 && ! (frame_pointer_needed
614 && (reg == REG_Y || reg == (REG_Y+1)))))
616 fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
620 if (frame_pointer_needed)
624 AS1 (push,r28) CR_TAB
625 AS1 (push,r29) CR_TAB
626 AS2 (in,r28,__SP_L__) CR_TAB
627 AS2 (in,r29,__SP_H__) "\n");
632 prologue_size += out_adj_frame_ptr (file, size);
634 if (interrupt_func_p)
636 prologue_size += out_set_stack_ptr (file, 1, 1);
638 else if (signal_func_p)
640 prologue_size += out_set_stack_ptr (file, 0, 0);
644 prologue_size += out_set_stack_ptr (file, -1, -1);
650 fprintf (file, "/* prologue end (size=%d) */\n", prologue_size);
653 /* Output function epilogue */
656 function_epilogue (file, size)
661 int interrupt_func_p;
669 if (avr_naked_function_p (current_function_decl))
671 fprintf (file, "/* epilogue: naked */\n");
675 interrupt_func_p = interrupt_function_p (current_function_decl);
676 signal_func_p = signal_function_p (current_function_decl);
677 leaf_func_p = leaf_function_p ();
678 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
679 function_size = (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
680 - INSN_ADDRESSES (INSN_UID (get_insns ())));
681 live_seq = sequent_regs_live ();
682 minimize = (TARGET_CALL_PROLOGUES
683 && !interrupt_func_p && !signal_func_p && live_seq);
686 fprintf (file, "/* epilogue: frame size=%d */\n", size);
689 fprintf (file, "__stop_progIi__:\n\trjmp __stop_progIi__\n");
692 else if (minimize && (frame_pointer_needed || live_seq > 4))
694 fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
696 if (frame_pointer_needed)
698 epilogue_size += out_adj_frame_ptr (file, -size);
702 fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
703 AS2 (in , r29, __SP_H__) CR_TAB));
709 fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
710 (18 - live_seq) * 2);
715 fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
716 (18 - live_seq) * 2);
722 if (frame_pointer_needed)
727 epilogue_size += out_adj_frame_ptr (file, -size);
729 if (interrupt_func_p | signal_func_p)
731 epilogue_size += out_set_stack_ptr (file, -1, 0);
735 epilogue_size += out_set_stack_ptr (file, -1, -1);
744 for (reg = 31; reg >= 0; --reg)
747 && (call_used_regs[reg]
748 && (interrupt_func_p || signal_func_p)
749 && !(reg == TMP_REGNO || reg == ZERO_REGNO)))
750 || (regs_ever_live[reg]
751 && (!call_used_regs[reg]
752 || interrupt_func_p || signal_func_p)
753 && ! (frame_pointer_needed
754 && (reg == REG_Y || reg == (REG_Y+1)))))
756 fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
761 if (interrupt_func_p | signal_func_p)
764 AS1 (pop,__tmp_reg__) CR_TAB
765 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
766 AS1 (pop,__tmp_reg__) CR_TAB
767 AS1 (pop,__zero_reg__) "\n");
769 fprintf (file, "\treti\n");
772 fprintf (file, "\tret\n");
776 fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
777 fprintf (file, "/* function %s size %d (%d) */\n", current_function_name,
778 prologue_size + function_size + epilogue_size, function_size);
779 commands_in_file += prologue_size + function_size + epilogue_size;
780 commands_in_prologues += prologue_size;
781 commands_in_epilogues += epilogue_size;
785 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
786 machine for a memory operand of mode MODE. */
789 legitimate_address_p (mode, x, strict)
790 enum machine_mode mode;
795 if (TARGET_ALL_DEBUG)
797 fprintf (stderr, "mode: (%s) %s %s %s %s:",
799 strict ? "(strict)": "",
800 reload_completed ? "(reload_completed)": "",
801 reload_in_progress ? "(reload_in_progress)": "",
802 reg_renumber ? "(reg_renumber)" : "");
803 if (GET_CODE (x) == PLUS
804 && REG_P (XEXP (x, 0))
805 && GET_CODE (XEXP (x, 1)) == CONST_INT
806 && INTVAL (XEXP (x, 1)) >= 0
807 && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
810 fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
811 true_regnum (XEXP (x, 0)));
814 if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
815 : REG_OK_FOR_BASE_NOSTRICT_P (x)))
817 else if (CONSTANT_ADDRESS_P (x))
819 else if (GET_CODE (x) == PLUS
820 && REG_P (XEXP (x, 0))
821 && GET_CODE (XEXP (x, 1)) == CONST_INT
822 && INTVAL (XEXP (x, 1)) >= 0)
824 int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
828 || REGNO (XEXP (x,0)) == REG_Y
829 || REGNO (XEXP (x,0)) == REG_Z)
831 if (XEXP (x,0) == frame_pointer_rtx
832 || XEXP (x,0) == arg_pointer_rtx)
835 else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
838 else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
839 && REG_P (XEXP (x, 0))
840 && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
841 : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
845 if (TARGET_ALL_DEBUG)
847 fprintf (stderr, " ret = %c\n", r);
852 /* Attempts to replace X with a valid
853 memory address for an operand of mode MODE */
856 legitimize_address (x, oldx, mode)
859 enum machine_mode mode;
862 if (TARGET_ALL_DEBUG)
864 fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
868 if (GET_CODE (oldx) == PLUS
869 && REG_P (XEXP (oldx,0)))
871 if (REG_P (XEXP (oldx,1)))
872 x = force_reg (GET_MODE (oldx), oldx);
873 else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
875 int offs = INTVAL (XEXP (oldx,1));
876 if (frame_pointer_rtx != XEXP (oldx,0))
877 if (offs > MAX_LD_OFFSET (mode))
879 if (TARGET_ALL_DEBUG)
880 fprintf (stderr, "force_reg (big offset)\n");
881 x = force_reg (GET_MODE (oldx), oldx);
889 /* Return a pointer register name as a string */
892 ptrreg_to_str (regno)
897 case REG_X: return "X";
898 case REG_Y: return "Y";
899 case REG_Z: return "Z";
901 fatal ("register r%d isn't a pointer\n", regno);
906 /* Return the condition name as a string.
907 Used in conditional jump constructing */
920 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
925 fatal ("Internal compiler bug: command `bgt'");
927 fatal ("Internal compiler bug: command `ble'");
929 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
936 fatal ("Internal compiler bug: command `bgtu'");
938 fatal ("Internal compiler bug: command `bleu'");
946 /* Output ADDR to FILE as address */
949 print_operand_address (file, addr)
953 switch (GET_CODE (addr))
956 fprintf (file, ptrreg_to_str (REGNO (addr)));
960 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
964 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
968 if (CONSTANT_ADDRESS_P (addr)
969 && (SYMBOL_REF_FLAG (addr) || GET_CODE (addr) == LABEL_REF))
971 fprintf (file, "pm(");
972 output_addr_const (file,addr);
976 output_addr_const (file, addr);
981 /* Output X as assembler operand to file FILE */
984 print_operand (file, x, code)
991 if (code >= 'A' && code <= 'D')
996 if (x == zero_reg_rtx)
997 fprintf (file,"__zero_reg__");
999 fprintf (file, reg_names[true_regnum (x) + abcd]);
1001 else if (GET_CODE (x) == CONST_INT)
1002 fprintf (file, "%d", INTVAL (x) + abcd);
1003 else if (GET_CODE (x) == MEM)
1005 rtx addr = XEXP (x,0);
1007 if (CONSTANT_P (addr) && abcd)
1010 output_address (addr);
1011 fprintf (file, ")+%d", abcd);
1013 else if (GET_CODE (addr) == PLUS)
1015 print_operand_address (file, XEXP (addr,0));
1016 if (REGNO (XEXP (addr, 0)) == REG_X)
1017 fatal_insn ("Internal compiler bug.\nBad address:"
1020 print_operand (file, XEXP (addr,1), code);
1023 print_operand_address (file, addr);
1025 else if (GET_CODE (x) == CONST_DOUBLE)
1029 if (GET_MODE (x) != SFmode)
1030 fatal_insn ("Internal compiler bug. Unknown mode:", x);
1031 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1032 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1033 asm_fprintf (file, "0x%lx", val);
1035 else if (code == 'j')
1036 asm_fprintf (file, cond_string (GET_CODE (x)));
1037 else if (code == 'k')
1038 asm_fprintf (file, cond_string (reverse_condition (GET_CODE (x))));
1040 print_operand_address (file, x);
1043 /* Recognize operand OP of mode MODE used in call instructions */
1046 call_insn_operand (op, mode)
1048 enum machine_mode mode ATTRIBUTE_UNUSED;
1050 if (GET_CODE (op) == MEM)
1052 rtx inside = XEXP (op, 0);
1053 if (register_operand (inside, Pmode))
1055 if (CONSTANT_ADDRESS_P (inside))
1061 /* Update the condition code in the INSN. */
1064 notice_update_cc (body, insn)
1065 rtx body ATTRIBUTE_UNUSED;
1070 switch (get_attr_cc (insn))
1073 /* Insn does not affect CC at all. */
1081 set = single_set (insn);
1085 cc_status.flags |= CC_NO_OVERFLOW;
1086 cc_status.value1 = SET_DEST (set);
1091 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1092 The V flag may or may not be known but that's ok because
1093 alter_cond will change tests to use EQ/NE. */
1094 set = single_set (insn);
1098 cc_status.value1 = SET_DEST (set);
1099 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1104 set = single_set (insn);
1107 cc_status.value1 = SET_SRC (set);
1111 /* Insn doesn't leave CC in a usable state. */
1114 /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1115 set = single_set (insn);
1118 rtx src = SET_SRC (set);
1120 if (GET_CODE (src) == ASHIFTRT
1121 && GET_MODE (src) == QImode)
1123 rtx x = XEXP (src, 1);
1125 if (GET_CODE (x) == CONST_INT
1128 cc_status.value1 = SET_DEST (set);
1129 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1137 /* Return maximum number of consecutive registers of
1138 class CLASS needed to hold a value of mode MODE. */
1141 class_max_nregs (class, mode)
1142 enum reg_class class ATTRIBUTE_UNUSED;
1143 enum machine_mode mode;
1145 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1148 /* Choose mode for jump insn:
1149 1 - relative jump in range -63 <= x <= 62 ;
1150 2 - relative jump in range -2046 <= x <= 2045 ;
1151 3 - absolute jump (only for ATmega[16]03). */
1154 avr_jump_mode (x, insn)
1155 rtx x; /* jump operand */
1156 rtx insn; /* jump insn */
1158 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1159 ? XEXP (x, 0) : x));
1160 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1161 int jump_distance = cur_addr - dest_addr;
1163 if (-63 <= jump_distance && jump_distance <= 62)
1165 else if (-2046 <= jump_distance && jump_distance <= 2045)
1173 /* return a AVR condition jump commands.
1174 LEN is a number returned by avr_jump_mode function. */
1177 ret_cond_branch (cond, len)
1184 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1185 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1187 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1188 AS1 (brmi,_PC_+2) CR_TAB
1190 (AS1 (breq,_PC_+6) CR_TAB
1191 AS1 (brmi,_PC_+4) CR_TAB
1195 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1197 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1198 AS1 (brlt,_PC_+2) CR_TAB
1200 (AS1 (breq,_PC_+6) CR_TAB
1201 AS1 (brlt,_PC_+4) CR_TAB
1204 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1206 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1207 AS1 (brlo,_PC_+2) CR_TAB
1209 (AS1 (breq,_PC_+6) CR_TAB
1210 AS1 (brlo,_PC_+4) CR_TAB
1213 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1214 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1216 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1217 AS1 (brpl,_PC_+2) CR_TAB
1219 (AS1 (breq,_PC_+2) CR_TAB
1220 AS1 (brpl,_PC_+4) CR_TAB
1223 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1225 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1226 AS1 (brge,_PC_+2) CR_TAB
1228 (AS1 (breq,_PC_+2) CR_TAB
1229 AS1 (brge,_PC_+4) CR_TAB
1232 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1234 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1235 AS1 (brsh,_PC_+2) CR_TAB
1237 (AS1 (breq,_PC_+2) CR_TAB
1238 AS1 (brsh,_PC_+4) CR_TAB
1244 return AS1 (br%j1,%0);
1246 return (AS1 (br%k1,_PC_+2) CR_TAB
1249 return (AS1 (br%k1,_PC_+4) CR_TAB
1256 /* Predicate function for immediate operand which fits to byte (8bit) */
1259 byte_immediate_operand (op, mode)
1261 enum machine_mode mode ATTRIBUTE_UNUSED;
1263 return (GET_CODE (op) == CONST_INT
1264 && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1267 /* Output all insn addresses and their sizes into the assembly language
1268 output file. This is helpful for debugging whether the length attributes
1269 in the md file are correct.
1270 Output insn cost for next insn. */
1273 final_prescan_insn (insn, operand, num_operands)
1274 rtx insn, *operand ATTRIBUTE_UNUSED;
1275 int num_operands ATTRIBUTE_UNUSED;
1277 int uid = INSN_UID (insn);
1279 if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1281 fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1282 INSN_ADDRESSES (uid),
1283 INSN_ADDRESSES (uid) - last_insn_address,
1284 rtx_cost (PATTERN (insn), INSN));
1286 last_insn_address = INSN_ADDRESSES (uid);
1288 if (TARGET_RTL_DUMP)
1290 fprintf (asm_out_file, "/*****************\n");
1291 print_rtl_single (asm_out_file, insn);
1292 fprintf (asm_out_file, "*****************/\n");
1296 /* Return 0 if undefined, 1 if always true or always false. */
1299 avr_simplify_comparision_p (mode, operator, x)
1300 enum machine_mode mode;
1304 unsigned int max = (mode == QImode ? 0xff :
1305 mode == HImode ? 0xffff :
1306 mode == SImode ? 0xffffffffU : 0);
1307 if (max && operator && GET_CODE (x) == CONST_INT)
1309 if (unsigned_condition (operator) != operator)
1312 if (max != (INTVAL (x) & max)
1313 && INTVAL (x) != 0xff)
1320 /* Returns nonzero if REGNO is the number of a hard
1321 register in which function arguments are sometimes passed. */
1324 function_arg_regno_p(r)
1327 return (r >= 8 && r <= 25);
1330 /* Initializing the variable cum for the state at the beginning
1331 of the argument list. */
1334 init_cumulative_args (cum, fntype, libname, indirect)
1335 CUMULATIVE_ARGS *cum;
1338 int indirect ATTRIBUTE_UNUSED;
1341 cum->regno = FIRST_CUM_REG;
1344 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1345 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1346 != void_type_node));
1352 /* Returns the number of registers to allocate for a function argument. */
1355 avr_num_arg_regs (mode, type)
1356 enum machine_mode mode;
1361 if (mode == BLKmode)
1362 size = int_size_in_bytes (type);
1364 size = GET_MODE_SIZE (mode);
1366 /* Align all function arguments to start in even-numbered registers,
1367 for "movw" on the enhanced core (to keep call conventions the same
1368 on all devices, do it even if "movw" is not available). Odd-sized
1369 arguments leave holes above them - registers still available for
1370 other uses. Use -mpack-args for compatibility with old asm code
1371 (the new convention will still be used for libgcc calls). */
1373 if (!(type && TARGET_PACK_ARGS))
1379 /* Controls whether a function argument is passed
1380 in a register, and which register. */
1383 function_arg (cum, mode, type, named)
1384 CUMULATIVE_ARGS *cum;
1385 enum machine_mode mode;
1387 int named ATTRIBUTE_UNUSED;
1389 int bytes = avr_num_arg_regs (mode, type);
1391 if (cum->nregs && bytes <= cum->nregs)
1392 return gen_rtx (REG, mode, cum->regno - bytes);
1397 /* Update the summarizer variable CUM to advance past an argument
1398 in the argument list. */
1401 function_arg_advance (cum, mode, type, named)
1402 CUMULATIVE_ARGS *cum; /* current arg information */
1403 enum machine_mode mode; /* current arg mode */
1404 tree type; /* type of the argument or 0 if lib support */
1405 int named ATTRIBUTE_UNUSED; /* whether or not the argument was named */
1407 int bytes = avr_num_arg_regs (mode, type);
1409 cum->nregs -= bytes;
1410 cum->regno -= bytes;
1412 if (cum->nregs <= 0)
1415 cum->regno = FIRST_CUM_REG;
1419 /***********************************************************************
1420 Functions for outputting various mov's for a various modes
1421 ************************************************************************/
1423 output_movqi (insn, operands, l)
1429 rtx dest = operands[0];
1430 rtx src = operands[1];
1438 if (register_operand (dest, QImode))
1440 if (register_operand (src, QImode)) /* mov r,r */
1442 if (test_hard_reg_class (STACK_REG, dest))
1443 return AS2 (out,%0,%1);
1444 else if (test_hard_reg_class (STACK_REG, src))
1445 return AS2 (in,%0,%1);
1447 return AS2 (mov,%0,%1);
1449 else if (CONSTANT_P (src))
1451 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1452 return AS2 (ldi,%0,lo8(%1));
1454 if (GET_CODE (src) == CONST_INT)
1456 if (src == const0_rtx) /* mov r,L */
1457 return AS1 (clr,%0);
1458 else if (src == const1_rtx)
1460 if (reg_was_0 (insn, dest))
1461 return AS1 (inc,%0 ; reg_was_0);
1464 return (AS1 (clr,%0) CR_TAB
1467 else if (src == const2_rtx)
1469 if (reg_was_0 (insn, dest))
1472 return (AS1 (inc,%0 ; reg_was_0) CR_TAB
1477 return (AS1 (clr,%0) CR_TAB
1481 else if (src == constm1_rtx)
1483 /* Immediate constants -1 to any register */
1484 if (reg_was_0 (insn, dest))
1485 return AS1 (dec,%0 ; reg_was_0);
1488 return (AS1 (clr,%0) CR_TAB
1494 /* Last resort, larger than loading from memory. */
1496 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1497 AS2 (ldi,r31,lo8(%1)) CR_TAB
1498 AS2 (mov,%0,r31) CR_TAB
1499 AS2 (mov,r31,__tmp_reg__));
1501 else if (GET_CODE (src) == MEM)
1502 return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1504 else if (GET_CODE (dest) == MEM)
1506 const char *template;
1508 if (src == const0_rtx)
1509 operands[1] = zero_reg_rtx;
1511 template = out_movqi_mr_r (insn, operands, real_l);
1514 output_asm_insn (template, operands);
1523 output_movhi (insn, operands, l)
1529 rtx dest = operands[0];
1530 rtx src = operands[1];
1536 if (register_operand (dest, HImode))
1538 if (register_operand (src, HImode)) /* mov r,r */
1540 if (test_hard_reg_class (STACK_REG, dest))
1542 if (TARGET_TINY_STACK)
1545 return AS2 (out,__SP_L__,%A1);
1547 else if (TARGET_NO_INTERRUPTS)
1550 return (AS2 (out,__SP_H__,%B1) CR_TAB
1551 AS2 (out,__SP_L__,%A1));
1555 return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB
1557 AS2 (out,__SP_H__,%B1) CR_TAB
1558 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1559 AS2 (out,__SP_L__,%A1));
1561 else if (test_hard_reg_class (STACK_REG, src))
1564 return (AS2 (in,%A0,__SP_L__) CR_TAB
1565 AS2 (in,%B0,__SP_H__));
1571 return (AS2 (movw,%0,%1));
1574 if (true_regnum (dest) > true_regnum (src))
1577 return (AS2 (mov,%B0,%B1) CR_TAB
1583 return (AS2 (mov,%A0,%A1) CR_TAB
1587 else if (CONSTANT_P (src))
1589 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1591 if (byte_immediate_operand (src, HImode)
1592 && reg_was_0 (insn, dest))
1595 return (AS2 (ldi,%A0,lo8(%1) ; reg_was_0));
1599 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1600 AS2 (ldi,%B0,hi8(%1)));
1603 if (GET_CODE (src) == CONST_INT)
1605 if (src == const0_rtx) /* mov r,L */
1608 return (AS1 (clr,%A0) CR_TAB
1611 else if (src == const1_rtx)
1613 if (reg_was_0 (insn, dest))
1616 return AS1 (inc,%0 ; reg_was_0);
1620 return (AS1 (clr,%0) CR_TAB
1623 else if (src == const2_rtx)
1625 if (reg_was_0 (insn, dest))
1628 return (AS1 (inc,%0 ; reg_was_0) CR_TAB
1633 return (AS1 (clr,%0) CR_TAB
1637 else if (src == constm1_rtx)
1639 /* Immediate constants -1 to any register */
1640 if (reg_was_0 (insn, dest))
1643 return (AS1 (dec,%A0 ; reg_was_0) CR_TAB
1648 return (AS1 (clr,%0) CR_TAB
1649 AS1 (dec,%A0) CR_TAB
1652 if ((INTVAL (src) & 0xff) == 0)
1655 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1656 AS1 (clr,%A0) CR_TAB
1657 AS2 (ldi,r31,hi8(%1)) CR_TAB
1658 AS2 (mov,%B0,r31) CR_TAB
1659 AS2 (mov,r31,__tmp_reg__));
1661 else if ((INTVAL (src) & 0xff00) == 0)
1664 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1665 AS2 (ldi,r31,lo8(%1)) CR_TAB
1666 AS2 (mov,%A0,r31) CR_TAB
1667 AS1 (clr,%B0) CR_TAB
1668 AS2 (mov,r31,__tmp_reg__));
1672 /* Last resort, equal to loading from memory. */
1674 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1675 AS2 (ldi,r31,lo8(%1)) CR_TAB
1676 AS2 (mov,%A0,r31) CR_TAB
1677 AS2 (ldi,r31,hi8(%1)) CR_TAB
1678 AS2 (mov,%B0,r31) CR_TAB
1679 AS2 (mov,r31,__tmp_reg__));
1681 else if (GET_CODE (src) == MEM)
1682 return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1684 else if (GET_CODE (dest) == MEM)
1686 const char *template;
1688 if (src == const0_rtx)
1689 operands[1] = zero_reg_rtx;
1691 template = out_movhi_mr_r (insn, operands, real_l);
1694 output_asm_insn (template, operands);
1699 fatal_insn ("Invalid insn:", insn);
1704 out_movqi_r_mr (insn, op, l)
1707 int *l; /* instruction length */
1711 rtx x = XEXP (src, 0);
1717 if (CONSTANT_ADDRESS_P (x))
1719 if (io_address_p (x, 1))
1722 return AS2 (in,%0,%1-0x20);
1725 return AS2 (lds,%0,%1);
1727 /* memory access by reg+disp */
1728 else if (GET_CODE (x) == PLUS
1729 && REG_P (XEXP (x,0))
1730 && GET_CODE (XEXP (x,1)) == CONST_INT)
1732 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1734 int disp = INTVAL (XEXP (x,1));
1735 if (REGNO (XEXP (x,0)) != REG_Y)
1736 fatal_insn ("Incorrect insn:",insn);
1737 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1740 op[4] = XEXP (x, 1);
1741 return (AS2 (adiw, r28, %4-63) CR_TAB
1742 AS2 (ldd, %0,Y+63) CR_TAB
1743 AS2 (sbiw, r28, %4-63));
1749 return (AS2 (subi, r28, lo8(-%4)) CR_TAB
1750 AS2 (sbci, r29, hi8(-%4)) CR_TAB
1751 AS2 (ld, %0,Y) CR_TAB
1752 AS2 (subi, r28, lo8(%4)) CR_TAB
1753 AS2 (sbci, r29, hi8(%4)));
1756 else if (REGNO (XEXP (x,0)) == REG_X)
1758 op[4] = XEXP (x, 1);
1759 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1760 it but I have this situation with extremal optimizing options. */
1761 if (reg_overlap_mentioned_p (dest, XEXP (x,0))
1762 || reg_unused_after (insn, XEXP (x,0)))
1765 return (AS2 (adiw,r26,%4) CR_TAB
1769 return (AS2 (adiw,r26,%4) CR_TAB
1770 AS2 (ld,%0,X) CR_TAB
1774 return AS2 (ldd,%0,%1);
1777 return AS2 (ld,%0,%1);
1781 out_movhi_r_mr (insn, op, l)
1784 int *l; /* instruction length */
1788 rtx base = XEXP (src, 0);
1789 int reg_dest = true_regnum (dest);
1790 int reg_base = true_regnum (base);
1798 if (reg_dest == reg_base) /* R = (R) */
1801 return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1802 AS2 (ld,%B0,%1) CR_TAB
1803 AS2 (mov,%A0,__tmp_reg__));
1805 else if (reg_base == REG_X) /* (R26) */
1807 if (reg_unused_after (insn, base))
1810 return (AS2 (ld,%A0,X+) CR_TAB
1814 return (AS2 (ld,%A0,X+) CR_TAB
1815 AS2 (ld,%B0,X) CR_TAB
1821 return (AS2 (ld,%A0,%1) CR_TAB
1822 AS2 (ldd,%B0,%1+1));
1825 else if (GET_CODE (base) == PLUS) /* (R + i) */
1827 int disp = INTVAL (XEXP (base, 1));
1828 int reg_base = true_regnum (XEXP (base, 0));
1830 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
1832 op[4] = XEXP (base, 1);
1834 if (REGNO (XEXP (base, 0)) != REG_Y)
1835 fatal_insn ("Incorrect insn:",insn);
1837 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1840 return (AS2 (adiw,r28,%4-62) CR_TAB
1841 AS2 (ldd,%A0,Y+62) CR_TAB
1842 AS2 (ldd,%B0,Y+63) CR_TAB
1843 AS2 (sbiw,r28,%4-62));
1848 return (AS2 (subi,r28,lo8(-%4)) CR_TAB
1849 AS2 (sbci,r29,hi8(-%4)) CR_TAB
1850 AS2 (ld,%A0,Y) CR_TAB
1851 AS2 (ldd,%B0,Y+1) CR_TAB
1852 AS2 (subi,r28,lo8(%4)) CR_TAB
1853 AS2 (sbci,r29,hi8(%4)));
1856 if (reg_base == REG_X)
1858 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1859 it but I have this situation with extremal
1860 optimization options. */
1862 op[4] = XEXP (base, 1);
1864 if (reg_base == reg_dest)
1867 return (AS2 (adiw,r26,%4) CR_TAB
1868 AS2 (ld,__tmp_reg__,X+) CR_TAB
1869 AS2 (ld,%B0,X) CR_TAB
1870 AS2 (mov,%A0,__tmp_reg__));
1873 if (INTVAL (op[4]) == 63)
1876 return (AS2 (adiw,r26,%4) CR_TAB
1877 AS2 (ld,%A0,X+) CR_TAB
1878 AS2 (ld,%B0,X) CR_TAB
1879 AS2 (subi,r26,%4+1) CR_TAB
1883 return (AS2 (adiw,r26,%4) CR_TAB
1884 AS2 (ld,%A0,X+) CR_TAB
1885 AS2 (ld,%B0,X) CR_TAB
1886 AS2 (sbiw,r26,%4+1));
1889 if (reg_base == reg_dest)
1892 return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
1893 AS2 (ldd,%B0,%B1) CR_TAB
1894 AS2 (mov,%A0,__tmp_reg__));
1898 return (AS2 (ldd,%A0,%A1) CR_TAB
1901 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
1903 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1904 fatal_insn ("Incorrect insn:", insn);
1907 return (AS2 (ld,%B0,%1) CR_TAB
1910 else if (GET_CODE (base) == POST_INC) /* (R++) */
1912 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1913 fatal_insn ("Incorrect insn:", insn);
1916 return (AS2 (ld,%A0,%1) CR_TAB
1919 else if (CONSTANT_ADDRESS_P (base))
1921 if (io_address_p (base, 2))
1924 return (AS2 (in,%A0,%A1-0x20) CR_TAB
1925 AS2 (in,%B0,%B1-0x20));
1928 return (AS2 (lds,%A0,%A1) CR_TAB
1932 fatal_insn ("Unknown move insn:",insn);
1937 out_movsi_r_mr (insn, op, l)
1940 int *l; /* instruction length */
1944 rtx base = XEXP (src, 0);
1945 int reg_dest = true_regnum (dest);
1946 int reg_base = true_regnum (base);
1954 if (reg_base == REG_X) /* (R26) */
1956 if (reg_dest == REG_X)
1957 return *l=6, (AS2 (adiw,r26,3) CR_TAB
1958 AS2 (ld,%D0,X) CR_TAB
1959 AS2 (ld,%C0,-X) CR_TAB
1960 AS2 (ld,__tmp_reg__,-X) CR_TAB
1961 AS2 (ld,%A0,-X) CR_TAB
1962 AS2 (mov,%B0,__tmp_reg__));
1963 else if (reg_dest == REG_X - 2)
1964 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
1965 AS2 (ld,%B0,X+) CR_TAB
1966 AS2 (ld,__tmp_reg__,X+) CR_TAB
1967 AS2 (ld,%D0,X) CR_TAB
1968 AS2 (mov,%C0,__tmp_reg__));
1969 else if (reg_unused_after (insn, base))
1970 return *l=4, (AS2 (ld,%A0,X+) CR_TAB
1971 AS2 (ld,%B0,X+) CR_TAB
1972 AS2 (ld,%C0,X+) CR_TAB
1975 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
1976 AS2 (ld,%B0,X+) CR_TAB
1977 AS2 (ld,%C0,X+) CR_TAB
1978 AS2 (ld,%D0,X) CR_TAB
1983 if (reg_dest == reg_base)
1984 return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
1985 AS2 (ldd,%C0,%1+2) CR_TAB
1986 AS2 (ldd,__tmp_reg__,%1+1) CR_TAB
1987 AS2 (ld,%A0,%1) CR_TAB
1988 AS2 (mov,%B0,__tmp_reg__));
1989 else if (reg_base == reg_dest + 2)
1990 return *l=5, (AS2 (ld ,%A0,%1) CR_TAB
1991 AS2 (ldd,%B0,%1+1) CR_TAB
1992 AS2 (ldd,__tmp_reg__,%1+2) CR_TAB
1993 AS2 (ldd,%D0,%1+3) CR_TAB
1994 AS2 (mov,%C0,__tmp_reg__));
1996 return *l=4, (AS2 (ld ,%A0,%1) CR_TAB
1997 AS2 (ldd,%B0,%1+1) CR_TAB
1998 AS2 (ldd,%C0,%1+2) CR_TAB
1999 AS2 (ldd,%D0,%1+3));
2002 else if (GET_CODE (base) == PLUS) /* (R + i) */
2004 int disp = INTVAL (XEXP (base, 1));
2006 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2008 if (REGNO (XEXP (base, 0)) != REG_Y)
2009 fatal_insn ("Incorrect insn:",insn);
2010 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2012 op[4] = GEN_INT (disp - 60);
2013 return *l=6,(AS2 (adiw, r28, %4) CR_TAB
2014 AS2 (ldd, %A0,Y+60) CR_TAB
2015 AS2 (ldd, %B0,Y+61) CR_TAB
2016 AS2 (ldd, %C0,Y+62) CR_TAB
2017 AS2 (ldd, %D0,Y+63) CR_TAB
2018 AS2 (sbiw, r28, %4));
2022 op[4] = XEXP (base, 1);
2023 return *l=8,(AS2 (subi, r28, lo8(-%4)) CR_TAB
2024 AS2 (sbci, r29, hi8(-%4)) CR_TAB
2025 AS2 (ld, %A0,Y) CR_TAB
2026 AS2 (ldd, %B0,Y+1) CR_TAB
2027 AS2 (ldd, %C0,Y+2) CR_TAB
2028 AS2 (ldd, %D0,Y+3) CR_TAB
2029 AS2 (subi, r28, lo8(%4)) CR_TAB
2030 AS2 (sbci, r29, hi8(%4)));
2034 reg_base = true_regnum (XEXP (base, 0));
2035 if (reg_dest == reg_base)
2036 return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2037 AS2 (ldd,%C0,%C1) CR_TAB
2038 AS2 (ldd,__tmp_reg__,%B1) CR_TAB
2039 AS2 (ldd,%A0,%A1) CR_TAB
2040 AS2 (mov,%B0,__tmp_reg__));
2041 else if (reg_dest == reg_base - 2)
2042 return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2043 AS2 (ldd,%B0,%B1) CR_TAB
2044 AS2 (ldd,__tmp_reg__,%C1) CR_TAB
2045 AS2 (ldd,%D0,%D1) CR_TAB
2046 AS2 (mov,%C0,__tmp_reg__));
2047 return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2048 AS2 (ldd,%B0,%B1) CR_TAB
2049 AS2 (ldd,%C0,%C1) CR_TAB
2052 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2053 return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2054 AS2 (ld,%C0,%1) CR_TAB
2055 AS2 (ld,%B0,%1) CR_TAB
2057 else if (GET_CODE (base) == POST_INC) /* (R++) */
2058 return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2059 AS2 (ld,%B0,%1) CR_TAB
2060 AS2 (ld,%C0,%1) CR_TAB
2062 else if (CONSTANT_ADDRESS_P (base))
2063 return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2064 AS2 (lds,%B0,%B1) CR_TAB
2065 AS2 (lds,%C0,%C1) CR_TAB
2068 fatal_insn ("Unknown move insn:",insn);
2073 out_movsi_mr_r (insn, op, l)
2080 rtx base = XEXP (dest, 0);
2081 int reg_base = true_regnum (base);
2082 int reg_src = true_regnum (src);
2088 if (CONSTANT_ADDRESS_P (base))
2089 return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2090 AS2 (sts,%B0,%B1) CR_TAB
2091 AS2 (sts,%C0,%C1) CR_TAB
2093 if (reg_base > 0) /* (r) */
2095 if (reg_base == REG_X) /* (R26) */
2097 if (reg_src == REG_X)
2099 if (reg_unused_after (insn, base))
2100 return *l=5, (AS2 (mov,__tmp_reg__,%B1) CR_TAB
2101 AS2 (st,%0+,%A1) CR_TAB
2102 AS2 (st,%0+,__tmp_reg__) CR_TAB
2103 AS2 (st,%0+,%C1) CR_TAB
2106 return *l=6, (AS2 (mov,__tmp_reg__,%B1) CR_TAB
2107 AS2 (st,%0+,%A1) CR_TAB
2108 AS2 (st,%0+,__tmp_reg__) CR_TAB
2109 AS2 (st,%0+,%C1) CR_TAB
2110 AS2 (st,%0,%D1) CR_TAB
2113 else if (reg_base == reg_src + 2)
2115 if (reg_unused_after (insn, base))
2116 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2117 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2118 AS2 (st,%0+,%A1) CR_TAB
2119 AS2 (st,%0+,%B1) CR_TAB
2120 AS2 (st,%0+,__zero_reg__) CR_TAB
2121 AS2 (st,%0,__tmp_reg__) CR_TAB
2122 AS1 (clr,__zero_reg__));
2124 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2125 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2126 AS2 (st,%0+,%A1) CR_TAB
2127 AS2 (st,%0+,%B1) CR_TAB
2128 AS2 (st,%0+,__zero_reg__) CR_TAB
2129 AS2 (st,%0,__tmp_reg__) CR_TAB
2130 AS1 (clr,__zero_reg__) CR_TAB
2133 return *l=5, (AS2 (st,%0+,%A1) CR_TAB
2134 AS2 (st,%0+,%B1) CR_TAB
2135 AS2 (st,%0+,%C1) CR_TAB
2136 AS2 (st,%0,%D1) CR_TAB
2140 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2141 AS2 (std,%0+1,%B1) CR_TAB
2142 AS2 (std,%0+2,%C1) CR_TAB
2143 AS2 (std,%0+3,%D1));
2145 else if (GET_CODE (base) == PLUS) /* (R + i) */
2147 int disp = INTVAL (XEXP (base, 1));
2148 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2150 if (REGNO (XEXP (base, 0)) != REG_Y)
2151 fatal_insn ("Incorrect insn:",insn);
2152 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2154 op[4] = GEN_INT (disp - 60);
2155 return *l=6,(AS2 (adiw, r28, %4) CR_TAB
2156 AS2 (std, Y+60,%A1) CR_TAB
2157 AS2 (std, Y+61,%B1) CR_TAB
2158 AS2 (std, Y+62,%C1) CR_TAB
2159 AS2 (std, Y+63,%D1) CR_TAB
2160 AS2 (sbiw, r28, %4));
2164 op[4] = XEXP (base, 1);
2165 return *l=8,(AS2 (subi, r28, lo8(-%4)) CR_TAB
2166 AS2 (sbci, r29, hi8(-%4)) CR_TAB
2167 AS2 (st, Y,%A1) CR_TAB
2168 AS2 (std, Y+1,%B1) CR_TAB
2169 AS2 (std, Y+2,%C1) CR_TAB
2170 AS2 (std, Y+3,%D1) CR_TAB
2171 AS2 (subi, r28, lo8(%4)) CR_TAB
2172 AS2 (sbci, r29, hi8(%4)));
2175 return *l=4, (AS2 (std,%A0,%A1) CR_TAB
2176 AS2 (std,%B0,%B1) CR_TAB
2177 AS2 (std,%C0,%C1) CR_TAB
2180 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2181 return *l=4, (AS2 (st,%0,%D1) CR_TAB
2182 AS2 (st,%0,%C1) CR_TAB
2183 AS2 (st,%0,%B1) CR_TAB
2185 else if (GET_CODE (base) == POST_INC) /* (R++) */
2186 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2187 AS2 (st,%0,%B1) CR_TAB
2188 AS2 (st,%0,%C1) CR_TAB
2190 fatal_insn ("Unknown move insn:",insn);
2195 output_movsisf(insn, operands, l)
2201 rtx dest = operands[0];
2202 rtx src = operands[1];
2208 if (register_operand (dest, VOIDmode))
2210 if (register_operand (src, VOIDmode)) /* mov r,r */
2212 if (true_regnum (dest) > true_regnum (src))
2217 return (AS2 (movw,%C0,%C1) CR_TAB
2218 AS2 (movw,%A0,%A1));
2221 return (AS2 (mov,%D0,%D1) CR_TAB
2222 AS2 (mov,%C0,%C1) CR_TAB
2223 AS2 (mov,%B0,%B1) CR_TAB
2231 return (AS2 (movw,%A0,%A1) CR_TAB
2232 AS2 (movw,%C0,%C1));
2235 return (AS2 (mov,%A0,%A1) CR_TAB
2236 AS2 (mov,%B0,%B1) CR_TAB
2237 AS2 (mov,%C0,%C1) CR_TAB
2241 else if (CONSTANT_P (src))
2243 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2245 if (byte_immediate_operand (src, SImode)
2246 && reg_was_0 (insn, dest))
2249 return (AS2 (ldi,%A0,lo8(%1) ; reg_was_0));
2253 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
2254 AS2 (ldi,%B0,hi8(%1)) CR_TAB
2255 AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2256 AS2 (ldi,%D0,hhi8(%1)));
2259 if (GET_CODE (src) == CONST_INT)
2261 if (src == const0_rtx) /* mov r,L */
2266 return (AS1 (clr,%A0) CR_TAB
2267 AS1 (clr,%B0) CR_TAB
2268 AS2 (movw,%C0,%A0));
2271 return (AS1 (clr,%A0) CR_TAB
2272 AS1 (clr,%B0) CR_TAB
2273 AS1 (clr,%C0) CR_TAB
2276 else if (src == const1_rtx)
2278 if (reg_was_0 (insn, dest))
2281 return AS1 (inc,%A0 ; reg_was_0);
2285 return (AS1 (clr,%D0) CR_TAB
2286 AS1 (clr,%B0) CR_TAB
2287 AS1 (clr,%C0) CR_TAB
2290 else if (src == const2_rtx)
2292 if (reg_was_0 (insn, dest))
2295 return (AS1 (inc,%A0 ; reg_was_0) CR_TAB
2302 return (AS1 (clr,%D0) CR_TAB
2303 AS1 (clr,%C0) CR_TAB
2304 AS2 (movw,%A0,%C0) CR_TAB
2305 AS1 (inc,%A0) CR_TAB
2309 return (AS1 (clr,%D0) CR_TAB
2310 AS1 (clr,%B0) CR_TAB
2311 AS1 (clr,%C0) CR_TAB
2312 AS1 (clr,%A0) CR_TAB
2313 AS1 (inc,%A0) CR_TAB
2316 else if (src == constm1_rtx)
2318 /* Immediate constants -1 to any register */
2319 if (reg_was_0 (insn, dest))
2324 return (AS1 (dec,%A0) CR_TAB
2325 AS1 (dec,%B0) CR_TAB
2326 AS2 (movw,%C0,%A0));
2329 return (AS1 (dec,%D0 ; reg_was_0) CR_TAB
2330 AS1 (dec,%C0) CR_TAB
2331 AS1 (dec,%B0) CR_TAB
2337 return (AS1 (clr,%A0) CR_TAB
2338 AS1 (dec,%A0) CR_TAB
2339 AS2 (mov,%B0,%A0) CR_TAB
2340 AS2 (movw,%C0,%A0));
2343 return (AS1 (clr,%A0) CR_TAB
2344 AS1 (dec,%A0) CR_TAB
2345 AS2 (mov,%B0,%A0) CR_TAB
2346 AS2 (mov,%C0,%A0) CR_TAB
2351 /* Last resort, better than loading from memory. */
2353 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2354 AS2 (ldi,r31,lo8(%1)) CR_TAB
2355 AS2 (mov,%A0,r31) CR_TAB
2356 AS2 (ldi,r31,hi8(%1)) CR_TAB
2357 AS2 (mov,%B0,r31) CR_TAB
2358 AS2 (ldi,r31,hlo8(%1)) CR_TAB
2359 AS2 (mov,%C0,r31) CR_TAB
2360 AS2 (ldi,r31,hhi8(%1)) CR_TAB
2361 AS2 (mov,%D0,r31) CR_TAB
2362 AS2 (mov,r31,__tmp_reg__));
2364 else if (GET_CODE (src) == MEM)
2365 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2367 else if (GET_CODE (dest) == MEM)
2369 const char *template;
2371 if (src == const0_rtx)
2372 operands[1] = zero_reg_rtx;
2374 template = out_movsi_mr_r (insn, operands, real_l);
2377 output_asm_insn (template, operands);
2382 fatal_insn ("Invalid insn:", insn);
2387 out_movqi_mr_r (insn, op, l)
2390 int *l; /* instruction length */
2394 rtx x = XEXP (dest, 0);
2400 if (CONSTANT_ADDRESS_P (x))
2402 if (io_address_p (x, 1))
2405 return AS2 (out,%0-0x20,%1);
2408 return AS2 (sts,%0,%1);
2410 /* memory access by reg+disp */
2411 else if (GET_CODE (x) == PLUS
2412 && REG_P (XEXP (x,0))
2413 && GET_CODE (XEXP (x,1)) == CONST_INT)
2415 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2417 int disp = INTVAL (XEXP (x,1));
2418 if (REGNO (XEXP (x,0)) != REG_Y)
2419 fatal_insn ("Incorrect insn:",insn);
2420 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2423 op[4] = XEXP (x, 1);
2424 return (AS2 (adiw, r28, %4-63) CR_TAB
2425 AS2 (std, Y+63,%1) CR_TAB
2426 AS2 (sbiw, r28, %4-63));
2432 return (AS2 (subi, r28, lo8(-%4)) CR_TAB
2433 AS2 (sbci, r29, hi8(-%4)) CR_TAB
2434 AS2 (st, Y,%1) CR_TAB
2435 AS2 (subi, r28, lo8(%4)) CR_TAB
2436 AS2 (sbci, r29, hi8(%4)));
2439 else if (REGNO (XEXP (x,0)) == REG_X)
2442 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2444 if (reg_unused_after (insn, XEXP (x,0)))
2447 return (AS2 (mov,__tmp_reg__,%1) CR_TAB
2448 AS2 (adiw,r26,%4) CR_TAB
2449 AS2 (st,X,__tmp_reg__));
2452 return (AS2 (mov,__tmp_reg__,%1) CR_TAB
2453 AS2 (adiw,r26,%4) CR_TAB
2454 AS2 (st,X,__tmp_reg__) CR_TAB
2459 if (reg_unused_after (insn, XEXP (x,0)))
2462 return (AS2 (adiw,r26,%4) CR_TAB
2466 return (AS2 (adiw,r26,%4) CR_TAB
2467 AS2 (st,X,%1) CR_TAB
2472 return AS2 (std,%0,%1);
2475 return AS2 (st,%0,%1);
2479 out_movhi_mr_r (insn, op, l)
2486 rtx base = XEXP (dest, 0);
2487 int reg_base = true_regnum (base);
2488 int reg_src = true_regnum (src);
2492 if (CONSTANT_ADDRESS_P (base))
2494 if (io_address_p (base, 2))
2497 return (AS2 (out,%B0-0x20,%B1) CR_TAB
2498 AS2 (out,%A0-0x20,%A1));
2500 return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2505 if (reg_base == REG_X)
2507 if (reg_src == REG_X)
2509 if (reg_unused_after (insn, src))
2510 return *l=3, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2511 AS2 (st ,X+,r26) CR_TAB
2512 AS2 (st ,X,__tmp_reg__));
2514 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2515 AS2 (st ,X+,r26) CR_TAB
2516 AS2 (st ,X,__tmp_reg__) CR_TAB
2521 if (reg_unused_after (insn, base))
2522 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2525 return *l=3, (AS2 (st ,X+,%A1) CR_TAB
2526 AS2 (st ,X,%B1) CR_TAB
2531 return *l=2, (AS2 (st ,%0,%A1) CR_TAB
2532 AS2 (std,%0+1,%B1));
2534 else if (GET_CODE (base) == PLUS)
2536 int disp = INTVAL (XEXP (base, 1));
2537 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2539 if (REGNO (XEXP (base, 0)) != REG_Y)
2540 fatal_insn ("Incorrect insn:",insn);
2541 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2543 op[4] = GEN_INT (disp - 62);
2544 return *l=4,(AS2 (adiw, r28, %4) CR_TAB
2545 AS2 (std, Y+62,%A1) CR_TAB
2546 AS2 (std, Y+63,%B1) CR_TAB
2547 AS2 (sbiw, r28, %4));
2551 op[4] = XEXP (base, 1);
2552 return *l=6,(AS2 (subi, r28, lo8(-%4)) CR_TAB
2553 AS2 (sbci, r29, hi8(-%4)) CR_TAB
2554 AS2 (st, Y,%A1) CR_TAB
2555 AS2 (std, Y+1,%B1) CR_TAB
2556 AS2 (subi, r28, lo8(%4)) CR_TAB
2557 AS2 (sbci, r29, hi8(%4)));
2560 return *l=2, (AS2 (std,%A0,%A1) CR_TAB
2563 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2564 return *l=2, (AS2 (st,%0,%B1) CR_TAB
2566 else if (GET_CODE (base) == POST_INC) /* (R++) */
2567 return *l=2, (AS2 (st,%0,%A1) CR_TAB
2569 fatal_insn ("Unknown move insn:",insn);
2573 /* Return 1 if frame pointer for current function required */
2576 frame_pointer_required_p ()
2578 return (current_function_calls_alloca
2579 || current_function_args_info.nregs == 0
2580 || current_function_varargs
2581 || get_frame_size () > 0);
2584 /* Return 1 if the next insn is a JUMP_INSN with condition (GT,LE,GTU,LTU) */
2587 compare_diff_p (insn)
2590 rtx next = next_real_insn (insn);
2591 RTX_CODE cond = UNKNOWN;
2592 if (GET_CODE (next) == JUMP_INSN)
2594 rtx pat = PATTERN (next);
2595 rtx src = SET_SRC (pat);
2596 rtx t = XEXP (src,0);
2597 cond = GET_CODE (t);
2599 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2602 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition */
2608 rtx next = next_real_insn (insn);
2609 RTX_CODE cond = UNKNOWN;
2610 if (GET_CODE (next) == JUMP_INSN)
2612 rtx pat = PATTERN (next);
2613 rtx src = SET_SRC (pat);
2614 rtx t = XEXP (src,0);
2615 cond = GET_CODE (t);
2617 return (cond == EQ || cond == NE);
2621 /* Output test instruction for HImode */
2628 if (!compare_eq_p (insn))
2631 return AS1 (tst,%B0);
2633 if (reg_unused_after (insn, SET_SRC (PATTERN (insn))))
2635 /* faster than sbiw if we can clobber the operand */
2637 return AS2 (or,%A0,%B0);
2639 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2642 return AS2 (sbiw,%0,0);
2645 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2646 AS2 (cpc,%B0,__zero_reg__));
2650 /* Output test instruction for SImode */
2657 if (!compare_eq_p (insn))
2660 return AS1 (tst,%D0);
2662 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2665 return (AS2 (sbiw,%A0,0) CR_TAB
2666 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2667 AS2 (cpc,%D0,__zero_reg__));
2670 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2671 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2672 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2673 AS2 (cpc,%D0,__zero_reg__));
2677 /* Generate asm equivalent for various shift's.
2678 Shift count are CONST_INT or REG. */
2681 out_shift_with_cnt (template, insn, operands, len)
2682 const char *template;
2689 int second_label = 1;
2691 op[0] = operands[0];
2692 op[1] = operands[1];
2693 op[2] = operands[2];
2694 op[3] = operands[3];
2697 if (CONSTANT_P (operands[2]))
2702 strcat (str, "ldi %3,lo8((%2)-1)");
2705 else if (GET_CODE (operands[2]) == MEM)
2710 op[3] = op_mov[0] = tmp_reg_rtx;
2715 output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2716 strcat (str, AS1 (rjmp,2f));
2720 out_movqi_r_mr (insn, op_mov, &mov_len);
2724 else if (register_operand (operands[2], QImode))
2726 if (reg_unused_after (insn, operands[2]))
2730 op[3] = tmp_reg_rtx;
2734 strcat (str, "mov %3,%2" CR_TAB);
2740 strcat (str, AS1 (rjmp,2f));
2745 strcat (str,"\n1:\t");
2746 strcat (str, template);
2747 strcat (str, second_label ? "\n2:\t" : "\n\t");
2751 output_asm_insn (str, op);
2756 /* 8bit shift left ((char)x << i) */
2759 ashlqi3_out (insn, operands, len)
2762 int *len; /* insn length (may be NULL) */
2764 if (GET_CODE (operands[2]) == CONST_INT)
2771 switch (INTVAL (operands[2]))
2775 return AS1 (clr,%0);
2779 return AS1 (lsl,%0);
2783 return (AS1 (lsl,%0) CR_TAB
2788 return (AS1 (lsl,%0) CR_TAB
2793 if (test_hard_reg_class (LD_REGS, operands[0]))
2796 return (AS1 (swap,%0) CR_TAB
2797 AS2 (andi,%0,0xf0));
2800 return (AS1 (lsl,%0) CR_TAB
2806 if (test_hard_reg_class (LD_REGS, operands[0]))
2809 return (AS1 (swap,%0) CR_TAB
2811 AS2 (andi,%0,0xe0));
2814 return (AS1 (lsl,%0) CR_TAB
2821 if (test_hard_reg_class (LD_REGS, operands[0]))
2824 return (AS1 (swap,%0) CR_TAB
2827 AS2 (andi,%0,0xc0));
2830 return (AS1 (lsl,%0) CR_TAB
2839 return (AS1 (ror,%0) CR_TAB
2844 else if (CONSTANT_P (operands[2]))
2845 fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
2849 out_shift_with_cnt (AS1 (lsl,%0),
2850 insn, operands, len);
2855 /* 16bit shift left ((short)x << i) */
2858 ashlhi3_out (insn, operands, len)
2863 if (GET_CODE (operands[2]) == CONST_INT)
2871 switch (INTVAL (operands[2]))
2875 return (AS1 (lsl,%A0) CR_TAB
2880 return (AS1 (lsl,%A0) CR_TAB
2881 AS1 (rol,%B0) CR_TAB
2882 AS1 (lsl,%A0) CR_TAB
2887 return (AS1 (lsr,%B0) CR_TAB
2888 AS2 (mov,%B0,%A0) CR_TAB
2889 AS1 (clr,%A0) CR_TAB
2890 AS1 (ror,%B0) CR_TAB
2894 if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
2895 return *len = 1, AS1 (clr,%A0);
2897 return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
2902 return (AS2 (mov,%B0,%A0) CR_TAB
2903 AS1 (clr,%A0) CR_TAB
2908 return (AS2 (mov,%B0,%A0) CR_TAB
2909 AS1 (clr,%A0) CR_TAB
2910 AS1 (lsl,%B0) CR_TAB
2915 return (AS2 (mov,%B0,%A0) CR_TAB
2916 AS1 (clr,%A0) CR_TAB
2917 AS1 (lsl,%B0) CR_TAB
2918 AS1 (lsl,%B0) CR_TAB
2922 if (test_hard_reg_class (LD_REGS, operands[0]))
2925 return (AS2 (mov,%B0,%A0) CR_TAB
2926 AS1 (clr,%A0) CR_TAB
2927 AS1 (swap,%B0) CR_TAB
2928 AS2 (andi,%B0,0xf0));
2930 /* %3 is a scratch register from class LD_REGS */
2932 return (AS2 (mov,%B0,%A0) CR_TAB
2933 AS1 (clr,%A0) CR_TAB
2934 AS1 (swap,%B0) CR_TAB
2935 AS2 (ldi,%3,0xf0) CR_TAB
2939 if (test_hard_reg_class (LD_REGS, operands[0]))
2942 return (AS2 (mov,%B0,%A0) CR_TAB
2943 AS1 (clr,%A0) CR_TAB
2944 AS1 (swap,%B0) CR_TAB
2945 AS1 (lsl,%B0) CR_TAB
2946 AS2 (andi,%B0,0xe0));
2951 return (AS2 (ldi,%3,0x20) CR_TAB
2952 AS2 (mul,%A0,%3) CR_TAB
2953 AS2 (mov,%B0,r0) CR_TAB
2954 AS1 (clr,%A0) CR_TAB
2955 AS1 (clr,__zero_reg__));
2963 return (AS2 (ldi,%3,0x40) CR_TAB
2964 AS2 (mul,%A0,%3) CR_TAB
2965 AS2 (mov,%B0,r0) CR_TAB
2966 AS1 (clr,%A0) CR_TAB
2967 AS1 (clr,__zero_reg__));
2973 return (AS1 (clr,%B0) CR_TAB
2974 AS1 (lsr,%A0) CR_TAB
2975 AS1 (ror,%B0) CR_TAB
2982 out_shift_with_cnt (AS1 (lsl,%0) CR_TAB
2984 insn, operands, len);
2989 /* 32bit shift left ((long)x << i) */
2992 ashlsi3_out (insn, operands, len)
2997 if (GET_CODE (operands[2]) == CONST_INT)
3005 switch (INTVAL (operands[2]))
3009 return (AS1 (lsl,%A0) CR_TAB
3010 AS1 (rol,%B0) CR_TAB
3011 AS1 (rol,%C0) CR_TAB
3015 /* Loop is one word smaller, but slower and needs a register. */
3017 return (AS1 (lsl,%A0) CR_TAB
3018 AS1 (rol,%B0) CR_TAB
3019 AS1 (rol,%C0) CR_TAB
3020 AS1 (rol,%D0) CR_TAB
3021 AS1 (lsl,%A0) CR_TAB
3022 AS1 (rol,%B0) CR_TAB
3023 AS1 (rol,%C0) CR_TAB
3028 int reg0 = true_regnum (operands[0]);
3029 int reg1 = true_regnum (operands[1]);
3032 return (AS2 (mov,%D0,%C1) CR_TAB
3033 AS2 (mov,%C0,%B1) CR_TAB
3034 AS2 (mov,%B0,%A1) CR_TAB
3036 else if (reg0 + 1 == reg1)
3039 return AS1 (clr,%A0);
3042 return (AS1 (clr,%A0) CR_TAB
3043 AS2 (mov,%B0,%A1) CR_TAB
3044 AS2 (mov,%C0,%B1) CR_TAB
3050 int reg0 = true_regnum (operands[0]);
3051 int reg1 = true_regnum (operands[1]);
3053 if (AVR_ENHANCED && (reg0 + 2 != reg1))
3056 return (AS2 (movw,%C0,%A1) CR_TAB
3057 AS1 (clr,%B0) CR_TAB
3060 if (reg0 + 1 >= reg1)
3061 return (AS2 (mov,%D0,%B1) CR_TAB
3062 AS2 (mov,%C0,%A1) CR_TAB
3063 AS1 (clr,%B0) CR_TAB
3065 if (reg0 + 2 == reg1)
3068 return (AS1 (clr,%B0) CR_TAB
3072 return (AS2 (mov,%C0,%A1) CR_TAB
3073 AS2 (mov,%D0,%B1) CR_TAB
3074 AS1 (clr,%B0) CR_TAB
3080 if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
3081 return (AS2 (mov,%D0,%A1) CR_TAB
3082 AS1 (clr,%C0) CR_TAB
3083 AS1 (clr,%B0) CR_TAB
3088 return (AS1 (clr,%C0) CR_TAB
3089 AS1 (clr,%B0) CR_TAB
3095 return (AS1 (clr,%D0) CR_TAB
3096 AS1 (lsr,%A0) CR_TAB
3097 AS1 (ror,%D0) CR_TAB
3098 AS1 (clr,%C0) CR_TAB
3099 AS1 (clr,%B0) CR_TAB
3106 out_shift_with_cnt (AS1 (lsl,%0) CR_TAB
3107 AS1 (rol,%B0) CR_TAB
3108 AS1 (rol,%C0) CR_TAB
3110 insn, operands, len);
3114 /* 8bit arithmetic shift right ((signed char)x >> i) */
3117 ashrqi3_out (insn, operands, len)
3120 int *len; /* insn length */
3122 if (GET_CODE (operands[2]) == CONST_INT)
3129 switch (INTVAL (operands[2]))
3133 return AS1 (asr,%0);
3137 return (AS1 (asr,%0) CR_TAB
3142 return (AS1 (asr,%0) CR_TAB
3148 return (AS1 (asr,%0) CR_TAB
3155 return (AS1 (asr,%0) CR_TAB
3163 return (AS2 (bst,%0,6) CR_TAB
3165 AS2 (sbc,%0,%0) CR_TAB
3171 return (AS1 (lsl,%0) CR_TAB
3175 else if (CONSTANT_P (operands[2]))
3176 fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
3180 out_shift_with_cnt (AS1 (asr,%0),
3181 insn, operands, len);
3186 /* 16bit arithmetic shift right ((signed short)x >> i) */
3189 ashrhi3_out (insn, operands, len)
3194 if (GET_CODE (operands[2]) == CONST_INT)
3202 switch (INTVAL (operands[2]))
3206 return (AS1 (asr,%B0) CR_TAB
3211 return (AS1 (asr,%B0) CR_TAB
3212 AS1 (ror,%A0) CR_TAB
3213 AS1 (asr,%B0) CR_TAB
3218 return (AS1 (lsl,%A0) CR_TAB
3219 AS2 (mov,%A0,%B0) CR_TAB
3220 AS1 (rol,%A0) CR_TAB
3224 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
3225 return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3226 AS1 (clr,%B0) CR_TAB
3227 AS2 (sbrc,%A0,7) CR_TAB
3230 return *len = 3, (AS1 (clr,%B0) CR_TAB
3231 AS2 (sbrc,%A0,7) CR_TAB
3236 return (AS2 (mov,%A0,%B0) CR_TAB
3237 AS1 (lsl,%B0) CR_TAB
3238 AS2 (sbc,%B0,%B0) CR_TAB
3243 return (AS2 (mov,%A0,%B0) CR_TAB
3244 AS1 (lsl,%B0) CR_TAB
3245 AS2 (sbc,%B0,%B0) CR_TAB
3246 AS1 (asr,%A0) CR_TAB
3250 if (AVR_ENHANCED && test_hard_reg_class (LD_REGS, operands[0]))
3253 return (AS2 (ldi,%3,0x20) CR_TAB
3254 AS2 (muls,%B0,%3) CR_TAB
3255 AS2 (mov,%A0,r1) CR_TAB
3256 AS2 (sbc,%B0,%B0) CR_TAB
3257 AS1 (clr,__zero_reg__));
3262 if (AVR_ENHANCED && test_hard_reg_class (LD_REGS, operands[0]))
3265 return (AS2 (ldi,%3,0x10) CR_TAB
3266 AS2 (muls,%B0,%3) CR_TAB
3267 AS2 (mov,%A0,r1) CR_TAB
3268 AS2 (sbc,%B0,%B0) CR_TAB
3269 AS1 (clr,__zero_reg__));
3274 if (AVR_ENHANCED && test_hard_reg_class (LD_REGS, operands[0]))
3277 return (AS2 (ldi,%3,0x08) CR_TAB
3278 AS2 (muls,%B0,%3) CR_TAB
3279 AS2 (mov,%A0,r1) CR_TAB
3280 AS2 (sbc,%B0,%B0) CR_TAB
3281 AS1 (clr,__zero_reg__));
3287 return (AS1 (lsl,%B0) CR_TAB
3288 AS2 (sbc,%A0,%A0) CR_TAB
3289 AS1 (lsl,%B0) CR_TAB
3290 AS2 (mov,%B0,%A0) CR_TAB
3294 return *len = 3, (AS1 (lsl,%B0) CR_TAB
3295 AS2 (sbc,%A0,%A0) CR_TAB
3302 out_shift_with_cnt (AS1 (asr,%B0) CR_TAB
3304 insn, operands, len);
3309 /* 32bit arithmetic shift right ((signed long)x >> i) */
3312 ashrsi3_out (insn, operands, len)
3317 if (GET_CODE (operands[2]) == CONST_INT)
3325 switch (INTVAL (operands[2]))
3329 return (AS1 (asr,%D0) CR_TAB
3330 AS1 (ror,%C0) CR_TAB
3331 AS1 (ror,%B0) CR_TAB
3335 /* Loop is one word smaller, but slower and needs a register. */
3337 return (AS1 (asr,%D0) CR_TAB
3338 AS1 (ror,%C0) CR_TAB
3339 AS1 (ror,%B0) CR_TAB
3340 AS1 (ror,%A0) CR_TAB
3341 AS1 (asr,%D0) CR_TAB
3342 AS1 (ror,%C0) CR_TAB
3343 AS1 (ror,%B0) CR_TAB
3348 int reg0 = true_regnum (operands[0]);
3349 int reg1 = true_regnum (operands[1]);
3352 return (AS2 (mov,%A0,%B1) CR_TAB
3353 AS2 (mov,%B0,%C1) CR_TAB
3354 AS2 (mov,%C0,%D1) CR_TAB
3355 AS1 (clr,%D0) CR_TAB
3356 AS2 (sbrc,%C0,7) CR_TAB
3358 else if (reg0 == reg1 + 1)
3361 return (AS1 (clr,%D0) CR_TAB
3362 AS2 (sbrc,%C0,7) CR_TAB
3366 return (AS1 (clr,%D0) CR_TAB
3367 AS2 (sbrc,%D1,7) CR_TAB
3368 AS1 (dec,%D0) CR_TAB
3369 AS2 (mov,%C0,%D1) CR_TAB
3370 AS2 (mov,%B0,%C1) CR_TAB
3376 int reg0 = true_regnum (operands[0]);
3377 int reg1 = true_regnum (operands[1]);
3379 if (AVR_ENHANCED && (reg0 != reg1 + 2))
3382 return (AS2 (movw,%A0,%C1) CR_TAB
3383 AS1 (clr,%D0) CR_TAB
3384 AS2 (sbrc,%B0,7) CR_TAB
3385 AS1 (com,%D0) CR_TAB
3388 if (reg0 <= reg1 + 1)
3389 return (AS2 (mov,%A0,%C1) CR_TAB
3390 AS2 (mov,%B0,%D1) CR_TAB
3391 AS1 (clr,%D0) CR_TAB
3392 AS2 (sbrc,%B0,7) CR_TAB
3393 AS1 (com,%D0) CR_TAB
3395 else if (reg0 == reg1 + 2)
3396 return *len = 4, (AS1 (clr,%D0) CR_TAB
3397 AS2 (sbrc,%B0,7) CR_TAB
3398 AS1 (com,%D0) CR_TAB
3401 return (AS2 (mov,%B0,%D1) CR_TAB
3402 AS2 (mov,%A0,%C1) CR_TAB
3403 AS1 (clr,%D0) CR_TAB
3404 AS2 (sbrc,%B0,7) CR_TAB
3405 AS1 (com,%D0) CR_TAB
3410 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3411 return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3412 AS1 (clr,%D0) CR_TAB
3413 AS2 (sbrc,%A0,7) CR_TAB
3414 AS1 (com,%D0) CR_TAB
3415 AS2 (mov,%B0,%D0) CR_TAB
3418 return *len = 5, (AS1 (clr,%D0) CR_TAB
3419 AS2 (sbrc,%A0,7) CR_TAB
3420 AS1 (com,%D0) CR_TAB
3421 AS2 (mov,%B0,%D0) CR_TAB
3426 return *len = 4, (AS1 (lsl,%D0) CR_TAB
3427 AS2 (sbc,%A0,%A0) CR_TAB
3428 AS2 (mov,%B0,%A0) CR_TAB
3429 AS2 (movw,%C0,%A0));
3431 return *len = 5, (AS1 (lsl,%D0) CR_TAB
3432 AS2 (sbc,%A0,%A0) CR_TAB
3433 AS2 (mov,%B0,%A0) CR_TAB
3434 AS2 (mov,%C0,%A0) CR_TAB
3441 out_shift_with_cnt (AS1 (asr,%D0) CR_TAB
3442 AS1 (ror,%C0) CR_TAB
3443 AS1 (ror,%B0) CR_TAB
3445 insn, operands, len);
3449 /* 8bit logic shift right ((unsigned char)x >> i) */
3452 lshrqi3_out (insn, operands, len)
3457 if (GET_CODE (operands[2]) == CONST_INT)
3464 switch (INTVAL (operands[2]))
3468 return AS1 (clr,%0);
3472 return AS1 (lsr,%0);
3476 return (AS1 (lsr,%0) CR_TAB
3480 return (AS1 (lsr,%0) CR_TAB
3485 if (test_hard_reg_class (LD_REGS, operands[0]))
3488 return (AS1 (swap,%0) CR_TAB
3489 AS2 (andi,%0,0x0f));
3492 return (AS1 (lsr,%0) CR_TAB
3498 if (test_hard_reg_class (LD_REGS, operands[0]))
3501 return (AS1 (swap,%0) CR_TAB
3506 return (AS1 (lsr,%0) CR_TAB
3513 if (test_hard_reg_class (LD_REGS, operands[0]))
3516 return (AS1 (swap,%0) CR_TAB
3522 return (AS1 (lsr,%0) CR_TAB
3531 return (AS1 (rol,%0) CR_TAB
3536 else if (CONSTANT_P (operands[2]))
3537 fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
3541 out_shift_with_cnt (AS1 (lsr,%0),
3542 insn, operands, len);
3546 /* 16bit logic shift right ((unsigned short)x >> i) */
3549 lshrhi3_out (insn, operands, len)
3554 if (GET_CODE (operands[2]) == CONST_INT)
3562 switch (INTVAL (operands[2]))
3566 return (AS1 (lsr,%B0) CR_TAB
3571 return (AS1 (lsr,%B0) CR_TAB
3572 AS1 (ror,%A0) CR_TAB
3573 AS1 (lsr,%B0) CR_TAB
3578 return (AS1 (lsl,%A0) CR_TAB
3579 AS2 (mov,%A0,%B0) CR_TAB
3580 AS1 (rol,%A0) CR_TAB
3581 AS2 (sbc,%B0,%B0) CR_TAB
3585 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
3586 return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
3589 return *len = 1, AS1 (clr,%B0);
3593 return (AS2 (mov,%A0,%B0) CR_TAB
3594 AS1 (clr,%B0) CR_TAB
3599 return (AS2 (mov,%A0,%B0) CR_TAB
3600 AS1 (clr,%B0) CR_TAB
3601 AS1 (lsr,%A0) CR_TAB
3606 return (AS2 (mov,%A0,%B0) CR_TAB
3607 AS1 (clr,%B0) CR_TAB
3608 AS1 (lsr,%A0) CR_TAB
3609 AS1 (lsr,%A0) CR_TAB
3613 if (test_hard_reg_class (LD_REGS, operands[0]))
3616 return (AS2 (mov,%A0,%B0) CR_TAB
3617 AS1 (clr,%B0) CR_TAB
3618 AS1 (swap,%A0) CR_TAB
3619 AS2 (andi,%A0,0x0f));
3621 /* %3 is a scratch register from class LD_REGS */
3623 return (AS2 (mov,%A0,%B0) CR_TAB
3624 AS1 (clr,%B0) CR_TAB
3625 AS1 (swap,%A0) CR_TAB
3626 AS2 (ldi,%3,0x0f) CR_TAB
3630 if (test_hard_reg_class (LD_REGS, operands[0]))
3633 return (AS2 (mov,%A0,%B0) CR_TAB
3634 AS1 (clr,%B0) CR_TAB
3635 AS1 (swap,%A0) CR_TAB
3636 AS1 (lsr,%A0) CR_TAB
3637 AS2 (andi,%A0,0x07));
3642 return (AS2 (ldi,%3,0x08) CR_TAB
3643 AS2 (mul,%B0,%3) CR_TAB
3644 AS2 (mov,%A0,r1) CR_TAB
3645 AS1 (clr,%B0) CR_TAB
3646 AS1 (clr,__zero_reg__));
3654 return (AS2 (ldi,%3,0x04) CR_TAB
3655 AS2 (mul,%B0,%3) CR_TAB
3656 AS2 (mov,%A0,r1) CR_TAB
3657 AS1 (clr,%B0) CR_TAB
3658 AS1 (clr,__zero_reg__));
3664 return (AS1 (lsl,%B0) CR_TAB
3665 AS2 (sbc,%A0,%A0) CR_TAB
3666 AS1 (neg,%A0) CR_TAB
3673 out_shift_with_cnt (AS1 (lsr,%B0) CR_TAB
3675 insn, operands, len);
3679 /* 32bit logic shift right ((unsigned int)x >> i) */
3682 lshrsi3_out (insn, operands, len)
3687 if (GET_CODE (operands[2]) == CONST_INT)
3695 switch (INTVAL (operands[2]))
3699 return (AS1 (lsr,%D0) CR_TAB
3700 AS1 (ror,%C0) CR_TAB
3701 AS1 (ror,%B0) CR_TAB
3705 /* Loop is one word smaller, but slower and needs a register. */
3707 return (AS1 (lsr,%D0) CR_TAB
3708 AS1 (ror,%C0) CR_TAB
3709 AS1 (ror,%B0) CR_TAB
3710 AS1 (ror,%A0) CR_TAB
3711 AS1 (lsr,%D0) CR_TAB
3712 AS1 (ror,%C0) CR_TAB
3713 AS1 (ror,%B0) CR_TAB
3718 int reg0 = true_regnum (operands[0]);
3719 int reg1 = true_regnum (operands[1]);
3722 return (AS2 (mov,%A0,%B1) CR_TAB
3723 AS2 (mov,%B0,%C1) CR_TAB
3724 AS2 (mov,%C0,%D1) CR_TAB
3726 else if (reg0 == reg1 + 1)
3727 return *len = 1, AS1 (clr,%D0);
3729 return (AS1 (clr,%D0) CR_TAB
3730 AS2 (mov,%C0,%D1) CR_TAB
3731 AS2 (mov,%B0,%C1) CR_TAB
3737 int reg0 = true_regnum (operands[0]);
3738 int reg1 = true_regnum (operands[1]);
3740 if (AVR_ENHANCED && (reg0 != reg1 + 2))
3743 return (AS2 (movw,%A0,%C1) CR_TAB
3744 AS1 (clr,%C0) CR_TAB
3747 if (reg0 <= reg1 + 1)
3748 return (AS2 (mov,%A0,%C1) CR_TAB
3749 AS2 (mov,%B0,%D1) CR_TAB
3750 AS1 (clr,%C0) CR_TAB
3752 else if (reg0 == reg1 + 2)
3753 return *len = 2, (AS1 (clr,%C0) CR_TAB
3756 return (AS2 (mov,%B0,%D1) CR_TAB
3757 AS2 (mov,%A0,%C1) CR_TAB
3758 AS1 (clr,%C0) CR_TAB
3763 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3764 return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
3765 AS1 (clr,%B0) CR_TAB
3766 AS1 (clr,%C0) CR_TAB
3769 return *len = 3, (AS1 (clr,%B0) CR_TAB
3770 AS1 (clr,%C0) CR_TAB
3775 return (AS1 (clr,%A0) CR_TAB
3776 AS2 (sbrc,%D0,7) CR_TAB
3777 AS1 (inc,%A0) CR_TAB
3778 AS1 (clr,%B0) CR_TAB
3779 AS1 (clr,%C0) CR_TAB
3786 out_shift_with_cnt (AS1 (lsr,%D0) CR_TAB
3787 AS1 (ror,%C0) CR_TAB
3788 AS1 (ror,%B0) CR_TAB
3790 insn, operands, len);
3794 /* Modifies the length assigned to instruction INSN
3795 LEN is the initially computed length of the insn. */
3798 adjust_insn_length (insn, len)
3802 rtx patt = PATTERN (insn);
3805 if (GET_CODE (patt) == SET)
3808 op[1] = SET_SRC (patt);
3809 op[0] = SET_DEST (patt);
3810 if (general_operand (op[1], VOIDmode)
3811 && general_operand (op[0], VOIDmode))
3813 switch (GET_MODE (op[0]))
3816 output_movqi (insn, op, &len);
3819 output_movhi (insn, op, &len);
3823 output_movsisf (insn, op, &len);
3829 else if (op[0] == cc0_rtx && REG_P (op[1]))
3831 switch (GET_MODE (op[1]))
3833 case HImode: out_tsthi (insn,&len); break;
3834 case SImode: out_tstsi (insn,&len); break;
3838 else if (GET_CODE (op[1]) == AND)
3840 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
3842 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
3843 if (GET_MODE (op[1]) == SImode)
3844 len = (((mask & 0xff) != 0xff)
3845 + ((mask & 0xff00) != 0xff00)
3846 + ((mask & 0xff0000UL) != 0xff0000UL)
3847 + ((mask & 0xff000000UL) != 0xff000000UL));
3848 else if (GET_MODE (op[1]) == HImode)
3849 len = (((mask & 0xff) != 0xff)
3850 + ((mask & 0xff00) != 0xff00));
3853 else if (GET_CODE (op[1]) == IOR)
3855 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
3857 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
3858 if (GET_MODE (op[1]) == SImode)
3859 len = (((mask & 0xff) != 0)
3860 + ((mask & 0xff00) != 0)
3861 + ((mask & 0xff0000UL) != 0)
3862 + ((mask & 0xff000000UL) != 0));
3863 else if (GET_MODE (op[1]) == HImode)
3864 len = (((mask & 0xff) != 0)
3865 + ((mask & 0xff00) != 0));
3869 set = single_set (insn);
3874 op[1] = SET_SRC (set);
3875 op[0] = SET_DEST (set);
3877 if (GET_CODE (patt) == PARALLEL
3878 && general_operand (op[1], VOIDmode)
3879 && general_operand (op[0], VOIDmode))
3881 if (XVECLEN (patt, 0) == 2)
3882 op[2] = XVECEXP (patt, 0, 1);
3884 switch (GET_MODE (op[0]))
3890 output_reload_inhi (insn, op, &len);
3894 output_reload_insisf (insn, op, &len);
3900 else if (GET_CODE (op[1]) == ASHIFT
3901 || GET_CODE (op[1]) == ASHIFTRT
3902 || GET_CODE (op[1]) == LSHIFTRT)
3906 ops[1] = XEXP (op[1],0);
3907 ops[2] = XEXP (op[1],1);
3908 switch (GET_CODE (op[1]))
3911 switch (GET_MODE (op[0]))
3913 case QImode: ashlqi3_out (insn,ops,&len); break;
3914 case HImode: ashlhi3_out (insn,ops,&len); break;
3915 case SImode: ashlsi3_out (insn,ops,&len); break;
3920 switch (GET_MODE (op[0]))
3922 case QImode: ashrqi3_out (insn,ops,&len); break;
3923 case HImode: ashrhi3_out (insn,ops,&len); break;
3924 case SImode: ashrsi3_out (insn,ops,&len); break;
3929 switch (GET_MODE (op[0]))
3931 case QImode: lshrqi3_out (insn,ops,&len); break;
3932 case HImode: lshrhi3_out (insn,ops,&len); break;
3933 case SImode: lshrsi3_out (insn,ops,&len); break;
3945 /* Return non-zero if register REG dead after INSN */
3948 reg_unused_after (insn, reg)
3952 return (dead_or_set_p (insn, reg)
3953 || (REG_P(reg) && _reg_unused_after (insn, reg)));
3956 /* Return non-zero if REG is not used after INSN.
3957 We assume REG is a reload reg, and therefore does
3958 not live past labels. It may live past calls or jumps though. */
3961 _reg_unused_after (insn, reg)
3968 /* If the reg is set by this instruction, then it is safe for our
3969 case. Disregard the case where this is a store to memory, since
3970 we are checking a register used in the store address. */
3971 set = single_set (insn);
3972 if (set && GET_CODE (SET_DEST (set)) != MEM
3973 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
3976 while ((insn = NEXT_INSN (insn)))
3978 code = GET_CODE (insn);
3981 /* If this is a label that existed before reload, then the register
3982 if dead here. However, if this is a label added by reorg, then
3983 the register may still be live here. We can't tell the difference,
3984 so we just ignore labels completely. */
3985 if (code == CODE_LABEL)
3990 if (code == JUMP_INSN)
3993 /* If this is a sequence, we must handle them all at once.
3994 We could have for instance a call that sets the target register,
3995 and a insn in a delay slot that uses the register. In this case,
3996 we must return 0. */
3997 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
4002 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
4004 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
4005 rtx set = single_set (this_insn);
4007 if (GET_CODE (this_insn) == CALL_INSN)
4009 else if (GET_CODE (this_insn) == JUMP_INSN)
4011 if (INSN_ANNULLED_BRANCH_P (this_insn))
4016 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4018 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4020 if (GET_CODE (SET_DEST (set)) != MEM)
4026 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
4031 else if (code == JUMP_INSN)
4035 if (code == CALL_INSN)
4038 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4039 if (GET_CODE (XEXP (tem, 0)) == USE
4040 && REG_P (XEXP (XEXP (tem, 0), 0))
4041 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
4043 if (call_used_regs[REGNO (reg)])
4047 if (GET_RTX_CLASS (code) == 'i')
4049 rtx set = single_set (insn);
4051 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4053 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4054 return GET_CODE (SET_DEST (set)) != MEM;
4055 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
4062 /* Output rtx VALUE as .byte to file FILE */
4065 asm_output_char (file, value)
4069 fprintf (file, "\t.byte ");
4070 output_addr_const (file, value);
4071 fprintf (file, "\n");
4075 /* Output VALUE as .byte to file FILE */
4078 asm_output_byte (file, value)
4082 fprintf (file, "\t.byte 0x%x\n", value & 0xff);
4086 /* Output rtx VALUE as .word to file FILE */
4089 asm_output_short (file, value)
4093 if (SYMBOL_REF_FLAG (value) || GET_CODE (value) == LABEL_REF)
4095 fprintf (file, "\t.word pm(");
4096 output_addr_const (file, (value));
4097 fprintf (file, ")\n");
4101 fprintf (file, "\t.word ");
4102 output_addr_const (file, (value));
4103 fprintf (file, "\n");
4108 /* Output real N to file FILE */
4111 asm_output_float (file, n)
4118 REAL_VALUE_TO_TARGET_SINGLE (n, val);
4119 REAL_VALUE_TO_DECIMAL (n, "%g", dstr);
4120 fprintf (file, "\t.long 0x%08lx\t/* %s */\n", val, dstr);
4123 /* Sets section name for declaration DECL */
4126 unique_section (decl, reloc)
4128 int reloc ATTRIBUTE_UNUSED;
4131 const char *name, *prefix;
4133 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
4134 /* Strip off any encoding in name. */
4135 STRIP_NAME_ENCODING (name, name);
4137 if (TREE_CODE (decl) == FUNCTION_DECL)
4139 if (flag_function_sections)
4145 fatal ("Strange situation: unique section is not a FUNCTION_DECL");
4147 if (flag_function_sections)
4149 len = strlen (name) + strlen (prefix);
4150 string = alloca (len + 1);
4151 sprintf (string, "%s%s", prefix, name);
4152 DECL_SECTION_NAME (decl) = build_string (len, string);
4157 /* Output section name to file FILE
4158 We make the section read-only and executable for a function decl,
4159 read-only for a const data decl, and writable for a non-const data decl. */
4162 asm_output_section_name(file, decl, name, reloc)
4166 int reloc ATTRIBUTE_UNUSED;
4168 fprintf (file, ".section %s, \"%s\", @progbits\n", name,
4169 decl && TREE_CODE (decl) == FUNCTION_DECL ? "ax" :
4170 decl && TREE_READONLY (decl) ? "a" : "aw");
4174 /* The routine used to output NUL terminated strings. We use a special
4175 version of this for most svr4 targets because doing so makes the
4176 generated assembly code more compact (and thus faster to assemble)
4177 as well as more readable, especially for targets like the i386
4178 (where the only alternative is to output character sequences as
4179 comma separated lists of numbers). */
4182 gas_output_limited_string(file, str)
4186 const unsigned char *_limited_str = (unsigned char *) str;
4188 fprintf (file, "%s\"", STRING_ASM_OP);
4189 for (; (ch = *_limited_str); _limited_str++)
4192 switch (escape = ESCAPES[ch])
4198 fprintf (file, "\\%03o", ch);
4202 putc (escape, file);
4206 fprintf (file, "\"\n");
4209 /* The routine used to output sequences of byte values. We use a special
4210 version of this for most svr4 targets because doing so makes the
4211 generated assembly code more compact (and thus faster to assemble)
4212 as well as more readable. Note that if we find subparts of the
4213 character sequence which end with NUL (and which are shorter than
4214 STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
4217 gas_output_ascii(file, str, length)
4222 const unsigned char *_ascii_bytes = (const unsigned char *) str;
4223 const unsigned char *limit = _ascii_bytes + length;
4224 unsigned bytes_in_chunk = 0;
4225 for (; _ascii_bytes < limit; _ascii_bytes++)
4227 const unsigned char *p;
4228 if (bytes_in_chunk >= 60)
4230 fprintf (file, "\"\n");
4233 for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
4235 if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
4237 if (bytes_in_chunk > 0)
4239 fprintf (file, "\"\n");
4242 gas_output_limited_string (file, (char*)_ascii_bytes);
4249 if (bytes_in_chunk == 0)
4250 fprintf (file, "\t.ascii\t\"");
4251 switch (escape = ESCAPES[ch = *_ascii_bytes])
4258 fprintf (file, "\\%03o", ch);
4259 bytes_in_chunk += 4;
4263 putc (escape, file);
4264 bytes_in_chunk += 2;
4269 if (bytes_in_chunk > 0)
4270 fprintf (file, "\"\n");
4273 /* Return value is nonzero if pseudos that have been
4274 assigned to registers of class CLASS would likely be spilled
4275 because registers of CLASS are needed for spill registers. */
4278 class_likely_spilled_p (c)
4281 return (c != ALL_REGS && c != ADDW_REGS);
4284 /* Only `progmem' attribute valid for type. */
4287 valid_machine_type_attribute(type, attributes, identifier, args)
4288 tree type ATTRIBUTE_UNUSED;
4289 tree attributes ATTRIBUTE_UNUSED;
4291 tree args ATTRIBUTE_UNUSED;
4293 return is_attribute_p ("progmem", identifier);
4296 /* If IDENTIFIER with arguments ARGS is a valid machine specific
4297 attribute for DECL return 1.
4299 progmem - put data to program memory;
4300 signal - make a function to be hardware interrupt. After function
4301 prologue interrupts are disabled;
4302 interrupt - make a function to be hardware interrupt. After function
4303 prologue interrupts are enabled;
4304 naked - don't generate function prologue/epilogue and `ret' command. */
4307 valid_machine_decl_attribute (decl, attributes, attr, args)
4309 tree attributes ATTRIBUTE_UNUSED;
4311 tree args ATTRIBUTE_UNUSED;
4313 if (is_attribute_p ("interrupt", attr)
4314 || is_attribute_p ("signal", attr)
4315 || is_attribute_p ("naked", attr))
4316 return TREE_CODE (decl) == FUNCTION_DECL;
4318 if (is_attribute_p ("progmem", attr)
4319 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
4321 if (DECL_INITIAL (decl) == NULL_TREE)
4323 warning ("Only initialized variables can be placed into "
4324 "program memory area.");
4333 /* Look for attribute `progmem' in DECL
4334 if found return 1, otherwise 0. */
4337 avr_progmem_p (decl)
4342 if (TREE_CODE (decl) != VAR_DECL)
4346 != lookup_attribute ("progmem", DECL_MACHINE_ATTRIBUTES (decl)))
4352 while (TREE_CODE (a) == ARRAY_TYPE);
4354 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
4360 /* Encode section information about tree DECL */
4363 encode_section_info (decl)
4366 if (TREE_CODE (decl) == FUNCTION_DECL)
4367 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
4369 if ((TREE_STATIC (decl) || DECL_EXTERNAL (decl))
4370 && TREE_CODE (decl) == VAR_DECL
4371 && avr_progmem_p (decl))
4373 const char *dsec = ".progmem.data";
4374 DECL_SECTION_NAME (decl) = build_string (strlen (dsec), dsec);
4375 TREE_READONLY (decl) = 1;
4379 /* Outputs to the stdio stream FILE some
4380 appropriate text to go at the start of an assembler file. */
4383 asm_file_start (file)
4386 output_file_directive (file, main_input_filename);
4387 fprintf (file, "\t.arch %s\n", avr_mcu_name);
4388 fputs ("__SREG__ = 0x3f\n"
4390 "__SP_L__ = 0x3d\n", file);
4392 fputs ("__tmp_reg__ = 0\n"
4393 "__zero_reg__ = 1\n"
4394 "_PC_ = 2\n", file);
4396 commands_in_file = 0;
4397 commands_in_prologues = 0;
4398 commands_in_epilogues = 0;
4401 /* Outputs to the stdio stream FILE some
4402 appropriate text to go at the end of an assembler file. */
4409 "/* File %s: code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
4410 main_input_filename,
4413 commands_in_file - commands_in_prologues - commands_in_epilogues,
4414 commands_in_prologues, commands_in_epilogues);
4417 /* Choose the order in which to allocate hard registers for
4418 pseudo-registers local to a basic block.
4420 Store the desired register order in the array `reg_alloc_order'.
4421 Element 0 should be the register to allocate first; element 1, the
4422 next register; and so on. */
4425 order_regs_for_local_alloc ()
4436 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4448 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4461 15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4466 int *order = (TARGET_ORDER_1 ? order_1 :
4467 TARGET_ORDER_2 ? order_2 :
4469 for (i=0; i < ARRAY_SIZE (order_0); ++i)
4470 reg_alloc_order[i] = order[i];
4473 /* Calculate the cost of X code of the expression in which it is contained,
4474 found in OUTER_CODE */
4477 default_rtx_costs (X, code, outer_code)
4480 enum rtx_code outer_code;
4487 cost = 2 * GET_MODE_SIZE (GET_MODE (X));
4490 if (outer_code != SET)
4492 if (GET_CODE (XEXP (X,0)) == SYMBOL_REF)
4493 cost += 2 * GET_MODE_SIZE (GET_MODE (X));
4495 cost += GET_MODE_SIZE (GET_MODE (X));
4501 if (outer_code == SET)
4502 cost = GET_MODE_SIZE (GET_MODE (X));
4504 cost = -GET_MODE_SIZE (GET_MODE (X));
4507 if (outer_code == SET)
4508 cost = GET_MODE_SIZE (GET_MODE (X));
4514 if (outer_code == SET)
4516 if (X == stack_pointer_rtx)
4518 else if (GET_CODE (XEXP (X,1)) == CONST_INT)
4519 cost = (INTVAL (XEXP (X,1)) <= 63 ? 1 :
4520 GET_MODE_SIZE (GET_MODE (X)));
4522 cost = GET_MODE_SIZE (GET_MODE (X));
4526 if (GET_CODE (XEXP (X,1)) == CONST_INT)
4527 cost = GET_MODE_SIZE (GET_MODE (XEXP (X,0)));
4535 /* Calculate the cost of a memory address */
4538 avr_address_cost (x)
4541 if (GET_CODE (x) == PLUS
4542 && GET_CODE (XEXP (x,1)) == CONST_INT
4543 && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
4544 && INTVAL (XEXP (x,1)) >= 61)
4546 if (CONSTANT_ADDRESS_P (x))
4548 if (io_address_p (x, 1))
4555 /* EXTRA_CONSTRAINT helper */
4558 extra_constraint (x, c)
4563 && GET_CODE (x) == MEM
4564 && GET_CODE (XEXP (x,0)) == PLUS)
4566 if (TARGET_ALL_DEBUG)
4568 fprintf (stderr, ("extra_constraint:\n"
4569 "reload_completed: %d\n"
4570 "reload_in_progress: %d\n"),
4571 reload_completed, reload_in_progress);
4574 if (GET_CODE (x) == MEM
4575 && GET_CODE (XEXP (x,0)) == PLUS
4576 && REG_P (XEXP (XEXP (x,0), 0))
4577 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
4578 && (INTVAL (XEXP (XEXP (x,0), 1))
4579 <= MAX_LD_OFFSET (GET_MODE (x))))
4581 rtx xx = XEXP (XEXP (x,0), 0);
4582 int regno = REGNO (xx);
4583 if (TARGET_ALL_DEBUG)
4585 fprintf (stderr, ("extra_constraint:\n"
4586 "reload_completed: %d\n"
4587 "reload_in_progress: %d\n"),
4588 reload_completed, reload_in_progress);
4591 if (regno >= FIRST_PSEUDO_REGISTER)
4592 return 1; /* allocate pseudos */
4593 else if (regno == REG_Z || regno == REG_Y)
4594 return 1; /* strictly check */
4595 else if (xx == frame_pointer_rtx
4596 || xx == arg_pointer_rtx)
4597 return 1; /* XXX frame & arg pointer checks */
4603 /* Convert condition code CONDITION to the valid AVR condition code */
4606 avr_normalize_condition (condition)
4620 fatal ("Wrong condition: %s", GET_RTX_NAME (condition));
4624 /* This fnction optimizes conditional jumps */
4627 machine_dependent_reorg (first_insn)
4633 for (insn = first_insn; insn; insn = NEXT_INSN (insn))
4635 if (! (insn == 0 || GET_CODE (insn) == INSN
4636 || GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN)
4637 || !single_set (insn))
4640 pattern = PATTERN (insn);
4642 cc_prev_status = cc_status;
4643 NOTICE_UPDATE_CC (pattern, insn);
4645 if (GET_CODE (pattern) == PARALLEL)
4646 pattern = XVECEXP (pattern, 0, 0);
4647 if (GET_CODE (pattern) == SET
4648 && SET_DEST (pattern) == cc0_rtx
4649 && compare_diff_p (insn))
4651 if (GET_CODE (SET_SRC (pattern)) == COMPARE)
4653 /* Now we work under compare insn */
4655 pattern = SET_SRC (pattern);
4656 if (true_regnum (XEXP (pattern,0)) >= 0
4657 && true_regnum (XEXP (pattern,1)) >= 0 )
4659 rtx x = XEXP (pattern,0);
4660 rtx next = next_real_insn (insn);
4661 rtx pat = PATTERN (next);
4662 rtx src = SET_SRC (pat);
4663 rtx t = XEXP (src,0);
4664 PUT_CODE (t, swap_condition (GET_CODE (t)));
4665 XEXP (pattern,0) = XEXP (pattern,1);
4666 XEXP (pattern,1) = x;
4667 INSN_CODE (next) = -1;
4669 else if (true_regnum (XEXP (pattern,0)) >= 0
4670 && GET_CODE (XEXP (pattern,1)) == CONST_INT)
4672 rtx x = XEXP (pattern,1);
4673 rtx next = next_real_insn (insn);
4674 rtx pat = PATTERN (next);
4675 rtx src = SET_SRC (pat);
4676 rtx t = XEXP (src,0);
4678 if (avr_simplify_comparision_p (GET_MODE (XEXP (pattern,0)),
4681 XEXP (pattern,1) = GEN_INT (INTVAL (x)+1);
4682 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
4683 INSN_CODE (next) = -1;
4684 INSN_CODE (insn) = -1;
4688 else if (true_regnum (SET_SRC (pattern)) >= 0)
4690 /* This is a tst insn */
4691 rtx next = next_real_insn (insn);
4692 rtx pat = PATTERN (next);
4693 rtx src = SET_SRC (pat);
4694 rtx t = XEXP (src,0);
4696 if (!(cc_prev_status.value1 != 0 && cc_status.value1 != 0
4697 && rtx_equal_p (cc_status.value1, cc_prev_status.value1)))
4699 PUT_CODE (t, swap_condition (GET_CODE (t)));
4700 SET_SRC (pattern) = gen_rtx (NEG,
4701 GET_MODE (SET_SRC (pattern)),
4703 INSN_CODE (next) = -1;
4704 INSN_CODE (insn) = -1;
4711 /* Returns register number for function return value.*/
4719 /* Ceate an RTX representing the place where a
4720 library function returns a value of mode MODE. */
4723 avr_libcall_value (mode)
4724 enum machine_mode mode;
4726 int offs = GET_MODE_SIZE (mode);
4729 return gen_rtx (REG, mode, RET_REGISTER + 2 - offs);
4732 /* Create an RTX representing the place where a
4733 function returns a value of data type VALTYPE. */
4736 avr_function_value (type, func)
4738 tree func ATTRIBUTE_UNUSED;
4741 if (TYPE_MODE (type) != BLKmode)
4742 return avr_libcall_value (TYPE_MODE (type));
4744 offs = int_size_in_bytes (type);
4747 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
4748 offs = GET_MODE_SIZE (SImode);
4749 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
4750 offs = GET_MODE_SIZE (DImode);
4752 return gen_rtx (REG, BLKmode, RET_REGISTER + 2 - offs);
4755 /* Returns non-zero if the number MASK has only one bit set. */
4758 mask_one_bit_p (mask)
4762 unsigned HOST_WIDE_INT n=mask;
4763 for (i = 0; i < 32; ++i)
4765 if (n & 0x80000000UL)
4767 if (n & 0x7fffffffUL)
4778 /* Places additional restrictions on the register class to
4779 use when it is necessary to copy value X into a register
4783 preferred_reload_class (x, class)
4784 rtx x ATTRIBUTE_UNUSED;
4785 enum reg_class class;
4791 test_hard_reg_class (class, x)
4792 enum reg_class class;
4795 int regno = true_regnum (x);
4798 return TEST_HARD_REG_CLASS (class, regno);
4802 debug_hard_reg_set (set)
4806 for (i=0; i < FIRST_PSEUDO_REGISTER; ++i)
4808 if (TEST_HARD_REG_BIT (set, i))
4810 fprintf (stderr, "r%-2d ", i);
4813 fprintf (stderr, "\n");
4817 jump_over_one_insn_p (insn, dest)
4821 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
4824 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
4825 int dest_addr = INSN_ADDRESSES (uid);
4826 return dest_addr - jump_addr == 2;
4829 /* Returns 1 if a value of mode MODE can be stored starting with hard
4830 register number REGNO. On the enhanced core, anything larger than
4831 1 byte must start in even numbered register for "movw" to work
4832 (this way we don't have to check for odd registers everywhere). */
4835 avr_hard_regno_mode_ok (regno, mode)
4837 enum machine_mode mode;
4841 /* if (regno < 24 && !AVR_ENHANCED)
4843 return !(regno & 1);
4846 /* Returns 1 if we know register operand OP was 0 before INSN. */
4849 reg_was_0 (insn, op)
4854 return (optimize > 0 && insn && op && REG_P (op)
4855 && (link = find_reg_note (insn, REG_WAS_0, 0))
4856 /* Make sure the insn that stored the 0 is still present. */
4857 && ! INSN_DELETED_P (XEXP (link, 0))
4858 && GET_CODE (XEXP (link, 0)) != NOTE
4859 /* Make sure cross jumping didn't happen here. */
4860 && no_labels_between_p (XEXP (link, 0), insn)
4861 /* Make sure the reg hasn't been clobbered. */
4862 && ! reg_set_between_p (op, XEXP (link, 0), insn));
4865 /* Returns 1 if X is a valid address for an I/O register of size SIZE
4866 (1 or 2). Used for lds/sts -> in/out optimization. */
4869 io_address_p (x, size)
4873 return (optimize > 0 && GET_CODE (x) == CONST_INT
4874 && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size);
4877 /* Returns nonzero (bit number + 1) if X, or -X, is a constant power of 2. */
4880 const_int_pow2_p (x)
4883 if (GET_CODE (x) == CONST_INT)
4885 HOST_WIDE_INT d = INTVAL (x);
4886 HOST_WIDE_INT abs_d = (d >= 0) ? d : -d;
4887 return exact_log2 (abs_d) + 1;
4893 output_reload_inhi (insn, operands, len)
4894 rtx insn ATTRIBUTE_UNUSED;
4902 if (GET_CODE (operands[1]) == CONST_INT)
4904 int val = INTVAL (operands[1]);
4905 if ((val & 0xff) == 0)
4908 return (AS2 (mov,%A0,__zero_reg__) CR_TAB
4909 AS2 (ldi,%2,hi8(%1)) CR_TAB
4912 else if ((val & 0xff00) == 0)
4915 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
4916 AS2 (mov,%A0,%2) CR_TAB
4917 AS2 (mov,%B0,__zero_reg__));
4919 else if ((val & 0xff) == ((val & 0xff00) >> 8))
4922 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
4923 AS2 (mov,%A0,%2) CR_TAB
4928 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
4929 AS2 (mov,%A0,%2) CR_TAB
4930 AS2 (ldi,%2,hi8(%1)) CR_TAB
4936 output_reload_insisf (insn, operands, len)
4937 rtx insn ATTRIBUTE_UNUSED;
4941 rtx src = operands[1];
4942 int cnst = (GET_CODE (src) == CONST_INT);
4947 *len = 4 + ((INTVAL (src) & 0xff) != 0)
4948 + ((INTVAL (src) & 0xff00) != 0)
4949 + ((INTVAL (src) & 0xff0000) != 0)
4950 + ((INTVAL (src) & 0xff000000U) != 0);
4957 if (cnst && ((INTVAL (src) & 0xff) == 0))
4958 output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
4961 output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
4962 output_asm_insn (AS2 (mov, %A0, %2), operands);
4964 if (cnst && ((INTVAL (src) & 0xff00) == 0))
4965 output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
4968 output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
4969 output_asm_insn (AS2 (mov, %B0, %2), operands);
4971 if (cnst && ((INTVAL (src) & 0xff0000) == 0))
4972 output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
4975 output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
4976 output_asm_insn (AS2 (mov, %C0, %2), operands);
4978 if (cnst && ((INTVAL (src) & 0xff000000U) == 0))
4979 output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
4982 output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
4983 output_asm_insn (AS2 (mov, %D0, %2), operands);