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 char * ptrreg_to_str PARAMS ((int));
51 static 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 (void)
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)
325 int from ATTRIBUTE_UNUSED;
326 int to ATTRIBUTE_UNUSED;
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 *file, int size)
523 int interrupt_func_p;
530 if (avr_naked_function_p (current_function_decl))
532 fprintf (file, "/* prologue: naked */\n");
536 interrupt_func_p = interrupt_function_p (current_function_decl);
537 signal_func_p = signal_function_p (current_function_decl);
538 leaf_func_p = leaf_function_p ();
539 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
540 live_seq = sequent_regs_live ();
541 minimize = (TARGET_CALL_PROLOGUES
542 && !interrupt_func_p && !signal_func_p && live_seq);
544 last_insn_address = 0;
546 fprintf (file, "/* prologue: frame size=%d */\n", size);
548 if (interrupt_func_p)
550 fprintf (file,"\tsei\n");
553 if (interrupt_func_p | signal_func_p)
556 AS1 (push,__zero_reg__) CR_TAB
557 AS1 (push,__tmp_reg__) CR_TAB
558 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
559 AS1 (push,__tmp_reg__) CR_TAB
560 AS1 (clr,__zero_reg__) "\n");
566 AS2 (ldi,r28,lo8(%s - %d)) CR_TAB
567 AS2 (ldi,r29,hi8(%s - %d)) CR_TAB
568 AS2 (out,__SP_H__,r29) CR_TAB
569 AS2 (out,__SP_L__,r28) "\n"),
570 avr_init_stack, size, avr_init_stack, size);
574 else if (minimize && (frame_pointer_needed || live_seq > 6))
577 AS2 (ldi, r26, lo8(%d)) CR_TAB
578 AS2 (ldi, r27, hi8(%d)) CR_TAB), size, size);
580 fprintf (file, (AS2 (ldi, r30, pm_lo8(.L_%s_body)) CR_TAB
581 AS2 (ldi, r31, pm_hi8(.L_%s_body)) CR_TAB)
582 ,current_function_name, current_function_name);
588 fprintf (file, AS1 (jmp,__prologue_saves__+%d) "\n",
589 (18 - live_seq) * 2);
594 fprintf (file, AS1 (rjmp,__prologue_saves__+%d) "\n",
595 (18 - live_seq) * 2);
598 fprintf (file, ".L_%s_body:\n", current_function_name);
602 for (reg = 0; reg < 32; ++reg)
605 && (call_used_regs[reg]
606 && (interrupt_func_p || signal_func_p)
607 && !(reg == TMP_REGNO || reg == ZERO_REGNO)))
608 || (regs_ever_live[reg]
609 && (!call_used_regs[reg]
610 || interrupt_func_p || signal_func_p)
611 && ! (frame_pointer_needed
612 && (reg == REG_Y || reg == (REG_Y+1)))))
614 fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
618 if (frame_pointer_needed)
622 AS1 (push,r28) CR_TAB
623 AS1 (push,r29) CR_TAB
624 AS2 (in,r28,__SP_L__) CR_TAB
625 AS2 (in,r29,__SP_H__) "\n");
630 prologue_size += out_adj_frame_ptr (file, size);
632 if (interrupt_func_p)
634 prologue_size += out_set_stack_ptr (file, 1, 1);
636 else if (signal_func_p)
638 prologue_size += out_set_stack_ptr (file, 0, 0);
642 prologue_size += out_set_stack_ptr (file, -1, -1);
648 fprintf (file, "/* prologue end (size=%d) */\n", prologue_size);
651 /* Output function epilogue */
654 function_epilogue (FILE *file, int size)
657 int interrupt_func_p;
665 if (avr_naked_function_p (current_function_decl))
667 fprintf (file, "/* epilogue: naked */\n");
671 interrupt_func_p = interrupt_function_p (current_function_decl);
672 signal_func_p = signal_function_p (current_function_decl);
673 leaf_func_p = leaf_function_p ();
674 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
675 function_size = (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
676 - INSN_ADDRESSES (INSN_UID (get_insns ())));
677 live_seq = sequent_regs_live ();
678 minimize = (TARGET_CALL_PROLOGUES
679 && !interrupt_func_p && !signal_func_p && live_seq);
682 fprintf (file, "/* epilogue: frame size=%d */\n", size);
685 fprintf (file, "__stop_progIi__:\n\trjmp __stop_progIi__\n");
688 else if (minimize && (frame_pointer_needed || live_seq > 4))
690 fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
692 if (frame_pointer_needed)
694 epilogue_size += out_adj_frame_ptr (file, -size);
698 fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
699 AS2 (in , r29, __SP_H__) CR_TAB));
705 fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
706 (18 - live_seq) * 2);
711 fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
712 (18 - live_seq) * 2);
718 if (frame_pointer_needed)
723 epilogue_size += out_adj_frame_ptr (file, -size);
725 if (interrupt_func_p | signal_func_p)
727 epilogue_size += out_set_stack_ptr (file, -1, 0);
731 epilogue_size += out_set_stack_ptr (file, -1, -1);
740 for (reg = 31; reg >= 0; --reg)
743 && (call_used_regs[reg]
744 && (interrupt_func_p || signal_func_p)
745 && !(reg == TMP_REGNO || reg == ZERO_REGNO)))
746 || (regs_ever_live[reg]
747 && (!call_used_regs[reg]
748 || interrupt_func_p || signal_func_p)
749 && ! (frame_pointer_needed
750 && (reg == REG_Y || reg == (REG_Y+1)))))
752 fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
757 if (interrupt_func_p | signal_func_p)
760 AS1 (pop,__tmp_reg__) CR_TAB
761 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
762 AS1 (pop,__tmp_reg__) CR_TAB
763 AS1 (pop,__zero_reg__) "\n");
765 fprintf (file, "\treti\n");
768 fprintf (file, "\tret\n");
772 fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
773 fprintf (file, "/* function %s size %d (%d) */\n", current_function_name,
774 prologue_size + function_size + epilogue_size, function_size);
775 commands_in_file += prologue_size + function_size + epilogue_size;
776 commands_in_prologues += prologue_size;
777 commands_in_epilogues += epilogue_size;
781 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
782 machine for a memory operand of mode MODE. */
785 legitimate_address_p (mode, x, strict)
786 enum machine_mode mode;
791 if (TARGET_ALL_DEBUG)
793 fprintf (stderr, "mode: (%s) %s %s %s %s:",
795 strict ? "(strict)": "",
796 reload_completed ? "(reload_completed)": "",
797 reload_in_progress ? "(reload_in_progress)": "",
798 reg_renumber ? "(reg_renumber)" : "");
799 if (GET_CODE (x) == PLUS
800 && REG_P (XEXP (x, 0))
801 && GET_CODE (XEXP (x, 1)) == CONST_INT
802 && INTVAL (XEXP (x, 1)) >= 0
803 && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
806 fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
807 true_regnum (XEXP (x, 0)));
810 if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
811 : REG_OK_FOR_BASE_NOSTRICT_P (x)))
813 else if (CONSTANT_ADDRESS_P (x))
815 else if (GET_CODE (x) == PLUS
816 && REG_P (XEXP (x, 0))
817 && GET_CODE (XEXP (x, 1)) == CONST_INT
818 && INTVAL (XEXP (x, 1)) >= 0)
820 int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
824 || REGNO (XEXP (x,0)) == REG_Y
825 || REGNO (XEXP (x,0)) == REG_Z)
827 if (XEXP (x,0) == frame_pointer_rtx
828 || XEXP (x,0) == arg_pointer_rtx)
831 else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
834 else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
835 && REG_P (XEXP (x, 0))
836 && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
837 : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
841 if (TARGET_ALL_DEBUG)
843 fprintf (stderr, " ret = %c\n", r);
848 /* Attempts to replace X with a valid
849 memory address for an operand of mode MODE */
852 legitimize_address (x, oldx, mode)
855 enum machine_mode mode;
858 if (TARGET_ALL_DEBUG)
860 fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
864 if (GET_CODE (oldx) == PLUS
865 && REG_P (XEXP (oldx,0)))
867 if (REG_P (XEXP (oldx,1)))
868 x = force_reg (GET_MODE (oldx), oldx);
869 else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
871 int offs = INTVAL (XEXP (oldx,1));
872 if (frame_pointer_rtx != XEXP (oldx,0))
873 if (offs > MAX_LD_OFFSET (mode))
875 if (TARGET_ALL_DEBUG)
876 fprintf (stderr, "force_reg (big offset)\n");
877 x = force_reg (GET_MODE (oldx), oldx);
885 /* Return a pointer register name as a string */
888 ptrreg_to_str (regno)
893 case REG_X: return "X";
894 case REG_Y: return "Y";
895 case REG_Z: return "Z";
897 fatal ("register r%d isn't a pointer\n", regno);
902 /* Return the condition name as a string.
903 Used in conditional jump constructing */
916 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
921 fatal ("Internal compiler bug: command `bgt'");
923 fatal ("Internal compiler bug: command `ble'");
925 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
932 fatal ("Internal compiler bug: command `bgtu'");
934 fatal ("Internal compiler bug: command `bleu'");
942 /* Output ADDR to FILE as address */
945 print_operand_address (file, addr)
949 switch (GET_CODE (addr))
952 fprintf (file, ptrreg_to_str (REGNO (addr)));
956 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
960 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
964 if (CONSTANT_ADDRESS_P (addr)
965 && (SYMBOL_REF_FLAG (addr) || GET_CODE (addr) == LABEL_REF))
967 fprintf (file, "pm(");
968 output_addr_const (file,addr);
972 output_addr_const (file, addr);
977 /* Output X as assembler operand to file FILE */
980 print_operand (file, x, code)
987 if (code >= 'A' && code <= 'D')
992 if (x == zero_reg_rtx)
993 fprintf (file,"__zero_reg__");
995 fprintf (file, reg_names[true_regnum (x) + abcd]);
997 else if (GET_CODE (x) == CONST_INT)
998 fprintf (file, "%d", INTVAL (x) + abcd);
999 else if (GET_CODE (x) == MEM)
1001 rtx addr = XEXP (x,0);
1003 if (CONSTANT_P (addr) && abcd)
1006 output_address (addr);
1007 fprintf (file, ")+%d", abcd);
1009 else if (GET_CODE (addr) == PLUS)
1011 print_operand_address (file, XEXP (addr,0));
1012 if (REGNO (XEXP (addr, 0)) == REG_X)
1013 fatal_insn ("Internal compiler bug.\nBad address:"
1016 print_operand (file, XEXP (addr,1), code);
1019 print_operand_address (file, addr);
1021 else if (GET_CODE (x) == CONST_DOUBLE)
1025 if (GET_MODE (x) != SFmode)
1026 fatal_insn ("Internal compiler bug. Unknown mode:", x);
1027 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1028 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1029 asm_fprintf (file, "0x%lx", val);
1031 else if (code == 'j')
1032 asm_fprintf (file, cond_string (GET_CODE (x)));
1033 else if (code == 'k')
1034 asm_fprintf (file, cond_string (reverse_condition (GET_CODE (x))));
1036 print_operand_address (file, x);
1039 /* Recognize operand OP of mode MODE used in call instructions */
1042 call_insn_operand (op, mode)
1044 enum machine_mode mode ATTRIBUTE_UNUSED;
1046 if (GET_CODE (op) == MEM)
1048 rtx inside = XEXP (op, 0);
1049 if (register_operand (inside, Pmode))
1051 if (CONSTANT_ADDRESS_P (inside))
1057 /* Update the condition code in the INSN. */
1060 notice_update_cc (body, insn)
1061 rtx body ATTRIBUTE_UNUSED;
1066 switch (get_attr_cc (insn))
1069 /* Insn does not affect CC at all. */
1077 set = single_set (insn);
1081 cc_status.flags |= CC_NO_OVERFLOW;
1082 cc_status.value1 = SET_DEST (set);
1087 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1088 The V flag may or may not be known but that's ok because
1089 alter_cond will change tests to use EQ/NE. */
1090 set = single_set (insn);
1094 cc_status.value1 = SET_DEST (set);
1095 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1100 set = single_set (insn);
1103 cc_status.value1 = SET_SRC (set);
1107 /* Insn doesn't leave CC in a usable state. */
1110 /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1111 set = single_set (insn);
1114 rtx src = SET_SRC (set);
1116 if (GET_CODE (src) == ASHIFTRT
1117 && GET_MODE (src) == QImode)
1119 rtx x = XEXP (src, 1);
1121 if (GET_CODE (x) == CONST_INT
1124 cc_status.value1 = SET_DEST (set);
1125 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1133 /* Return maximum number of consecutive registers of
1134 class CLASS needed to hold a value of mode MODE. */
1137 class_max_nregs (class, mode)
1138 enum reg_class class ATTRIBUTE_UNUSED;
1139 enum machine_mode mode;
1141 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1144 /* Choose mode for jump insn:
1145 1 - relative jump in range -63 <= x <= 62 ;
1146 2 - relative jump in range -2046 <= x <= 2045 ;
1147 3 - absolute jump (only for ATmega[16]03). */
1150 avr_jump_mode (x,insn)
1151 rtx x; /* jump operand */
1152 rtx insn; /* jump insn */
1154 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1155 ? XEXP (x, 0) : x));
1156 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1157 int jump_distance = cur_addr - dest_addr;
1159 if (-63 <= jump_distance && jump_distance <= 62)
1161 else if (-2046 <= jump_distance && jump_distance <= 2045)
1169 /* return a AVR condition jump commands.
1170 LEN is a number returned by avr_jump_mode function. */
1173 ret_cond_branch (cond,len)
1180 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1181 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1183 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1184 AS1 (brmi,_PC_+2) CR_TAB
1186 (AS1 (breq,_PC_+6) CR_TAB
1187 AS1 (brmi,_PC_+4) CR_TAB
1191 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1193 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1194 AS1 (brlt,_PC_+2) CR_TAB
1196 (AS1 (breq,_PC_+6) CR_TAB
1197 AS1 (brlt,_PC_+4) CR_TAB
1200 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1202 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1203 AS1 (brlo,_PC_+2) CR_TAB
1205 (AS1 (breq,_PC_+6) CR_TAB
1206 AS1 (brlo,_PC_+4) CR_TAB
1209 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1210 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1212 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1213 AS1 (brpl,_PC_+2) CR_TAB
1215 (AS1 (breq,_PC_+2) CR_TAB
1216 AS1 (brpl,_PC_+4) CR_TAB
1219 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1221 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1222 AS1 (brge,_PC_+2) CR_TAB
1224 (AS1 (breq,_PC_+2) CR_TAB
1225 AS1 (brge,_PC_+4) CR_TAB
1228 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1230 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1231 AS1 (brsh,_PC_+2) CR_TAB
1233 (AS1 (breq,_PC_+2) CR_TAB
1234 AS1 (brsh,_PC_+4) CR_TAB
1240 return AS1 (br%j1,%0);
1242 return (AS1 (br%k1,_PC_+2) CR_TAB
1245 return (AS1 (br%k1,_PC_+4) CR_TAB
1252 /* Predicate function for immediate operand which fits to byte (8bit) */
1255 byte_immediate_operand (op, mode)
1257 enum machine_mode mode ATTRIBUTE_UNUSED;
1259 return (GET_CODE (op) == CONST_INT
1260 && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1263 /* Output all insn addresses and their sizes into the assembly language
1264 output file. This is helpful for debugging whether the length attributes
1265 in the md file are correct.
1266 Output insn cost for next insn. */
1269 final_prescan_insn (insn, operand, num_operands)
1270 rtx insn, *operand ATTRIBUTE_UNUSED;
1271 int num_operands ATTRIBUTE_UNUSED;
1273 int uid = INSN_UID (insn);
1275 if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1277 fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1278 INSN_ADDRESSES (uid),
1279 INSN_ADDRESSES (uid) - last_insn_address,
1280 rtx_cost (PATTERN (insn), INSN));
1282 last_insn_address = INSN_ADDRESSES (uid);
1284 if (TARGET_RTL_DUMP)
1286 fprintf (asm_out_file, "/*****************\n");
1287 print_rtl_single (asm_out_file, insn);
1288 fprintf (asm_out_file, "*****************/\n");
1292 /* return 1 if undefined,
1293 1 if always true or always false */
1296 avr_simplify_comparision_p (mode, operator, x)
1297 enum machine_mode mode;
1301 unsigned int max = (mode == QImode ? 0xff :
1302 mode == HImode ? 0xffff :
1303 mode == SImode ? 0xffffffffU : 0);
1304 if (max && operator && GET_CODE (x) == CONST_INT)
1306 if (unsigned_condition (operator) != operator)
1309 if (max != (INTVAL (x) & max)
1310 && INTVAL (x) != 0xff)
1317 /* Returns nonzero if REGNO is the number of a hard
1318 register in which function arguments are sometimes passed. */
1321 function_arg_regno_p(r)
1324 return (r >= 8 && r <= 25);
1327 /* Initializing the variable cum for the state at the beginning
1328 of the argument list. */
1331 init_cumulative_args (cum, fntype, libname, indirect)
1332 CUMULATIVE_ARGS *cum;
1335 int indirect ATTRIBUTE_UNUSED;
1338 cum->regno = FIRST_CUM_REG;
1341 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1342 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1343 != void_type_node));
1349 /* Returns the number of registers to allocate for a function argument. */
1352 avr_num_arg_regs (mode, type)
1353 enum machine_mode mode;
1358 if (mode == BLKmode)
1359 size = int_size_in_bytes (type);
1361 size = GET_MODE_SIZE (mode);
1363 /* Align all function arguments to start in even-numbered registers,
1364 for "movw" on the enhanced core (to keep call conventions the same
1365 on all devices, do it even if "movw" is not available). Odd-sized
1366 arguments leave holes above them - registers still available for
1367 other uses. Use -mpack-args for compatibility with old asm code
1368 (the new convention will still be used for libgcc calls). */
1370 if (!(type && TARGET_PACK_ARGS))
1376 /* Controls whether a function argument is passed
1377 in a register, and which register. */
1380 function_arg (cum, mode, type, named)
1381 CUMULATIVE_ARGS *cum;
1382 enum machine_mode mode;
1384 int named ATTRIBUTE_UNUSED;
1386 int bytes = avr_num_arg_regs (mode, type);
1388 if (cum->nregs && bytes <= cum->nregs)
1389 return gen_rtx (REG, mode, cum->regno - bytes);
1394 /* Update the summarizer variable CUM to advance past an argument
1395 in the argument list. */
1398 function_arg_advance (cum, mode, type, named)
1399 CUMULATIVE_ARGS *cum; /* current arg information */
1400 enum machine_mode mode; /* current arg mode */
1401 tree type; /* type of the argument or 0 if lib support */
1402 int named ATTRIBUTE_UNUSED; /* whether or not the argument was named */
1404 int bytes = avr_num_arg_regs (mode, type);
1406 cum->nregs -= bytes;
1407 cum->regno -= bytes;
1409 if (cum->nregs <= 0)
1412 cum->regno = FIRST_CUM_REG;
1416 /***********************************************************************
1417 Functions for outputting various mov's for a various modes
1418 ************************************************************************/
1420 output_movqi (insn, operands, l)
1426 rtx dest = operands[0];
1427 rtx src = operands[1];
1435 if (register_operand (dest, QImode))
1437 if (register_operand (src, QImode)) /* mov r,r */
1439 if (test_hard_reg_class (STACK_REG, dest))
1440 return AS2 (out,%0,%1);
1441 else if (test_hard_reg_class (STACK_REG, src))
1442 return AS2 (in,%0,%1);
1444 return AS2 (mov,%0,%1);
1446 else if (CONSTANT_P (src))
1448 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1449 return AS2 (ldi,%0,lo8(%1));
1451 if (GET_CODE (src) == CONST_INT)
1453 if (src == const0_rtx) /* mov r,L */
1454 return AS1 (clr,%0);
1455 else if (src == const1_rtx)
1457 if (reg_was_0 (insn, operands[0]))
1458 return AS1 (inc,%0 ; reg_was_0);
1461 return (AS1 (clr,%0) CR_TAB
1464 else if (src == const2_rtx)
1466 if (reg_was_0 (insn, operands[0]))
1469 return (AS1 (inc,%0 ; reg_was_0) CR_TAB
1474 return (AS1 (clr,%0) CR_TAB
1478 else if (src == constm1_rtx)
1480 /* Immediate constants -1 to any register */
1481 if (reg_was_0 (insn, operands[0]))
1482 return AS1 (dec,%0 ; reg_was_0);
1485 return (AS1 (clr,%0) CR_TAB
1491 /* Last resort, larger than loading from memory. */
1493 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1494 AS2 (ldi,r31,lo8(%1)) CR_TAB
1495 AS2 (mov,%0,r31) CR_TAB
1496 AS2 (mov,r31,__tmp_reg__));
1498 else if (GET_CODE (src) == MEM)
1499 return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1501 else if (GET_CODE (dest) == MEM)
1506 if (operands[1] == const0_rtx)
1508 operands[1] = zero_reg_rtx;
1512 template = out_movqi_mr_r (insn, operands, real_l);
1515 output_asm_insn (template, operands);
1518 operands[1] = const0_rtx;
1525 output_movhi (insn, operands, l)
1531 rtx dest = operands[0];
1532 rtx src = operands[1];
1538 if (register_operand (dest, HImode))
1540 if (register_operand (src, HImode)) /* mov r,r */
1542 if (test_hard_reg_class (STACK_REG, dest))
1544 if (TARGET_TINY_STACK)
1547 return AS2 (out,__SP_L__,%A1);
1549 else if (TARGET_NO_INTERRUPTS)
1552 return (AS2 (out,__SP_H__,%B1) CR_TAB
1553 AS2 (out,__SP_L__,%A1));
1557 return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB
1559 AS2 (out,__SP_H__,%B1) CR_TAB
1560 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1561 AS2 (out,__SP_L__,%A1));
1563 else if (test_hard_reg_class (STACK_REG, src))
1566 return (AS2 (in,%A0,__SP_L__) CR_TAB
1567 AS2 (in,%B0,__SP_H__));
1573 return (AS2 (movw,%0,%1));
1576 if (true_regnum (operands[0]) > true_regnum (operands[1]))
1579 return (AS2 (mov,%B0,%B1) CR_TAB
1585 return (AS2 (mov,%A0,%A1) CR_TAB
1589 else if (CONSTANT_P (src))
1591 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1594 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1595 AS2 (ldi,%B0,hi8(%1)));
1598 if (GET_CODE (src) == CONST_INT)
1600 if (src == const0_rtx) /* mov r,L */
1603 return (AS1 (clr,%A0) CR_TAB
1606 else if (src == const1_rtx)
1608 if (reg_was_0 (insn, operands[0]))
1611 return AS1 (inc,%0 ; reg_was_0);
1615 return (AS1 (clr,%0) CR_TAB
1618 else if (src == const2_rtx)
1620 if (reg_was_0 (insn, operands[0]))
1623 return (AS1 (inc,%0 ; reg_was_0) CR_TAB
1628 return (AS1 (clr,%0) CR_TAB
1632 else if (src == constm1_rtx)
1634 /* Immediate constants -1 to any register */
1635 if (reg_was_0 (insn, operands[0]))
1638 return (AS1 (dec,%A0 ; reg_was_0) CR_TAB
1643 return (AS1 (clr,%0) CR_TAB
1644 AS1 (dec,%A0) CR_TAB
1647 if ((INTVAL (src) & 0xff) == 0)
1650 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1651 AS1 (clr,%A0) CR_TAB
1652 AS2 (ldi,r31,hi8(%1)) CR_TAB
1653 AS2 (mov,%B0,r31) CR_TAB
1654 AS2 (mov,r31,__tmp_reg__));
1656 else if ((INTVAL (src) & 0xff00) == 0)
1659 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1660 AS2 (ldi,r31,lo8(%1)) CR_TAB
1661 AS2 (mov,%A0,r31) CR_TAB
1662 AS1 (clr,%B0) CR_TAB
1663 AS2 (mov,r31,__tmp_reg__));
1667 /* Last resort, equal to loading from memory. */
1669 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1670 AS2 (ldi,r31,lo8(%1)) CR_TAB
1671 AS2 (mov,%A0,r31) CR_TAB
1672 AS2 (ldi,r31,hi8(%1)) CR_TAB
1673 AS2 (mov,%B0,r31) CR_TAB
1674 AS2 (mov,r31,__tmp_reg__));
1676 else if (GET_CODE (src) == MEM)
1677 return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1679 else if (GET_CODE (dest) == MEM)
1684 if (operands[1] == const0_rtx)
1686 operands[1] = zero_reg_rtx;
1690 template = out_movhi_mr_r (insn, operands, real_l);
1693 output_asm_insn (template, operands);
1696 operands[1] = const0_rtx;
1699 fatal_insn ("Invalid insn:", insn);
1704 out_movqi_r_mr (insn, op, l)
1707 int *l; /* instruction length */
1716 if (CONSTANT_ADDRESS_P (x))
1718 if (io_address_p (x, 1))
1721 return AS2 (in,%0,%1-0x20);
1724 return AS2 (lds,%0,%1);
1726 /* memory access by reg+disp */
1727 else if (GET_CODE (x) == PLUS
1728 && REG_P (XEXP (x,0))
1729 && GET_CODE (XEXP (x,1)) == CONST_INT)
1731 if((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (op[1]))) >= 63)
1733 int disp = INTVAL (XEXP (x,1));
1734 if (REGNO (XEXP (x,0)) != REG_Y)
1735 fatal_insn ("Incorrect insn:",insn);
1736 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (op[1])))
1739 op[4] = XEXP (x, 1);
1740 return (AS2 (adiw, r28, %4-63) CR_TAB
1741 AS2 (ldd, %0,Y+63) CR_TAB
1742 AS2 (sbiw, r28, %4-63));
1748 return (AS2 (subi, r28, lo8(-%4)) CR_TAB
1749 AS2 (sbci, r29, hi8(-%4)) CR_TAB
1750 AS2 (ld, %0,Y) CR_TAB
1751 AS2 (subi, r28, lo8(%4)) CR_TAB
1752 AS2 (sbci, r29, hi8(%4)));
1755 else if (REGNO (XEXP (x,0)) == REG_X)
1757 op[4] = XEXP (x, 1);
1758 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1759 it but I have this situation with extremal optimizing options. */
1760 if (reg_overlap_mentioned_p (op[0],XEXP (x,0))
1761 || reg_unused_after (insn, XEXP (x,0)))
1764 return (AS2 (adiw,r26,%4) CR_TAB
1768 return (AS2 (adiw,r26,%4) CR_TAB
1769 AS2 (ld,%0,X) CR_TAB
1773 return AS2 (ldd,%0,%1);
1776 return AS2 (ld,%0,%1);
1780 out_movhi_r_mr (insn, op, l)
1783 int *l; /* instruction length */
1785 int reg_dest = true_regnum (op[0]);
1786 int reg_base = true_regnum (XEXP (op[1], 0));
1794 if (reg_dest == reg_base) /* R = (R) */
1797 return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1798 AS2 (ld,%B0,%1) CR_TAB
1799 AS2 (mov,%A0,__tmp_reg__));
1801 else if (reg_base == REG_X) /* (R26) */
1803 if (reg_unused_after (insn, XEXP (op[1],0)))
1806 return (AS2 (ld,%A0,X+) CR_TAB
1810 return (AS2 (ld,%A0,X+) CR_TAB
1811 AS2 (ld,%B0,X) CR_TAB
1817 return (AS2 (ld,%A0,%1) CR_TAB
1818 AS2 (ldd,%B0,%1+1));
1821 else if (GET_CODE (XEXP (op[1],0)) == PLUS) /* (R + i) */
1823 int disp = INTVAL(XEXP (XEXP (op[1], 0), 1));
1824 int reg_base = true_regnum (XEXP (XEXP (op[1], 0), 0));
1826 if (disp > MAX_LD_OFFSET (GET_MODE (op[1])))
1828 rtx x = XEXP (op[1], 0);
1829 op[4] = XEXP (x, 1);
1831 if (REGNO (XEXP (x,0)) != REG_Y)
1832 fatal_insn ("Incorrect insn:",insn);
1834 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (op[1])))
1837 return (AS2 (adiw,r28,%4-62) CR_TAB
1838 AS2 (ldd,%A0,Y+62) CR_TAB
1839 AS2 (ldd,%B0,Y+63) CR_TAB
1840 AS2 (sbiw,r28,%4-62));
1845 return (AS2 (subi,r28,lo8(-%4)) CR_TAB
1846 AS2 (sbci,r29,hi8(-%4)) CR_TAB
1847 AS2 (ld,%A0,Y) CR_TAB
1848 AS2 (ldd,%B0,Y+1) CR_TAB
1849 AS2 (subi,r28,lo8(%4)) CR_TAB
1850 AS2 (sbci,r29,hi8(%4)));
1853 if (reg_base == REG_X)
1855 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1856 it but I have this situation with extremal
1857 optimization options. */
1859 op[4] = XEXP (XEXP (op[1],0), 1);
1861 if (reg_base == reg_dest)
1864 return (AS2 (adiw,r26,%4) CR_TAB
1865 AS2 (ld,__tmp_reg__,X+) CR_TAB
1866 AS2 (ld,%B0,X) CR_TAB
1867 AS2 (mov,%A0,__tmp_reg__));
1870 if (INTVAL (op[4]) == 63)
1873 return (AS2 (adiw,r26,%4) CR_TAB
1874 AS2 (ld,%A0,X+) CR_TAB
1875 AS2 (ld,%B0,X) CR_TAB
1876 AS2 (subi,r26,%4+1) CR_TAB
1880 return (AS2 (adiw,r26,%4) CR_TAB
1881 AS2 (ld,%A0,X+) CR_TAB
1882 AS2 (ld,%B0,X) CR_TAB
1883 AS2 (sbiw,r26,%4+1));
1886 if (reg_base == reg_dest)
1889 return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
1890 AS2 (ldd,%B0,%B1) CR_TAB
1891 AS2 (mov,%A0,__tmp_reg__));
1895 return (AS2 (ldd,%A0,%A1) CR_TAB
1898 else if (GET_CODE (XEXP (op[1],0)) == PRE_DEC) /* (--R) */
1900 if (reg_overlap_mentioned_p (op[0], XEXP (XEXP (op[1],0),0)))
1901 fatal_insn ("Incorrect insn:", insn);
1904 return (AS2 (ld,%B0,%1) CR_TAB
1907 else if (GET_CODE (XEXP (op[1],0)) == POST_INC) /* (R++) */
1909 if (reg_overlap_mentioned_p (op[0], XEXP (XEXP (op[1],0),0)))
1910 fatal_insn ("Incorrect insn:", insn);
1913 return (AS2 (ld,%A0,%1) CR_TAB
1916 else if (CONSTANT_ADDRESS_P (XEXP (op[1],0)))
1919 return (AS2 (lds,%A0,%A1) CR_TAB
1923 fatal_insn ("Unknown move insn:",insn);
1928 out_movsi_r_mr (insn,op,l)
1931 int *l; /* instruction length */
1933 int reg_dest=true_regnum (op[0]);
1934 int reg_base=true_regnum (XEXP (op[1],0));
1942 if (reg_base == REG_X) /* (R26) */
1944 if (reg_dest == REG_X)
1945 return *l=6, (AS2 (adiw,r26,3) CR_TAB
1946 AS2 (ld,%D0,X) CR_TAB
1947 AS2 (ld,%C0,-X) CR_TAB
1948 AS2 (ld,__tmp_reg__,-X) CR_TAB
1949 AS2 (ld,%A0,-X) CR_TAB
1950 AS2 (mov,%B0,__tmp_reg__));
1951 else if (reg_dest == REG_X - 2)
1952 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
1953 AS2 (ld,%B0,X+) CR_TAB
1954 AS2 (ld,__tmp_reg__,X+) CR_TAB
1955 AS2 (ld,%D0,X) CR_TAB
1956 AS2 (mov,%C0,__tmp_reg__));
1957 else if (reg_unused_after (insn,XEXP (op[1],0)))
1958 return *l=4, (AS2 (ld,%A0,X+) CR_TAB
1959 AS2 (ld,%B0,X+) CR_TAB
1960 AS2 (ld,%C0,X+) CR_TAB
1963 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
1964 AS2 (ld,%B0,X+) CR_TAB
1965 AS2 (ld,%C0,X+) CR_TAB
1966 AS2 (ld,%D0,X) CR_TAB
1971 if (reg_dest == reg_base)
1972 return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
1973 AS2 (ldd,%C0,%1+2) CR_TAB
1974 AS2 (ldd,__tmp_reg__,%1+1) CR_TAB
1975 AS2 (ld,%A0,%1) CR_TAB
1976 AS2 (mov,%B0,__tmp_reg__));
1977 else if (reg_base == reg_dest + 2)
1978 return *l=5, (AS2 (ld ,%A0,%1) CR_TAB
1979 AS2 (ldd,%B0,%1+1) CR_TAB
1980 AS2 (ldd,__tmp_reg__,%1+2) CR_TAB
1981 AS2 (ldd,%D0,%1+3) CR_TAB
1982 AS2 (mov,%C0,__tmp_reg__));
1984 return *l=4, (AS2 (ld ,%A0,%1) CR_TAB
1985 AS2 (ldd,%B0,%1+1) CR_TAB
1986 AS2 (ldd,%C0,%1+2) CR_TAB
1987 AS2 (ldd,%D0,%1+3));
1990 else if (GET_CODE (XEXP (op[1],0)) == PLUS) /* (R + i) */
1992 int disp = INTVAL(XEXP (XEXP (op[1],0), 1));
1994 if (disp > MAX_LD_OFFSET (GET_MODE (op[1])))
1996 rtx x = XEXP (op[1],0);
1997 if (REGNO (XEXP (x,0)) != REG_Y)
1998 fatal_insn ("Incorrect insn:",insn);
1999 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (op[1])))
2001 op[4] = GEN_INT (disp - 60);
2002 return *l=6,(AS2 (adiw, r28, %4) CR_TAB
2003 AS2 (ldd, %A0,Y+60) CR_TAB
2004 AS2 (ldd, %B0,Y+61) CR_TAB
2005 AS2 (ldd, %C0,Y+62) CR_TAB
2006 AS2 (ldd, %D0,Y+63) CR_TAB
2007 AS2 (sbiw, r28, %4));
2012 return *l=8,(AS2 (subi, r28, lo8(-%4)) CR_TAB
2013 AS2 (sbci, r29, hi8(-%4)) CR_TAB
2014 AS2 (ld, %A0,Y) CR_TAB
2015 AS2 (ldd, %B0,Y+1) CR_TAB
2016 AS2 (ldd, %C0,Y+2) CR_TAB
2017 AS2 (ldd, %D0,Y+3) CR_TAB
2018 AS2 (subi, r28, lo8(%4)) CR_TAB
2019 AS2 (sbci, r29, hi8(%4)));
2023 reg_base = true_regnum (XEXP (XEXP (op[1],0), 0));
2024 if (reg_dest == reg_base)
2025 return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2026 AS2 (ldd,%C0,%C1) CR_TAB
2027 AS2 (ldd,__tmp_reg__,%B1) CR_TAB
2028 AS2 (ldd,%A0,%A1) CR_TAB
2029 AS2 (mov,%B0,__tmp_reg__));
2030 else if (reg_dest == reg_base - 2)
2031 return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2032 AS2 (ldd,%B0,%B1) CR_TAB
2033 AS2 (ldd,__tmp_reg__,%C1) CR_TAB
2034 AS2 (ldd,%D0,%D1) CR_TAB
2035 AS2 (mov,%C0,__tmp_reg__));
2036 return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2037 AS2 (ldd,%B0,%B1) CR_TAB
2038 AS2 (ldd,%C0,%C1) CR_TAB
2041 else if (GET_CODE (XEXP (op[1],0)) == PRE_DEC) /* (--R) */
2042 return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2043 AS2 (ld,%C0,%1) CR_TAB
2044 AS2 (ld,%B0,%1) CR_TAB
2046 else if (GET_CODE (XEXP (op[1],0)) == POST_INC) /* (R++) */
2047 return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2048 AS2 (ld,%B0,%1) CR_TAB
2049 AS2 (ld,%C0,%1) CR_TAB
2051 else if (CONSTANT_ADDRESS_P (XEXP (op[1],0)))
2052 return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2053 AS2 (lds,%B0,%B1) CR_TAB
2054 AS2 (lds,%C0,%C1) CR_TAB
2057 fatal_insn ("Unknown move insn:",insn);
2062 out_movsi_mr_r (insn,op,l)
2067 int reg_base = true_regnum (XEXP (op[0],0));
2068 int reg_dest = true_regnum (op[1]);
2074 if (CONSTANT_ADDRESS_P (XEXP (op[0],0)))
2075 return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2076 AS2 (sts,%B0,%B1) CR_TAB
2077 AS2 (sts,%C0,%C1) CR_TAB
2079 if (reg_base > 0) /* (r) */
2081 if (reg_base == REG_X) /* (R26) */
2083 if (reg_dest == REG_X)
2085 if (reg_unused_after (insn,XEXP (op[0],0)))
2086 return *l=5, (AS2 (mov,__tmp_reg__,%B1) CR_TAB
2087 AS2 (st,%0+,%A1) CR_TAB
2088 AS2 (st,%0+,__tmp_reg__) CR_TAB
2089 AS2 (st,%0+,%C1) CR_TAB
2092 return *l=6, (AS2 (mov,__tmp_reg__,%B1) CR_TAB
2093 AS2 (st,%0+,%A1) CR_TAB
2094 AS2 (st,%0+,__tmp_reg__) CR_TAB
2095 AS2 (st,%0+,%C1) CR_TAB
2096 AS2 (st,%0,%D1) CR_TAB
2099 else if (reg_base == reg_dest+2)
2101 if (reg_unused_after (insn,XEXP (op[0],0)))
2102 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2103 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2104 AS2 (st,%0+,%A1) CR_TAB
2105 AS2 (st,%0+,%B1) CR_TAB
2106 AS2 (st,%0+,__zero_reg__) CR_TAB
2107 AS2 (st,%0,__tmp_reg__) CR_TAB
2108 AS1 (clr,__zero_reg__));
2110 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2111 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2112 AS2 (st,%0+,%A1) CR_TAB
2113 AS2 (st,%0+,%B1) CR_TAB
2114 AS2 (st,%0+,__zero_reg__) CR_TAB
2115 AS2 (st,%0,__tmp_reg__) CR_TAB
2116 AS1 (clr,__zero_reg__) CR_TAB
2119 return *l=5, (AS2 (st,%0+,%A1) CR_TAB
2120 AS2 (st,%0+,%B1) CR_TAB
2121 AS2 (st,%0+,%C1) CR_TAB
2122 AS2 (st,%0,%D1) CR_TAB
2126 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2127 AS2 (std,%0+1,%B1) CR_TAB
2128 AS2 (std,%0+2,%C1) CR_TAB
2129 AS2 (std,%0+3,%D1));
2131 else if (GET_CODE (XEXP (op[0],0)) == PLUS) /* (R + i) */
2133 int disp = INTVAL(XEXP (XEXP (op[0],0), 1));
2134 if (disp > MAX_LD_OFFSET (GET_MODE (op[0])))
2136 rtx x = XEXP (op[0],0);
2137 if (REGNO (XEXP (x,0)) != REG_Y)
2138 fatal_insn ("Incorrect insn:",insn);
2139 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (op[0])))
2141 op[4] = GEN_INT (disp - 60);
2142 return *l=6,(AS2 (adiw, r28, %4) CR_TAB
2143 AS2 (std, Y+60,%A1) CR_TAB
2144 AS2 (std, Y+61,%B1) CR_TAB
2145 AS2 (std, Y+62,%C1) CR_TAB
2146 AS2 (std, Y+63,%D1) CR_TAB
2147 AS2 (sbiw, r28, %4));
2152 return *l=8,(AS2 (subi, r28, lo8(-%4)) CR_TAB
2153 AS2 (sbci, r29, hi8(-%4)) CR_TAB
2154 AS2 (st, Y,%A1) CR_TAB
2155 AS2 (std, Y+1,%B1) CR_TAB
2156 AS2 (std, Y+2,%C1) CR_TAB
2157 AS2 (std, Y+3,%D1) CR_TAB
2158 AS2 (subi, r28, lo8(%4)) CR_TAB
2159 AS2 (sbci, r29, hi8(%4)));
2162 return *l=4, (AS2 (std,%A0,%A1) CR_TAB
2163 AS2 (std,%B0,%B1) CR_TAB
2164 AS2 (std,%C0,%C1) CR_TAB
2167 else if (GET_CODE (XEXP (op[0],0)) == PRE_DEC) /* (--R) */
2168 return *l=4, (AS2 (st,%0,%D1) CR_TAB
2169 AS2 (st,%0,%C1) CR_TAB
2170 AS2 (st,%0,%B1) CR_TAB
2172 else if (GET_CODE (XEXP (op[0],0)) == POST_INC) /* (R++) */
2173 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2174 AS2 (st,%0,%B1) CR_TAB
2175 AS2 (st,%0,%C1) CR_TAB
2177 fatal_insn ("Unknown move insn:",insn);
2182 output_movsisf(insn, operands, l)
2188 rtx dest = operands[0];
2189 rtx src = operands[1];
2195 if (register_operand (dest, VOIDmode))
2197 if (register_operand (src, VOIDmode)) /* mov r,r */
2199 if (true_regnum (dest) > true_regnum (src))
2204 return (AS2 (movw,%C0,%C1) CR_TAB
2205 AS2 (movw,%A0,%A1));
2208 return (AS2 (mov,%D0,%D1) CR_TAB
2209 AS2 (mov,%C0,%C1) CR_TAB
2210 AS2 (mov,%B0,%B1) CR_TAB
2218 return (AS2 (movw,%A0,%A1) CR_TAB
2219 AS2 (movw,%C0,%C1));
2222 return (AS2 (mov,%A0,%A1) CR_TAB
2223 AS2 (mov,%B0,%B1) CR_TAB
2224 AS2 (mov,%C0,%C1) CR_TAB
2228 else if (CONSTANT_P (src))
2230 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2233 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
2234 AS2 (ldi,%B0,hi8(%1)) CR_TAB
2235 AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2236 AS2 (ldi,%D0,hhi8(%1)));
2239 if (GET_CODE (src) == CONST_INT)
2241 if (src == const0_rtx) /* mov r,L */
2246 return (AS1 (clr,%A0) CR_TAB
2247 AS1 (clr,%B0) CR_TAB
2248 AS2 (movw,%C0,%A0));
2251 return (AS1 (clr,%A0) CR_TAB
2252 AS1 (clr,%B0) CR_TAB
2253 AS1 (clr,%C0) CR_TAB
2256 else if (src == const1_rtx)
2258 if (reg_was_0 (insn, operands[0]))
2261 return AS1 (inc,%A0 ; reg_was_0);
2265 return (AS1 (clr,%D0) CR_TAB
2266 AS1 (clr,%B0) CR_TAB
2267 AS1 (clr,%C0) CR_TAB
2270 else if (src == const2_rtx)
2272 if (reg_was_0 (insn, operands[0]))
2275 return (AS1 (inc,%A0 ; reg_was_0) CR_TAB
2282 return (AS1 (clr,%D0) CR_TAB
2283 AS1 (clr,%C0) CR_TAB
2284 AS2 (movw,%A0,%C0) CR_TAB
2285 AS1 (inc,%A0) CR_TAB
2289 return (AS1 (clr,%D0) CR_TAB
2290 AS1 (clr,%B0) CR_TAB
2291 AS1 (clr,%C0) CR_TAB
2292 AS1 (clr,%A0) CR_TAB
2293 AS1 (inc,%A0) CR_TAB
2296 else if (src == constm1_rtx)
2298 /* Immediate constants -1 to any register */
2299 if (reg_was_0 (insn, operands[0]))
2304 return (AS1 (dec,%A0) CR_TAB
2305 AS1 (dec,%B0) CR_TAB
2306 AS2 (movw,%C0,%A0));
2309 return (AS1 (dec,%D0 ; reg_was_0) CR_TAB
2310 AS1 (dec,%C0) CR_TAB
2311 AS1 (dec,%B0) CR_TAB
2317 return (AS1 (clr,%A0) CR_TAB
2318 AS1 (dec,%A0) CR_TAB
2319 AS2 (mov,%B0,%A0) CR_TAB
2320 AS2 (movw,%C0,%A0));
2323 return (AS1 (clr,%A0) CR_TAB
2324 AS1 (dec,%A0) CR_TAB
2325 AS2 (mov,%B0,%A0) CR_TAB
2326 AS2 (mov,%C0,%A0) CR_TAB
2331 /* Last resort, better than loading from memory. */
2333 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2334 AS2 (ldi,r31,lo8(%1)) CR_TAB
2335 AS2 (mov,%A0,r31) CR_TAB
2336 AS2 (ldi,r31,hi8(%1)) CR_TAB
2337 AS2 (mov,%B0,r31) CR_TAB
2338 AS2 (ldi,r31,hlo8(%1)) CR_TAB
2339 AS2 (mov,%C0,r31) CR_TAB
2340 AS2 (ldi,r31,hhi8(%1)) CR_TAB
2341 AS2 (mov,%D0,r31) CR_TAB
2342 AS2 (mov,r31,__tmp_reg__));
2344 else if (GET_CODE (src) == MEM)
2345 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2347 else if (GET_CODE (dest) == MEM)
2352 if (operands[1] == const0_rtx)
2354 operands[1] = zero_reg_rtx;
2358 template = out_movsi_mr_r (insn, operands, real_l);
2361 output_asm_insn (template, operands);
2364 operands[1] = const0_rtx;
2367 fatal_insn ("Invalid insn:", insn);
2372 out_movqi_mr_r (insn, op, l)
2375 int *l; /* instruction length */
2385 if (CONSTANT_ADDRESS_P (x))
2387 if (io_address_p (x, 1))
2390 return AS2 (out,%0-0x20,%1);
2393 return AS2 (sts,%0,%1);
2395 /* memory access by reg+disp */
2396 else if (GET_CODE (x) == PLUS
2397 && REG_P (XEXP (x,0))
2398 && GET_CODE (XEXP (x,1)) == CONST_INT)
2400 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (op[0]))) >= 63)
2402 int disp = INTVAL (XEXP (x,1));
2403 if (REGNO (XEXP (x,0)) != REG_Y)
2404 fatal_insn ("Incorrect insn:",insn);
2405 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (op[0])))
2408 op[4] = XEXP (x, 1);
2409 return (AS2 (adiw, r28, %4-63) CR_TAB
2410 AS2 (std, Y+63,%1) CR_TAB
2411 AS2 (sbiw, r28, %4-63));
2417 return (AS2 (subi, r28, lo8(-%4)) CR_TAB
2418 AS2 (sbci, r29, hi8(-%4)) CR_TAB
2419 AS2 (st, Y,%1) CR_TAB
2420 AS2 (subi, r28, lo8(%4)) CR_TAB
2421 AS2 (sbci, r29, hi8(%4)));
2424 else if (REGNO (XEXP (x,0)) == REG_X)
2427 if (reg_overlap_mentioned_p (op[1],XEXP (x,0)))
2429 if (reg_unused_after (insn, XEXP (x,0)))
2432 return (AS2 (mov,__tmp_reg__,%1) CR_TAB
2433 AS2 (adiw,r26,%4) CR_TAB
2434 AS2 (st,X,__tmp_reg__));
2437 return (AS2 (mov,__tmp_reg__,%1) CR_TAB
2438 AS2 (adiw,r26,%4) CR_TAB
2439 AS2 (st,X,__tmp_reg__) CR_TAB
2444 if (reg_unused_after (insn, XEXP (x,0)))
2447 return (AS2 (adiw,r26,%4) CR_TAB
2451 return (AS2 (adiw,r26,%4) CR_TAB
2452 AS2 (st,X,%1) CR_TAB
2457 return AS2 (std,%0,%1);
2460 return AS2 (st,%0,%1);
2464 out_movhi_mr_r (insn,op,l)
2469 int reg_base = true_regnum (XEXP (op[0],0));
2470 int reg_dest = true_regnum (op[1]);
2474 if (CONSTANT_ADDRESS_P (XEXP (op[0],0)))
2475 return *l=4,(AS2 (sts,%A0,%A1) CR_TAB
2479 if (reg_base == REG_X)
2481 if (reg_dest == REG_X)
2483 if (reg_unused_after (insn, op[1]))
2484 return *l=3, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2485 AS2 (st ,X+,r26) CR_TAB
2486 AS2 (st ,X,__tmp_reg__));
2488 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2489 AS2 (st ,X+,r26) CR_TAB
2490 AS2 (st ,X,__tmp_reg__) CR_TAB
2495 if (reg_unused_after (insn, XEXP (op[0],0)))
2496 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2499 return *l=3, (AS2 (st ,X+,%A1) CR_TAB
2500 AS2 (st ,X,%B1) CR_TAB
2505 return *l=2, (AS2 (st ,%0,%A1) CR_TAB
2506 AS2 (std,%0+1,%B1));
2508 else if (GET_CODE (XEXP (op[0],0)) == PLUS)
2510 int disp = INTVAL(XEXP (XEXP (op[0],0), 1));
2511 if (disp > MAX_LD_OFFSET (GET_MODE (op[0])))
2513 rtx x = XEXP (op[0],0);
2514 if (REGNO (XEXP (x,0)) != REG_Y)
2515 fatal_insn ("Incorrect insn:",insn);
2516 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (op[0])))
2518 op[4] = GEN_INT (disp - 62);
2519 return *l=4,(AS2 (adiw, r28, %4) CR_TAB
2520 AS2 (std, Y+62,%A1) CR_TAB
2521 AS2 (std, Y+63,%B1) CR_TAB
2522 AS2 (sbiw, r28, %4));
2527 return *l=6,(AS2 (subi, r28, lo8(-%4)) CR_TAB
2528 AS2 (sbci, r29, hi8(-%4)) CR_TAB
2529 AS2 (st, Y,%A1) CR_TAB
2530 AS2 (std, Y+1,%B1) CR_TAB
2531 AS2 (subi, r28, lo8(%4)) CR_TAB
2532 AS2 (sbci, r29, hi8(%4)));
2535 return *l=2, (AS2 (std,%A0,%A1) CR_TAB
2538 else if (GET_CODE (XEXP (op[0],0)) == PRE_DEC) /* (--R) */
2539 return *l=2, (AS2 (st,%0,%B1) CR_TAB
2541 else if (GET_CODE (XEXP (op[0],0)) == POST_INC) /* (R++) */
2542 return *l=2, (AS2 (st,%0,%A1) CR_TAB
2544 fatal_insn ("Unknown move insn:",insn);
2548 /* Return 1 if frame pointer for current function required */
2551 frame_pointer_required_p(void)
2553 return (current_function_calls_alloca
2554 || current_function_args_info.nregs == 0
2555 || current_function_varargs
2556 || get_frame_size () > 0);
2559 /* Return 1 if the next insn is a JUMP_INSN with condition (GT,LE,GTU,LTU) */
2562 compare_diff_p (insn)
2565 rtx next = next_real_insn (insn);
2566 RTX_CODE cond = UNKNOWN;
2567 if (GET_CODE (next) == JUMP_INSN)
2569 rtx pat = PATTERN (next);
2570 rtx src = SET_SRC (pat);
2571 rtx t = XEXP (src,0);
2572 cond = GET_CODE (t);
2574 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2577 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition */
2583 rtx next = next_real_insn (insn);
2584 RTX_CODE cond = UNKNOWN;
2585 if (GET_CODE (next) == JUMP_INSN)
2587 rtx pat = PATTERN (next);
2588 rtx src = SET_SRC (pat);
2589 rtx t = XEXP (src,0);
2590 cond = GET_CODE (t);
2592 return (cond == EQ || cond == NE);
2596 /* Output test instruction for HImode */
2603 if (!compare_eq_p (insn))
2606 return AS1 (tst,%B0);
2608 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2611 return AS2 (sbiw,%0,0);
2613 if (compare_eq_p (insn) && reg_unused_after (insn, SET_SRC (PATTERN (insn))))
2616 return AS2 (or,%A0,%B0);
2619 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2620 AS2 (cpc,%B0,__zero_reg__));
2624 /* Output test instruction for SImode */
2631 if (!compare_eq_p (insn))
2634 return AS1 (tst,%D0);
2636 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2639 return (AS2 (sbiw,%A0,0) CR_TAB
2640 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2641 AS2 (cpc,%D0,__zero_reg__));
2644 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2645 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2646 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2647 AS2 (cpc,%D0,__zero_reg__));
2651 /* Generate asm equivalent for various shift's.
2652 Shift count are CONST_INT or REG. */
2655 out_shift_with_cnt (template,insn,operands,len)
2663 int second_label = 1;
2665 op[0] = operands[0];
2666 op[1] = operands[1];
2667 op[2] = operands[2];
2668 op[3] = operands[3];
2671 if (CONSTANT_P (operands[2]))
2676 strcat (str, "ldi %3,lo8((%2)-1)");
2679 else if (GET_CODE (operands[2]) == MEM)
2684 op[3] = op_mov[0] = tmp_reg_rtx;
2689 output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2690 strcat (str, AS1 (rjmp,2f));
2694 out_movqi_r_mr (insn, op_mov, &mov_len);
2698 else if (register_operand (operands[2], QImode))
2700 if (reg_unused_after (insn, operands[2]))
2704 op[3] = tmp_reg_rtx;
2708 strcat (str, "mov %3,%2" CR_TAB);
2714 strcat (str, AS1 (rjmp,2f));
2719 strcat (str,"\n1:\t");
2720 strcat (str, template);
2721 strcat (str, second_label ? "\n2:\t" : "\n\t");
2725 output_asm_insn (str, op);
2730 /* 8bit shift left ((char)x << i) */
2733 ashlqi3_out (insn,operands,len)
2736 int *len; /* insn length (may be NULL) */
2738 if (GET_CODE (operands[2]) == CONST_INT)
2745 switch (INTVAL (operands[2]))
2749 return AS1 (clr,%0);
2753 return AS1 (lsl,%0);
2757 return (AS1 (lsl,%0) CR_TAB
2762 return (AS1 (lsl,%0) CR_TAB
2767 if (test_hard_reg_class (LD_REGS, operands[0]))
2770 return (AS1 (swap,%0) CR_TAB
2771 AS2 (andi,%0,0xf0));
2774 return (AS1 (lsl,%0) CR_TAB
2780 if (test_hard_reg_class (LD_REGS, operands[0]))
2783 return (AS1 (swap,%0) CR_TAB
2785 AS2 (andi,%0,0xe0));
2788 return (AS1 (lsl,%0) CR_TAB
2795 if (test_hard_reg_class (LD_REGS, operands[0]))
2798 return (AS1 (swap,%0) CR_TAB
2801 AS2 (andi,%0,0xc0));
2804 return (AS1 (lsl,%0) CR_TAB
2813 return (AS1 (ror,%0) CR_TAB
2818 else if (CONSTANT_P (operands[2]))
2819 fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
2823 out_shift_with_cnt (AS1 (lsl,%0),
2824 insn, operands, len);
2829 /* 16bit shift left ((short)x << i) */
2832 ashlhi3_out (insn,operands,len)
2837 if (GET_CODE (operands[2]) == CONST_INT)
2845 switch (INTVAL (operands[2]))
2847 default: len = t; break;
2851 return (AS1 (lsl,%A0) CR_TAB
2856 return (AS1 (lsl,%A0) CR_TAB
2857 AS1 (rol,%B0) CR_TAB
2862 if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
2863 return *len = 1, AS1 (clr,%A0);
2865 return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
2871 out_shift_with_cnt (AS1 (lsl,%0) CR_TAB
2873 insn, operands, len);
2878 /* 32bit shift left ((long)x << i) */
2881 ashlsi3_out (insn,operands,len)
2886 if (GET_CODE (operands[2]) == CONST_INT)
2894 switch (INTVAL (operands[2]))
2896 default: len = t; break;
2900 return (AS1 (lsl,%A0) CR_TAB
2901 AS1 (rol,%B0) CR_TAB
2902 AS1 (rol,%C0) CR_TAB
2907 int reg0 = true_regnum (operands[0]);
2908 int reg1 = true_regnum (operands[1]);
2911 return (AS2 (mov,%D0,%C1) CR_TAB
2912 AS2 (mov,%C0,%B1) CR_TAB
2913 AS2 (mov,%B0,%A1) CR_TAB
2915 else if (reg0 + 1 == reg1)
2918 return AS1 (clr,%A0);
2921 return (AS1 (clr,%A0) CR_TAB
2922 AS2 (mov,%B0,%A1) CR_TAB
2923 AS2 (mov,%C0,%B1) CR_TAB
2929 int reg0 = true_regnum (operands[0]);
2930 int reg1 = true_regnum (operands[1]);
2932 if (AVR_ENHANCED && (reg0 + 2 != reg1))
2935 return (AS2 (movw,%C0,%A1) CR_TAB
2936 AS1 (clr,%B0) CR_TAB
2939 if (reg0 + 1 >= reg1)
2940 return (AS2 (mov,%D0,%B1) CR_TAB
2941 AS2 (mov,%C0,%A1) CR_TAB
2942 AS1 (clr,%B0) CR_TAB
2944 if (reg0 + 2 == reg1)
2947 return (AS1 (clr,%B0) CR_TAB
2951 return (AS2 (mov,%C0,%A1) CR_TAB
2952 AS2 (mov,%D0,%B1) CR_TAB
2953 AS1 (clr,%B0) CR_TAB
2959 if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
2960 return (AS2 (mov,%D0,%A1) CR_TAB
2961 AS1 (clr,%C0) CR_TAB
2962 AS1 (clr,%B0) CR_TAB
2967 return (AS1 (clr,%C0) CR_TAB
2968 AS1 (clr,%B0) CR_TAB
2975 out_shift_with_cnt (AS1 (lsl,%0) CR_TAB
2976 AS1 (rol,%B0) CR_TAB
2977 AS1 (rol,%C0) CR_TAB
2979 insn, operands, len);
2983 /* 8bit arithmetic shift right ((signed char)x >> i) */
2986 ashrqi3_out (insn,operands,len)
2989 int *len; /* insn length */
2991 if (GET_CODE (operands[2]) == CONST_INT)
2998 switch (INTVAL (operands[2]))
3002 return AS1 (asr,%0);
3006 return (AS1 (asr,%0) CR_TAB
3011 return (AS1 (asr,%0) CR_TAB
3017 return (AS1 (asr,%0) CR_TAB
3024 return (AS1 (asr,%0) CR_TAB
3032 return (AS2 (bst,%0,6) CR_TAB
3034 AS2 (sbc,%0,%0) CR_TAB
3040 return (AS1 (lsl,%0) CR_TAB
3044 else if (CONSTANT_P (operands[2]))
3045 fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
3049 out_shift_with_cnt (AS1 (asr,%0),
3050 insn, operands, len);
3055 /* 16bit arithmetic shift right ((signed short)x >> i) */
3058 ashrhi3_out (insn,operands,len)
3063 if (GET_CODE (operands[2]) == CONST_INT)
3071 switch (INTVAL (operands[2]))
3073 default: len = t; break;
3077 return (AS1 (asr,%B0) CR_TAB
3082 return (AS1 (asr,%B0) CR_TAB
3083 AS1 (ror,%A0) CR_TAB
3084 AS1 (asr,%B0) CR_TAB
3088 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
3089 return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3090 AS1 (clr,%B0) CR_TAB
3091 AS2 (sbrc,%A0,7) CR_TAB
3094 return *len = 3, (AS1 (clr,%B0) CR_TAB
3095 AS2 (sbrc,%A0,7) CR_TAB
3099 return *len = 3, (AS1 (lsl,%B0) CR_TAB
3100 AS2 (sbc,%A0,%A0) CR_TAB
3106 out_shift_with_cnt (AS1 (asr,%B0) CR_TAB
3108 insn, operands, len);
3113 /* 32bit arithmetic shift right ((signed long)x >> i) */
3116 ashrsi3_out (insn,operands,len)
3121 if (GET_CODE (operands[2]) == CONST_INT)
3129 switch (INTVAL (operands[2]))
3131 default: len = t; break;
3135 return (AS1 (asr,%D0) CR_TAB
3136 AS1 (ror,%C0) CR_TAB
3137 AS1 (ror,%B0) CR_TAB
3142 int reg0 = true_regnum (operands[0]);
3143 int reg1 = true_regnum (operands[1]);
3146 return (AS2 (mov,%A0,%B1) CR_TAB
3147 AS2 (mov,%B0,%C1) CR_TAB
3148 AS2 (mov,%C0,%D1) CR_TAB
3149 AS1 (clr,%D0) CR_TAB
3150 AS2 (sbrc,%C0,7) CR_TAB
3152 else if (reg0 == reg1 + 1)
3155 return (AS1 (clr,%D0) CR_TAB
3156 AS2 (sbrc,%C0,7) CR_TAB
3160 return (AS1 (clr,%D0) CR_TAB
3161 AS2 (sbrc,%D1,7) CR_TAB
3162 AS1 (dec,%D0) CR_TAB
3163 AS2 (mov,%C0,%D1) CR_TAB
3164 AS2 (mov,%B0,%C1) CR_TAB
3170 int reg0 = true_regnum (operands[0]);
3171 int reg1 = true_regnum (operands[1]);
3173 if (AVR_ENHANCED && (reg0 != reg1 + 2))
3176 return (AS2 (movw,%A0,%C1) CR_TAB
3177 AS1 (clr,%D0) CR_TAB
3178 AS2 (sbrc,%B0,7) CR_TAB
3179 AS1 (com,%D0) CR_TAB
3182 if (reg0 <= reg1 + 1)
3183 return (AS2 (mov,%A0,%C1) CR_TAB
3184 AS2 (mov,%B0,%D1) CR_TAB
3185 AS1 (clr,%D0) CR_TAB
3186 AS2 (sbrc,%B0,7) CR_TAB
3187 AS1 (com,%D0) CR_TAB
3189 else if (reg0 == reg1 + 2)
3190 return *len = 4, (AS1 (clr,%D0) CR_TAB
3191 AS2 (sbrc,%B0,7) CR_TAB
3192 AS1 (com,%D0) CR_TAB
3195 return (AS2 (mov,%B0,%D1) CR_TAB
3196 AS2 (mov,%A0,%C1) CR_TAB
3197 AS1 (clr,%D0) CR_TAB
3198 AS2 (sbrc,%B0,7) CR_TAB
3199 AS1 (com,%D0) CR_TAB
3204 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3205 return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3206 AS1 (clr,%D0) CR_TAB
3207 AS2 (sbrc,%A0,7) CR_TAB
3208 AS1 (com,%D0) CR_TAB
3209 AS2 (mov,%B0,%D0) CR_TAB
3212 return *len = 5, (AS1 (clr,%D0) CR_TAB
3213 AS2 (sbrc,%A0,7) CR_TAB
3214 AS1 (com,%D0) CR_TAB
3215 AS2 (mov,%B0,%D0) CR_TAB
3221 out_shift_with_cnt (AS1 (asr,%D0) CR_TAB
3222 AS1 (ror,%C0) CR_TAB
3223 AS1 (ror,%B0) CR_TAB
3225 insn, operands, len);
3229 /* 8bit logic shift right ((unsigned char)x >> i) */
3232 lshrqi3_out (insn,operands,len)
3237 if (GET_CODE (operands[2]) == CONST_INT)
3244 switch (INTVAL (operands[2]))
3248 return AS1 (clr,%0);
3252 return AS1 (lsr,%0);
3256 return (AS1 (lsr,%0) CR_TAB
3260 return (AS1 (lsr,%0) CR_TAB
3265 if (test_hard_reg_class (LD_REGS, operands[0]))
3268 return (AS1 (swap,%0) CR_TAB
3269 AS2 (andi,%0,0x0f));
3272 return (AS1 (lsr,%0) CR_TAB
3278 if (test_hard_reg_class (LD_REGS, operands[0]))
3281 return (AS1 (swap,%0) CR_TAB
3286 return (AS1 (lsr,%0) CR_TAB
3293 if (test_hard_reg_class (LD_REGS, operands[0]))
3296 return (AS1 (swap,%0) CR_TAB
3302 return (AS1 (lsr,%0) CR_TAB
3311 return (AS1 (rol,%0) CR_TAB
3316 else if (CONSTANT_P (operands[2]))
3317 fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
3321 out_shift_with_cnt (AS1 (lsr,%0),
3322 insn, operands, len);
3326 /* 16bit logic shift right ((unsigned short)x >> i) */
3329 lshrhi3_out (insn,operands,len)
3334 if (GET_CODE (operands[2]) == CONST_INT)
3342 switch (INTVAL (operands[2]))
3344 default: len = t; break;
3348 return (AS1 (lsr,%B0) CR_TAB
3353 return (AS1 (lsr,%B0) CR_TAB
3354 AS1 (ror,%A0) CR_TAB
3355 AS1 (lsr,%B0) CR_TAB
3359 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
3360 return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
3363 return *len = 1, AS1 (clr,%B0);
3367 return (AS1 (lsl,%B0) CR_TAB
3368 AS2 (sbc,%A0,%A0) CR_TAB
3369 AS1 (neg,%A0) CR_TAB
3375 out_shift_with_cnt (AS1 (lsr,%B0) CR_TAB
3377 insn, operands, len);
3381 /* 32bit logic shift right ((unsigned int)x >> i) */
3384 lshrsi3_out (insn,operands,len)
3389 if (GET_CODE (operands[2]) == CONST_INT)
3397 switch (INTVAL (operands[2]))
3399 default: len = t; break;
3403 return (AS1 (lsr,%D0) CR_TAB
3404 AS1 (ror,%C0) CR_TAB
3405 AS1 (ror,%B0) CR_TAB
3410 int reg0 = true_regnum (operands[0]);
3411 int reg1 = true_regnum (operands[1]);
3414 return (AS2 (mov,%A0,%B1) CR_TAB
3415 AS2 (mov,%B0,%C1) CR_TAB
3416 AS2 (mov,%C0,%D1) CR_TAB
3418 else if (reg0 == reg1 + 1)
3419 return *len = 1, AS1 (clr,%D0);
3421 return (AS1 (clr,%D0) CR_TAB
3422 AS2 (mov,%C0,%D1) CR_TAB
3423 AS2 (mov,%B0,%C1) CR_TAB
3429 int reg0 = true_regnum (operands[0]);
3430 int reg1 = true_regnum (operands[1]);
3432 if (AVR_ENHANCED && (reg0 != reg1 + 2))
3435 return (AS2 (movw,%A0,%C1) CR_TAB
3436 AS1 (clr,%C0) CR_TAB
3439 if (reg0 <= reg1 + 1)
3440 return (AS2 (mov,%A0,%C1) CR_TAB
3441 AS2 (mov,%B0,%D1) CR_TAB
3442 AS1 (clr,%C0) CR_TAB
3444 else if (reg0 == reg1 + 2)
3445 return *len = 2, (AS1 (clr,%C0) CR_TAB
3448 return (AS2 (mov,%B0,%D1) CR_TAB
3449 AS2 (mov,%A0,%C1) CR_TAB
3450 AS1 (clr,%C0) CR_TAB
3455 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3456 return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
3457 AS1 (clr,%B0) CR_TAB
3458 AS1 (clr,%C0) CR_TAB
3461 return *len = 3, (AS1 (clr,%B0) CR_TAB
3462 AS1 (clr,%C0) CR_TAB
3468 out_shift_with_cnt (AS1 (lsr,%D0) CR_TAB
3469 AS1 (ror,%C0) CR_TAB
3470 AS1 (ror,%B0) CR_TAB
3472 insn, operands, len);
3476 /* Modifies the length assigned to instruction INSN
3477 LEN is the initially computed length of the insn. */
3480 adjust_insn_length (insn,len)
3484 rtx patt = PATTERN (insn);
3486 if (GET_CODE (patt) == SET)
3489 op[1] = SET_SRC (patt);
3490 op[0] = SET_DEST (patt);
3491 if (general_operand (op[1], VOIDmode)
3492 && general_operand (op[0], VOIDmode))
3494 switch (GET_MODE (op[0]))
3497 output_movqi (insn, op, &len);
3500 output_movhi (insn, op, &len);
3504 output_movsisf (insn, op, &len);
3510 else if (op[0] == cc0_rtx && REG_P (op[1]))
3512 switch (GET_MODE (op[1]))
3514 case HImode: out_tsthi (insn,&len); break;
3515 case SImode: out_tstsi (insn,&len); break;
3519 else if (GET_CODE (op[1]) == AND)
3521 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
3523 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
3524 if (GET_MODE (op[1]) == SImode)
3525 len = (((mask & 0xff) != 0xff)
3526 + ((mask & 0xff00) != 0xff00)
3527 + ((mask & 0xff0000UL) != 0xff0000UL)
3528 + ((mask & 0xff000000UL) != 0xff000000UL));
3529 else if (GET_MODE (op[1]) == HImode)
3530 len = (((mask & 0xff) != 0xff)
3531 + ((mask & 0xff00) != 0xff00));
3534 else if (GET_CODE (op[1]) == IOR)
3536 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
3538 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
3539 if (GET_MODE (op[1]) == SImode)
3540 len = (((mask & 0xff) == 0)
3541 + ((mask & 0xff00) == 0)
3542 + ((mask & 0xff0000UL) == 0)
3543 + ((mask & 0xff000000UL) ==0));
3544 else if (GET_MODE (op[1]) == HImode)
3545 len = (((mask & 0xff) == 0)
3546 + ((mask & 0xff00) == 0));
3550 set = single_set (insn);
3554 op[1] = SET_SRC (set);
3555 op[0] = SET_DEST (set);
3556 if (GET_CODE (op[1]) == ASHIFT
3557 || GET_CODE (op[1]) == ASHIFTRT
3558 || GET_CODE (op[1]) == LSHIFTRT)
3562 ops[1] = XEXP (op[1],0);
3563 ops[2] = XEXP (op[1],1);
3564 switch (GET_CODE (op[1]))
3567 switch (GET_MODE (op[0]))
3569 case QImode: ashlqi3_out (insn,ops,&len); break;
3570 case HImode: ashlhi3_out (insn,ops,&len); break;
3571 case SImode: ashlsi3_out (insn,ops,&len); break;
3576 switch (GET_MODE (op[0]))
3578 case QImode: ashrqi3_out (insn,ops,&len); break;
3579 case HImode: ashrhi3_out (insn,ops,&len); break;
3580 case SImode: ashrsi3_out (insn,ops,&len); break;
3585 switch (GET_MODE (op[0]))
3587 case QImode: lshrqi3_out (insn,ops,&len); break;
3588 case HImode: lshrhi3_out (insn,ops,&len); break;
3589 case SImode: lshrsi3_out (insn,ops,&len); break;
3601 /* Return non-zero if register REG dead after INSN */
3604 reg_unused_after (insn, reg)
3608 return (dead_or_set_p (insn, reg)
3609 || (REG_P(reg) && _reg_unused_after (insn, reg)));
3612 /* Return non-zero if REG is not used after INSN.
3613 We assume REG is a reload reg, and therefore does
3614 not live past labels. It may live past calls or jumps though. */
3617 _reg_unused_after (insn, reg)
3624 /* If the reg is set by this instruction, then it is safe for our
3625 case. Disregard the case where this is a store to memory, since
3626 we are checking a register used in the store address. */
3627 set = single_set (insn);
3628 if (set && GET_CODE (SET_DEST (set)) != MEM
3629 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
3632 while ((insn = NEXT_INSN (insn)))
3634 code = GET_CODE (insn);
3637 /* If this is a label that existed before reload, then the register
3638 if dead here. However, if this is a label added by reorg, then
3639 the register may still be live here. We can't tell the difference,
3640 so we just ignore labels completely. */
3641 if (code == CODE_LABEL)
3646 if (code == JUMP_INSN)
3649 /* If this is a sequence, we must handle them all at once.
3650 We could have for instance a call that sets the target register,
3651 and a insn in a delay slot that uses the register. In this case,
3652 we must return 0. */
3653 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
3658 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
3660 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
3661 rtx set = single_set (this_insn);
3663 if (GET_CODE (this_insn) == CALL_INSN)
3665 else if (GET_CODE (this_insn) == JUMP_INSN)
3667 if (INSN_ANNULLED_BRANCH_P (this_insn))
3672 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
3674 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
3676 if (GET_CODE (SET_DEST (set)) != MEM)
3682 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
3687 else if (code == JUMP_INSN)
3691 if (code == CALL_INSN)
3694 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
3695 if (GET_CODE (XEXP (tem, 0)) == USE
3696 && REG_P (XEXP (XEXP (tem, 0), 0))
3697 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
3699 if (call_used_regs[REGNO (reg)])
3703 if (GET_RTX_CLASS (code) == 'i')
3705 rtx set = single_set (insn);
3707 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
3709 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
3710 return GET_CODE (SET_DEST (set)) != MEM;
3711 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
3718 /* Output rtx VALUE as .byte to file FILE */
3721 asm_output_char(file,value)
3725 fprintf (file, "\t.byte ");
3726 output_addr_const (file, value);
3727 fprintf (file, "\n");
3731 /* Output VALUE as .byte to file FILE */
3734 asm_output_byte (file,value)
3738 fprintf (file, "\t.byte 0x%x\n",value & 0xff);
3742 /* Output rtx VALUE as .word to file FILE */
3745 asm_output_short (file, value)
3749 if (SYMBOL_REF_FLAG (value) || GET_CODE (value) == LABEL_REF)
3751 fprintf (file, "\t.word pm(");
3752 output_addr_const (file, (value));
3753 fprintf (file, ")\n");
3757 fprintf (file, "\t.word ");
3758 output_addr_const (file, (value));
3759 fprintf (file, "\n");
3764 /* Output real N to file FILE */
3767 asm_output_float (file, n)
3774 REAL_VALUE_TO_TARGET_SINGLE (n, val);
3775 REAL_VALUE_TO_DECIMAL (n, "%g", dstr);
3776 fprintf (file, "\t.long 0x%08lx\t/* %s */\n",val, dstr);
3779 /* Sets section name for declaration DECL */
3782 unique_section (decl, reloc)
3784 int reloc ATTRIBUTE_UNUSED;
3789 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
3790 /* Strip off any encoding in name. */
3791 STRIP_NAME_ENCODING (name, name);
3793 if (TREE_CODE (decl) == FUNCTION_DECL)
3795 if (flag_function_sections)
3801 fatal ("Strange situation: unique section is not a FUNCTION_DECL");
3803 if (flag_function_sections)
3805 len = strlen (name) + strlen (prefix);
3806 string = alloca (len + 1);
3807 sprintf (string, "%s%s", prefix, name);
3808 DECL_SECTION_NAME (decl) = build_string (len, string);
3813 /* Output section name to file FILE
3814 We make the section read-only and executable for a function decl,
3815 read-only for a const data decl, and writable for a non-const data decl. */
3818 asm_output_section_name(file, decl, name, reloc)
3822 int reloc ATTRIBUTE_UNUSED;
3824 fprintf (file, ".section %s, \"%s\", @progbits\n", name,
3825 decl && TREE_CODE (decl) == FUNCTION_DECL ? "ax" :
3826 decl && TREE_READONLY (decl) ? "a" : "aw");
3830 /* The routine used to output NUL terminated strings. We use a special
3831 version of this for most svr4 targets because doing so makes the
3832 generated assembly code more compact (and thus faster to assemble)
3833 as well as more readable, especially for targets like the i386
3834 (where the only alternative is to output character sequences as
3835 comma separated lists of numbers). */
3838 gas_output_limited_string(file, str)
3839 FILE * file ATTRIBUTE_UNUSED;
3842 unsigned char *_limited_str = (unsigned char *) str;
3844 fprintf (file, "\t%s\t\"", STRING_ASM_OP);
3845 for (; (ch = *_limited_str); _limited_str++)
3848 switch (escape = ESCAPES[ch])
3854 fprintf (file, "\\%03o", ch);
3858 putc (escape, file);
3862 fprintf (file, "\"\n");
3865 /* The routine used to output sequences of byte values. We use a special
3866 version of this for most svr4 targets because doing so makes the
3867 generated assembly code more compact (and thus faster to assemble)
3868 as well as more readable. Note that if we find subparts of the
3869 character sequence which end with NUL (and which are shorter than
3870 STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
3873 gas_output_ascii(file, str, length)
3878 unsigned char *_ascii_bytes = (unsigned char *) str;
3879 unsigned char *limit = _ascii_bytes + length;
3880 unsigned bytes_in_chunk = 0;
3881 for (; _ascii_bytes < limit; _ascii_bytes++)
3883 register unsigned char *p;
3884 if (bytes_in_chunk >= 60)
3886 fprintf (file, "\"\n");
3889 for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
3891 if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
3893 if (bytes_in_chunk > 0)
3895 fprintf (file, "\"\n");
3898 gas_output_limited_string (file, (char*)_ascii_bytes);
3905 if (bytes_in_chunk == 0)
3906 fprintf (file, "\t.ascii\t\"");
3907 switch (escape = ESCAPES[ch = *_ascii_bytes])
3914 fprintf (file, "\\%03o", ch);
3915 bytes_in_chunk += 4;
3919 putc (escape, file);
3920 bytes_in_chunk += 2;
3925 if (bytes_in_chunk > 0)
3926 fprintf (file, "\"\n");
3929 /* Return value is nonzero if pseudos that have been
3930 assigned to registers of class CLASS would likely be spilled
3931 because registers of CLASS are needed for spill registers. */
3934 class_likely_spilled_p(int c)
3936 return (c != ALL_REGS && c != ADDW_REGS);
3939 /* Only `progmem' attribute valid for type. */
3942 valid_machine_type_attribute(type, attributes, identifier, args)
3943 tree type ATTRIBUTE_UNUSED;
3944 tree attributes ATTRIBUTE_UNUSED;
3946 tree args ATTRIBUTE_UNUSED;
3948 return is_attribute_p ("progmem", identifier);
3951 /* If IDENTIFIER with arguments ARGS is a valid machine specific
3952 attribute for DECL return 1.
3954 progmem - put data to program memory;
3955 signal - make a function to be hardware interrupt. After function
3956 prologue interrupts are disabled;
3957 interrupt - make a function to be hardware interrupt. After function
3958 prologue interrupts are enabled;
3959 naked - don't generate function prologue/epilogue and `ret' command. */
3962 valid_machine_decl_attribute (decl, attributes, attr, args)
3964 tree attributes ATTRIBUTE_UNUSED;
3966 tree args ATTRIBUTE_UNUSED;
3968 if (is_attribute_p ("interrupt", attr)
3969 || is_attribute_p ("signal", attr)
3970 || is_attribute_p ("naked", attr))
3971 return TREE_CODE (decl) == FUNCTION_DECL;
3973 if (is_attribute_p ("progmem", attr)
3974 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
3976 if (DECL_INITIAL (decl) == NULL_TREE)
3978 warning ("Only initialized variables can be placed into "
3979 "program memory area.");
3988 /* Look for attribute `progmem' in DECL
3989 if found return 1, otherwise 0. */
3992 avr_progmem_p (decl)
3997 if (TREE_CODE (decl) != VAR_DECL)
4001 != lookup_attribute ("progmem", DECL_MACHINE_ATTRIBUTES (decl)))
4007 while (TREE_CODE (a) == ARRAY_TYPE);
4009 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
4015 /* Encode section information about tree DECL */
4018 encode_section_info (decl)
4021 if (TREE_CODE (decl) == FUNCTION_DECL)
4022 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
4024 if ((TREE_STATIC (decl) || DECL_EXTERNAL (decl))
4025 && TREE_CODE (decl) == VAR_DECL
4026 && avr_progmem_p (decl))
4028 char * dsec = ".progmem.data";
4029 DECL_SECTION_NAME (decl) = build_string (strlen (dsec), dsec);
4030 TREE_READONLY (decl) = 1;
4034 /* Outputs to the stdio stream FILE some
4035 appropriate text to go at the start of an assembler file. */
4038 asm_file_start (file)
4041 output_file_directive (file, main_input_filename);
4042 fprintf (file, "\t.arch %s\n", avr_mcu_name);
4043 fputs ("__SREG__ = 0x3f\n"
4045 "__SP_L__ = 0x3d\n", file);
4047 fputs ("__tmp_reg__ = 0\n"
4048 "__zero_reg__ = 1\n"
4049 "_PC_ = 2\n", file);
4051 commands_in_file = 0;
4052 commands_in_prologues = 0;
4053 commands_in_epilogues = 0;
4056 /* Outputs to the stdio stream FILE some
4057 appropriate text to go at the end of an assembler file. */
4064 "/* File %s: code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
4065 main_input_filename,
4068 commands_in_file - commands_in_prologues - commands_in_epilogues,
4069 commands_in_prologues, commands_in_epilogues);
4072 /* Choose the order in which to allocate hard registers for
4073 pseudo-registers local to a basic block.
4075 Store the desired register order in the array `reg_alloc_order'.
4076 Element 0 should be the register to allocate first; element 1, the
4077 next register; and so on. */
4080 order_regs_for_local_alloc (void)
4091 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4103 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4116 15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4121 int *order = (TARGET_ORDER_1 ? order_1 :
4122 TARGET_ORDER_2 ? order_2 :
4124 for (i=0; i < ARRAY_SIZE (order_0); ++i)
4125 reg_alloc_order[i] = order[i];
4128 /* Calculate the cost of X code of the expression in which it is contained,
4129 found in OUTER_CODE */
4132 default_rtx_costs (X, code, outer_code)
4135 enum rtx_code outer_code;
4142 cost = 2 * GET_MODE_SIZE (GET_MODE (X));
4145 if (outer_code != SET)
4147 if (GET_CODE (XEXP (X,0)) == SYMBOL_REF)
4148 cost += 2 * GET_MODE_SIZE (GET_MODE (X));
4150 cost += GET_MODE_SIZE (GET_MODE (X));
4156 if (outer_code == SET)
4157 cost = GET_MODE_SIZE (GET_MODE (X));
4159 cost = -GET_MODE_SIZE (GET_MODE (X));
4162 if (outer_code == SET)
4163 cost = GET_MODE_SIZE (GET_MODE (X));
4169 if (outer_code == SET)
4171 if (X == stack_pointer_rtx)
4173 else if (GET_CODE (XEXP (X,1)) == CONST_INT)
4174 cost = (INTVAL (XEXP (X,1)) <= 63 ? 1 :
4175 GET_MODE_SIZE (GET_MODE (X)));
4177 cost = GET_MODE_SIZE (GET_MODE (X));
4181 if (GET_CODE (XEXP (X,1)) == CONST_INT)
4182 cost = GET_MODE_SIZE (GET_MODE (XEXP (X,0)));
4190 /* Calculate the cost of a memory address */
4193 avr_address_cost (rtx x)
4195 if (GET_CODE (x) == PLUS
4196 && GET_CODE (XEXP (x,1)) == CONST_INT
4197 && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
4198 && INTVAL (XEXP (x,1)) >= 61)
4200 if (CONSTANT_ADDRESS_P (x))
4205 /* EXTRA_CONSTRAINT helper */
4208 extra_constraint (x,c)
4213 && GET_CODE (x) == MEM
4214 && GET_CODE (XEXP (x,0)) == PLUS)
4216 if (TARGET_ALL_DEBUG)
4218 fprintf (stderr, ("extra_constraint:\n"
4219 "reload_completed: %d\n"
4220 "reload_in_progress: %d\n"),
4221 reload_completed, reload_in_progress);
4224 if (GET_CODE (x) == MEM
4225 && GET_CODE (XEXP (x,0)) == PLUS
4226 && REG_P (XEXP (XEXP (x,0), 0))
4227 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
4228 && (INTVAL (XEXP (XEXP (x,0), 1))
4229 <= MAX_LD_OFFSET (GET_MODE (x))))
4231 rtx xx = XEXP (XEXP (x,0), 0);
4232 int regno = REGNO (xx);
4233 if (TARGET_ALL_DEBUG)
4235 fprintf (stderr, ("extra_constraint:\n"
4236 "reload_completed: %d\n"
4237 "reload_in_progress: %d\n"),
4238 reload_completed, reload_in_progress);
4241 if (regno >= FIRST_PSEUDO_REGISTER)
4242 return 1; /* allocate pseudos */
4243 else if (regno == REG_Z || regno == REG_Y)
4244 return 1; /* strictly check */
4245 else if (xx == frame_pointer_rtx
4246 || xx == arg_pointer_rtx)
4247 return 1; /* XXX frame & arg pointer checks */
4253 /* Convert condition code CONDITION to the valid AVR condition code */
4256 avr_normalize_condition (condition)
4270 fatal ("Wrong condition: %s", GET_RTX_NAME (condition));
4274 /* This fnction optimizes conditional jumps */
4277 machine_dependent_reorg (first_insn)
4283 for (insn = first_insn; insn; insn = NEXT_INSN (insn))
4285 if (! (insn == 0 || GET_CODE (insn) == INSN
4286 || GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN)
4287 || !single_set (insn))
4290 pattern = PATTERN (insn);
4292 cc_prev_status = cc_status;
4293 NOTICE_UPDATE_CC (pattern, insn);
4295 if (GET_CODE (pattern) == PARALLEL)
4296 pattern = XVECEXP (pattern, 0, 0);
4297 if (GET_CODE (pattern) == SET
4298 && SET_DEST (pattern) == cc0_rtx
4299 && compare_diff_p (insn))
4301 if (GET_CODE (SET_SRC (pattern)) == COMPARE)
4303 /* Now we work under compare insn */
4305 pattern = SET_SRC (pattern);
4306 if (true_regnum (XEXP (pattern,0)) >= 0
4307 && true_regnum (XEXP (pattern,1)) >= 0 )
4309 rtx x = XEXP (pattern,0);
4310 rtx next = next_real_insn (insn);
4311 rtx pat = PATTERN (next);
4312 rtx src = SET_SRC (pat);
4313 rtx t = XEXP (src,0);
4314 PUT_CODE (t, swap_condition (GET_CODE (t)));
4315 XEXP (pattern,0) = XEXP (pattern,1);
4316 XEXP (pattern,1) = x;
4317 INSN_CODE (next) = -1;
4319 else if (true_regnum (XEXP (pattern,0)) >= 0
4320 && GET_CODE (XEXP (pattern,1)) == CONST_INT)
4322 rtx x = XEXP (pattern,1);
4323 rtx next = next_real_insn (insn);
4324 rtx pat = PATTERN (next);
4325 rtx src = SET_SRC (pat);
4326 rtx t = XEXP (src,0);
4328 if (avr_simplify_comparision_p (GET_MODE (XEXP (pattern,0)),
4331 XEXP (pattern,1) = GEN_INT (INTVAL (x)+1);
4332 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
4333 INSN_CODE (next) = -1;
4334 INSN_CODE (insn) = -1;
4338 else if (true_regnum (SET_SRC (pattern)) >= 0)
4340 /* This is a tst insn */
4341 rtx next = next_real_insn (insn);
4342 rtx pat = PATTERN (next);
4343 rtx src = SET_SRC (pat);
4344 rtx t = XEXP (src,0);
4346 if (!(cc_prev_status.value1 != 0 && cc_status.value1 != 0
4347 && rtx_equal_p (cc_status.value1, cc_prev_status.value1)))
4349 PUT_CODE (t, swap_condition (GET_CODE (t)));
4350 SET_SRC (pattern) = gen_rtx (NEG,
4351 GET_MODE (SET_SRC (pattern)),
4353 INSN_CODE (next) = -1;
4354 INSN_CODE (insn) = -1;
4361 /* Returns register number for function return value.*/
4364 avr_ret_register (void)
4369 /* Ceate an RTX representing the place where a
4370 library function returns a value of mode MODE. */
4373 avr_libcall_value (mode)
4374 enum machine_mode mode;
4376 int offs = GET_MODE_SIZE (mode);
4379 return gen_rtx (REG, mode, RET_REGISTER + 2 - offs);
4382 /* Create an RTX representing the place where a
4383 function returns a value of data type VALTYPE. */
4386 avr_function_value (type,func)
4388 tree func ATTRIBUTE_UNUSED;
4391 if (TYPE_MODE (type) != BLKmode)
4392 return avr_libcall_value (TYPE_MODE (type));
4394 offs = int_size_in_bytes (type);
4397 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
4398 offs = GET_MODE_SIZE (SImode);
4399 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
4400 offs = GET_MODE_SIZE (DImode);
4402 return gen_rtx (REG, BLKmode, RET_REGISTER + 2 - offs);
4405 /* Returns non-zero if the number MASK has only one bit set. */
4408 mask_one_bit_p (mask)
4412 unsigned HOST_WIDE_INT n=mask;
4413 for (i = 0; i < 32; ++i)
4415 if (n & 0x80000000UL)
4417 if (n & 0x7fffffffUL)
4428 /* Places additional restrictions on the register class to
4429 use when it is necessary to copy value X into a register
4433 preferred_reload_class (x, class)
4434 rtx x ATTRIBUTE_UNUSED;
4435 enum reg_class class;
4441 test_hard_reg_class (class, x)
4442 enum reg_class class;
4445 int regno = true_regnum (x);
4448 return TEST_HARD_REG_CLASS (class, regno);
4452 debug_hard_reg_set (set)
4456 for (i=0; i < FIRST_PSEUDO_REGISTER; ++i)
4458 if (TEST_HARD_REG_BIT (set, i))
4460 fprintf (stderr, "r%-2d ", i);
4463 fprintf (stderr, "\n");
4467 jump_over_one_insn_p (insn, dest)
4471 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
4474 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
4475 int dest_addr = INSN_ADDRESSES (uid);
4476 return dest_addr - jump_addr == 2;
4479 /* Returns 1 if a value of mode MODE can be stored starting with hard
4480 register number REGNO. On the enhanced core, anything larger than
4481 1 byte must start in even numbered register for "movw" to work
4482 (this way we don't have to check for odd registers everywhere). */
4485 avr_hard_regno_mode_ok (regno, mode)
4487 enum machine_mode mode;
4491 if (regno < 24 && !AVR_ENHANCED)
4493 return !(regno & 1);
4496 /* Returns 1 if we know register operand OP was 0 before INSN. */
4499 reg_was_0 (insn, op)
4504 return (optimize > 0 && insn && op && REG_P (op)
4505 && (link = find_reg_note (insn, REG_WAS_0, 0))
4506 /* Make sure the insn that stored the 0 is still present. */
4507 && ! INSN_DELETED_P (XEXP (link, 0))
4508 && GET_CODE (XEXP (link, 0)) != NOTE
4509 /* Make sure cross jumping didn't happen here. */
4510 && no_labels_between_p (XEXP (link, 0), insn)
4511 /* Make sure the reg hasn't been clobbered. */
4512 && ! reg_set_between_p (op, XEXP (link, 0), insn));
4515 /* Returns 1 if X is a valid address for an I/O register of size SIZE
4516 (1 or 2). Used for lds/sts -> in/out optimization. */
4519 io_address_p (x, size)
4523 return (optimize > 0 && GET_CODE (x) == CONST_INT
4524 && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size);
4527 /* Returns nonzero (bit number + 1) if X, or -X, is a constant power of 2. */
4530 const_int_pow2_p (x)
4533 if (GET_CODE (x) == CONST_INT)
4535 HOST_WIDE_INT d = INTVAL (x);
4536 HOST_WIDE_INT abs_d = (d >= 0) ? d : -d;
4537 return exact_log2 (abs_d) + 1;
4543 output_reload_inhi (insn, operands, len)
4544 rtx insn ATTRIBUTE_UNUSED;
4548 if (GET_CODE (operands[1]) == CONST_INT)
4550 int val = INTVAL (operands[1]);
4551 if ((val & 0xff) == 0)
4554 return (AS2 (mov,%A0,__zero_reg__) CR_TAB
4555 AS2 (ldi,%2,hi8(%1)) CR_TAB
4558 else if ((val & 0xff00) == 0)
4561 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
4562 AS2 (mov,%A0,%2) CR_TAB
4563 AS2 (mov,%B0,__zero_reg__));
4565 else if ((val & 0xff) == ((val & 0xff00) >> 8))
4568 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
4569 AS2 (mov,%A0,%2) CR_TAB
4574 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
4575 AS2 (mov,%A0,%2) CR_TAB
4576 AS2 (ldi,%2,hi8(%1)) CR_TAB
4582 output_reload_insisf (insn, operands, which_alternative)
4583 rtx insn ATTRIBUTE_UNUSED;
4585 int which_alternative ATTRIBUTE_UNUSED;
4587 int cnst = (GET_CODE (operands[1]) == CONST_INT);
4589 if (cnst && ((INTVAL (operands[1]) & 0xff) == 0))
4590 output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
4593 output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
4594 output_asm_insn (AS2 (mov, %A0, %2), operands);
4596 if (cnst && ((INTVAL (operands[1]) & 0xff00) == 0))
4597 output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
4600 output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
4601 output_asm_insn (AS2 (mov, %B0, %2), operands);
4603 if (cnst && ((INTVAL (operands[1]) & 0xff0000) == 0))
4604 output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
4607 output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
4608 output_asm_insn (AS2 (mov, %C0, %2), operands);
4610 if (cnst && ((INTVAL (operands[1]) & 0xff000000U) == 0))
4611 output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
4614 output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
4615 output_asm_insn (AS2 (mov, %D0, %2), operands);