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 /* Size of all jump tables in the current function, in words. */
92 static int jump_tables_size;
94 /* Initial stack value specified by the `-minit-stack=' option */
95 const char *avr_init_stack = "__stack";
97 /* Default MCU name */
98 const char *avr_mcu_name = "avr2";
100 /* More than 8K of program memory: use "call" and "jmp". */
103 /* Enhanced core: use "movw", "mul", ... */
104 int avr_enhanced_p = 0;
119 /* List of all known AVR MCU types - if updated, it has to be kept
120 in sync in several places (FIXME: is there a better way?):
122 - avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
123 - t-avr (MULTILIB_MATCHES)
124 - gas/config/tc-avr.c
127 static const struct mcu_type_s avr_mcu_types[] = {
128 /* Classic, <= 8K. */
130 { "at90s2313", AVR2 },
131 { "at90s2323", AVR2 },
132 { "attiny22", AVR2 },
133 { "at90s2333", AVR2 },
134 { "at90s2343", AVR2 },
135 { "at90s4414", AVR2 },
136 { "at90s4433", AVR2 },
137 { "at90s4434", AVR2 },
138 { "at90s8515", AVR2 },
139 { "at90c8534", AVR2 },
140 { "at90s8535", AVR2 },
143 { "atmega103", AVR3 },
144 { "atmega603", AVR3 },
145 /* Enhanced, <= 8K. */
147 { "atmega83", AVR4 },
148 { "atmega85", AVR4 },
149 /* Enhanced, > 8K. */
151 { "atmega161", AVR5 },
152 { "atmega163", AVR5 },
153 { "atmega32", AVR5 },
155 /* Assembler only. */
157 { "at90s1200", AVR1 },
158 { "attiny10", AVR1 },
159 { "attiny11", AVR1 },
160 { "attiny12", AVR1 },
161 { "attiny15", AVR1 },
162 { "attiny28", AVR1 },
166 int avr_case_values_threshold = 30000;
169 avr_override_options ()
171 const struct mcu_type_s *t;
173 for (t = avr_mcu_types; t->name; t++)
174 if (strcmp (t->name, avr_mcu_name) == 0)
179 fprintf (stderr, "Unknown MCU `%s' specified\nKnown MCU names:\n",
181 for (t = avr_mcu_types; t->name; t++)
182 fprintf (stderr," %s\n", t->name);
183 fatal ("select right MCU name");
190 fatal ("MCU `%s' not supported", avr_mcu_name);
191 case AVR2: avr_enhanced_p = 0; avr_mega_p = 0; break;
192 case AVR3: avr_enhanced_p = 0; avr_mega_p = 1; break;
193 case AVR4: avr_enhanced_p = 1; avr_mega_p = 0; break;
194 case AVR5: avr_enhanced_p = 1; avr_mega_p = 1; break;
197 if (optimize && !TARGET_NO_TABLEJUMP)
198 avr_case_values_threshold = (!AVR_MEGA || TARGET_CALL_PROLOGUES) ? 8 : 17;
202 /* Initialize TMP_REG_RTX and ZERO_REG_RTX */
206 tmp_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
207 memset (tmp_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
208 PUT_CODE (tmp_reg_rtx, REG);
209 PUT_MODE (tmp_reg_rtx, QImode);
210 XINT (tmp_reg_rtx, 0) = TMP_REGNO;
212 zero_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
213 memset (zero_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
214 PUT_CODE (zero_reg_rtx, REG);
215 PUT_MODE (zero_reg_rtx, QImode);
216 XINT (zero_reg_rtx, 0) = ZERO_REGNO;
218 ldi_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
219 memset (ldi_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
220 PUT_CODE (ldi_reg_rtx, REG);
221 PUT_MODE (ldi_reg_rtx, QImode);
222 XINT (ldi_reg_rtx, 0) = LDI_REG_REGNO;
225 /* return register class from register number */
227 static int reg_class_tab[]={
228 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
229 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
230 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
231 GENERAL_REGS, /* r0 - r15 */
232 LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
233 LD_REGS, /* r16 - 23 */
234 ADDW_REGS,ADDW_REGS, /* r24,r25 */
235 POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
236 POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
237 POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
238 STACK_REG,STACK_REG /* SPL,SPH */
241 /* Return register class for register R */
244 avr_regno_reg_class (r)
248 return reg_class_tab[r];
253 /* A C expression which defines the machine-dependent operand
254 constraint letters for register classes. If C is such a
255 letter, the value should be the register class corresponding to
256 it. Otherwise, the value should be `NO_REGS'. The register
257 letter `r', corresponding to class `GENERAL_REGS', will not be
258 passed to this macro; you do not need to handle it. */
261 avr_reg_class_from_letter (c)
266 case 't' : return R0_REG;
267 case 'b' : return BASE_POINTER_REGS;
268 case 'e' : return POINTER_REGS;
269 case 'w' : return ADDW_REGS;
270 case 'd' : return LD_REGS;
271 case 'l' : return NO_LD_REGS;
272 case 'a' : return SIMPLE_LD_REGS;
273 case 'x' : return POINTER_X_REGS;
274 case 'y' : return POINTER_Y_REGS;
275 case 'z' : return POINTER_Z_REGS;
276 case 'q' : return STACK_REG;
282 /* Return non-zero if FUNC is a naked function. */
285 avr_naked_function_p (func)
290 if (TREE_CODE (func) != FUNCTION_DECL)
293 a = lookup_attribute ("naked", DECL_MACHINE_ATTRIBUTES (func));
294 return a != NULL_TREE;
297 /* Return nonzero if FUNC is an interrupt function as specified
298 by the "interrupt" attribute. */
301 interrupt_function_p (func)
306 if (TREE_CODE (func) != FUNCTION_DECL)
309 a = lookup_attribute ("interrupt", DECL_MACHINE_ATTRIBUTES (func));
310 return a != NULL_TREE;
313 /* Return nonzero if FUNC is a signal function as specified
314 by the "signal" attribute. */
317 signal_function_p (func)
322 if (TREE_CODE (func) != FUNCTION_DECL)
325 a = lookup_attribute ("signal", DECL_MACHINE_ATTRIBUTES (func));
326 return a != NULL_TREE;
329 /* Compute offset between arg_pointer and frame_pointer */
332 initial_elimination_offset (from, to)
337 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
341 int interrupt_func_p = interrupt_function_p (current_function_decl);
342 int signal_func_p = signal_function_p (current_function_decl);
343 int leaf_func_p = leaf_function_p ();
344 int offset= frame_pointer_needed ? 2 : 0;
346 for (reg = 0; reg < 32; ++reg)
348 if ((!leaf_func_p && (call_used_regs[reg]
349 && (interrupt_func_p || signal_func_p)))
350 || (regs_ever_live[reg]
351 && (!call_used_regs[reg] || interrupt_func_p || signal_func_p)
352 && ! (frame_pointer_needed
353 && (reg == REG_Y || reg == (REG_Y+1)))))
358 return get_frame_size () + 2 + 1 + offset;
363 /* This function checks sequence of live registers */
372 for (reg = 0; reg < 18; ++reg)
374 if (!call_used_regs[reg])
376 if (regs_ever_live[reg])
386 if (!frame_pointer_needed)
388 if (regs_ever_live[REG_Y])
396 if (regs_ever_live[REG_Y+1])
409 return (cur_seq == live_seq) ? live_seq : 0;
413 /* Output to FILE the asm instructions to adjust the frame pointer by
414 ADJ (r29:r28 -= ADJ;) which can be positive (prologue) or negative
415 (epilogue). Returns the number of instructions generated. */
418 out_adj_frame_ptr (file, adj)
426 if (TARGET_TINY_STACK)
428 if (adj < -63 || adj > 63)
429 warning ("large frame pointer change (%d) with -mtiny-stack", adj);
431 /* The high byte (r29) doesn't change - prefer "subi" (1 cycle)
432 over "sbiw" (2 cycles, same size). */
434 fprintf (file, (AS2 (subi, r28, %d) CR_TAB), adj);
437 else if (adj < -63 || adj > 63)
439 fprintf (file, (AS2 (subi, r28, lo8(%d)) CR_TAB
440 AS2 (sbci, r29, hi8(%d)) CR_TAB),
446 fprintf (file, (AS2 (adiw, r28, %d) CR_TAB), -adj);
451 fprintf (file, (AS2 (sbiw, r28, %d) CR_TAB), adj);
459 /* Output to FILE the asm instructions to copy r29:r28 to SPH:SPL,
460 handling various cases of interrupt enable flag state BEFORE and AFTER
461 (0=disabled, 1=enabled, -1=unknown/unchanged) and target_flags.
462 Returns the number of instructions generated. */
465 out_set_stack_ptr (file, before, after)
470 int do_sph, do_cli, do_save, do_sei, lock_sph, size;
472 /* The logic here is so that -mno-interrupts actually means
473 "it is safe to write SPH in one instruction, then SPL in the
474 next instruction, without disabling interrupts first".
475 The after != -1 case (interrupt/signal) is not affected. */
477 do_sph = !TARGET_TINY_STACK;
478 lock_sph = do_sph && !TARGET_NO_INTERRUPTS;
479 do_cli = (before != 0 && (after == 0 || lock_sph));
480 do_save = (do_cli && before == -1 && after == -1);
481 do_sei = ((do_cli || before != 1) && after == 1);
486 fprintf (file, AS2 (in, __tmp_reg__, __SREG__) CR_TAB);
492 fprintf (file, "cli" CR_TAB);
496 /* Do SPH first - maybe this will disable interrupts for one instruction
497 someday (a suggestion has been sent to avr@atmel.com for consideration
498 in future devices - that would make -mno-interrupts always safe). */
501 fprintf (file, AS2 (out, __SP_H__, r29) CR_TAB);
505 /* Set/restore the I flag now - interrupts will be really enabled only
506 after the next instruction starts. This was not clearly documented.
507 XXX - verify this on the new devices with enhanced AVR core. */
510 fprintf (file, AS2 (out, __SREG__, __tmp_reg__) CR_TAB);
515 fprintf (file, "sei" CR_TAB);
519 fprintf (file, AS2 (out, __SP_L__, r28) "\n");
525 /* Output function prologue */
528 function_prologue (file, size)
533 int interrupt_func_p;
540 if (avr_naked_function_p (current_function_decl))
542 fprintf (file, "/* prologue: naked */\n");
546 interrupt_func_p = interrupt_function_p (current_function_decl);
547 signal_func_p = signal_function_p (current_function_decl);
548 leaf_func_p = leaf_function_p ();
549 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
550 live_seq = sequent_regs_live ();
551 minimize = (TARGET_CALL_PROLOGUES
552 && !interrupt_func_p && !signal_func_p && live_seq);
554 last_insn_address = 0;
555 jump_tables_size = 0;
557 fprintf (file, "/* prologue: frame size=%d */\n", size);
559 if (interrupt_func_p)
561 fprintf (file,"\tsei\n");
564 if (interrupt_func_p | signal_func_p)
567 AS1 (push,__zero_reg__) CR_TAB
568 AS1 (push,__tmp_reg__) CR_TAB
569 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
570 AS1 (push,__tmp_reg__) CR_TAB
571 AS1 (clr,__zero_reg__) "\n");
577 AS2 (ldi,r28,lo8(%s - %d)) CR_TAB
578 AS2 (ldi,r29,hi8(%s - %d)) CR_TAB
579 AS2 (out,__SP_H__,r29) CR_TAB
580 AS2 (out,__SP_L__,r28) "\n"),
581 avr_init_stack, size, avr_init_stack, size);
585 else if (minimize && (frame_pointer_needed || live_seq > 6))
588 AS2 (ldi, r26, lo8(%d)) CR_TAB
589 AS2 (ldi, r27, hi8(%d)) CR_TAB), size, size);
591 fprintf (file, (AS2 (ldi, r30, pm_lo8(.L_%s_body)) CR_TAB
592 AS2 (ldi, r31, pm_hi8(.L_%s_body)) CR_TAB)
593 ,current_function_name, current_function_name);
599 fprintf (file, AS1 (jmp,__prologue_saves__+%d) "\n",
600 (18 - live_seq) * 2);
605 fprintf (file, AS1 (rjmp,__prologue_saves__+%d) "\n",
606 (18 - live_seq) * 2);
609 fprintf (file, ".L_%s_body:\n", current_function_name);
613 for (reg = 0; reg < 32; ++reg)
616 && (call_used_regs[reg]
617 && (interrupt_func_p || signal_func_p)
618 && !(reg == TMP_REGNO || reg == ZERO_REGNO)))
619 || (regs_ever_live[reg]
620 && (!call_used_regs[reg]
621 || interrupt_func_p || signal_func_p)
622 && ! (frame_pointer_needed
623 && (reg == REG_Y || reg == (REG_Y+1)))))
625 fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
629 if (frame_pointer_needed)
633 AS1 (push,r28) CR_TAB
634 AS1 (push,r29) CR_TAB
635 AS2 (in,r28,__SP_L__) CR_TAB
636 AS2 (in,r29,__SP_H__) "\n");
641 prologue_size += out_adj_frame_ptr (file, size);
643 if (interrupt_func_p)
645 prologue_size += out_set_stack_ptr (file, 1, 1);
647 else if (signal_func_p)
649 prologue_size += out_set_stack_ptr (file, 0, 0);
653 prologue_size += out_set_stack_ptr (file, -1, -1);
659 fprintf (file, "/* prologue end (size=%d) */\n", prologue_size);
662 /* Output function epilogue */
665 function_epilogue (file, size)
670 int interrupt_func_p;
678 if (avr_naked_function_p (current_function_decl))
680 fprintf (file, "/* epilogue: naked */\n");
684 interrupt_func_p = interrupt_function_p (current_function_decl);
685 signal_func_p = signal_function_p (current_function_decl);
686 leaf_func_p = leaf_function_p ();
687 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
688 function_size = (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
689 - INSN_ADDRESSES (INSN_UID (get_insns ())));
690 function_size += jump_tables_size;
691 live_seq = sequent_regs_live ();
692 minimize = (TARGET_CALL_PROLOGUES
693 && !interrupt_func_p && !signal_func_p && live_seq);
696 fprintf (file, "/* epilogue: frame size=%d */\n", size);
699 fprintf (file, "__stop_progIi__:\n\trjmp __stop_progIi__\n");
702 else if (minimize && (frame_pointer_needed || live_seq > 4))
704 fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
706 if (frame_pointer_needed)
708 epilogue_size += out_adj_frame_ptr (file, -size);
712 fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
713 AS2 (in , r29, __SP_H__) CR_TAB));
719 fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
720 (18 - live_seq) * 2);
725 fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
726 (18 - live_seq) * 2);
732 if (frame_pointer_needed)
737 epilogue_size += out_adj_frame_ptr (file, -size);
739 if (interrupt_func_p | signal_func_p)
741 epilogue_size += out_set_stack_ptr (file, -1, 0);
745 epilogue_size += out_set_stack_ptr (file, -1, -1);
754 for (reg = 31; reg >= 0; --reg)
757 && (call_used_regs[reg]
758 && (interrupt_func_p || signal_func_p)
759 && !(reg == TMP_REGNO || reg == ZERO_REGNO)))
760 || (regs_ever_live[reg]
761 && (!call_used_regs[reg]
762 || interrupt_func_p || signal_func_p)
763 && ! (frame_pointer_needed
764 && (reg == REG_Y || reg == (REG_Y+1)))))
766 fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
771 if (interrupt_func_p | signal_func_p)
774 AS1 (pop,__tmp_reg__) CR_TAB
775 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
776 AS1 (pop,__tmp_reg__) CR_TAB
777 AS1 (pop,__zero_reg__) "\n");
779 fprintf (file, "\treti\n");
782 fprintf (file, "\tret\n");
786 fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
787 fprintf (file, "/* function %s size %d (%d) */\n", current_function_name,
788 prologue_size + function_size + epilogue_size, function_size);
789 commands_in_file += prologue_size + function_size + epilogue_size;
790 commands_in_prologues += prologue_size;
791 commands_in_epilogues += epilogue_size;
795 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
796 machine for a memory operand of mode MODE. */
799 legitimate_address_p (mode, x, strict)
800 enum machine_mode mode;
805 if (TARGET_ALL_DEBUG)
807 fprintf (stderr, "mode: (%s) %s %s %s %s:",
809 strict ? "(strict)": "",
810 reload_completed ? "(reload_completed)": "",
811 reload_in_progress ? "(reload_in_progress)": "",
812 reg_renumber ? "(reg_renumber)" : "");
813 if (GET_CODE (x) == PLUS
814 && REG_P (XEXP (x, 0))
815 && GET_CODE (XEXP (x, 1)) == CONST_INT
816 && INTVAL (XEXP (x, 1)) >= 0
817 && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
820 fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
821 true_regnum (XEXP (x, 0)));
824 if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
825 : REG_OK_FOR_BASE_NOSTRICT_P (x)))
827 else if (CONSTANT_ADDRESS_P (x))
829 else if (GET_CODE (x) == PLUS
830 && REG_P (XEXP (x, 0))
831 && GET_CODE (XEXP (x, 1)) == CONST_INT
832 && INTVAL (XEXP (x, 1)) >= 0)
834 int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
838 || REGNO (XEXP (x,0)) == REG_Y
839 || REGNO (XEXP (x,0)) == REG_Z)
841 if (XEXP (x,0) == frame_pointer_rtx
842 || XEXP (x,0) == arg_pointer_rtx)
845 else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
848 else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
849 && REG_P (XEXP (x, 0))
850 && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
851 : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
855 if (TARGET_ALL_DEBUG)
857 fprintf (stderr, " ret = %c\n", r);
862 /* Attempts to replace X with a valid
863 memory address for an operand of mode MODE */
866 legitimize_address (x, oldx, mode)
869 enum machine_mode mode;
872 if (TARGET_ALL_DEBUG)
874 fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
878 if (GET_CODE (oldx) == PLUS
879 && REG_P (XEXP (oldx,0)))
881 if (REG_P (XEXP (oldx,1)))
882 x = force_reg (GET_MODE (oldx), oldx);
883 else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
885 int offs = INTVAL (XEXP (oldx,1));
886 if (frame_pointer_rtx != XEXP (oldx,0))
887 if (offs > MAX_LD_OFFSET (mode))
889 if (TARGET_ALL_DEBUG)
890 fprintf (stderr, "force_reg (big offset)\n");
891 x = force_reg (GET_MODE (oldx), oldx);
899 /* Return a pointer register name as a string */
902 ptrreg_to_str (regno)
907 case REG_X: return "X";
908 case REG_Y: return "Y";
909 case REG_Z: return "Z";
911 fatal ("register r%d isn't a pointer\n", regno);
916 /* Return the condition name as a string.
917 Used in conditional jump constructing */
930 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
935 fatal ("Internal compiler bug: command `bgt'");
937 fatal ("Internal compiler bug: command `ble'");
939 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
946 fatal ("Internal compiler bug: command `bgtu'");
948 fatal ("Internal compiler bug: command `bleu'");
956 /* Output ADDR to FILE as address */
959 print_operand_address (file, addr)
963 switch (GET_CODE (addr))
966 fprintf (file, ptrreg_to_str (REGNO (addr)));
970 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
974 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
978 if (CONSTANT_ADDRESS_P (addr)
979 && (SYMBOL_REF_FLAG (addr) || GET_CODE (addr) == LABEL_REF))
981 fprintf (file, "pm(");
982 output_addr_const (file,addr);
986 output_addr_const (file, addr);
991 /* Output X as assembler operand to file FILE */
994 print_operand (file, x, code)
1001 if (code >= 'A' && code <= 'D')
1006 if (x == zero_reg_rtx)
1007 fprintf (file,"__zero_reg__");
1009 fprintf (file, reg_names[true_regnum (x) + abcd]);
1011 else if (GET_CODE (x) == CONST_INT)
1012 fprintf (file, "%d", INTVAL (x) + abcd);
1013 else if (GET_CODE (x) == MEM)
1015 rtx addr = XEXP (x,0);
1017 if (CONSTANT_P (addr) && abcd)
1020 output_address (addr);
1021 fprintf (file, ")+%d", abcd);
1023 else if (GET_CODE (addr) == PLUS)
1025 print_operand_address (file, XEXP (addr,0));
1026 if (REGNO (XEXP (addr, 0)) == REG_X)
1027 fatal_insn ("Internal compiler bug.\nBad address:"
1030 print_operand (file, XEXP (addr,1), code);
1033 print_operand_address (file, addr);
1035 else if (GET_CODE (x) == CONST_DOUBLE)
1039 if (GET_MODE (x) != SFmode)
1040 fatal_insn ("Internal compiler bug. Unknown mode:", x);
1041 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1042 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1043 asm_fprintf (file, "0x%lx", val);
1045 else if (code == 'j')
1046 asm_fprintf (file, cond_string (GET_CODE (x)));
1047 else if (code == 'k')
1048 asm_fprintf (file, cond_string (reverse_condition (GET_CODE (x))));
1050 print_operand_address (file, x);
1053 /* Recognize operand OP of mode MODE used in call instructions */
1056 call_insn_operand (op, mode)
1058 enum machine_mode mode ATTRIBUTE_UNUSED;
1060 if (GET_CODE (op) == MEM)
1062 rtx inside = XEXP (op, 0);
1063 if (register_operand (inside, Pmode))
1065 if (CONSTANT_ADDRESS_P (inside))
1071 /* Update the condition code in the INSN. */
1074 notice_update_cc (body, insn)
1075 rtx body ATTRIBUTE_UNUSED;
1080 switch (get_attr_cc (insn))
1083 /* Insn does not affect CC at all. */
1091 set = single_set (insn);
1095 cc_status.flags |= CC_NO_OVERFLOW;
1096 cc_status.value1 = SET_DEST (set);
1101 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1102 The V flag may or may not be known but that's ok because
1103 alter_cond will change tests to use EQ/NE. */
1104 set = single_set (insn);
1108 cc_status.value1 = SET_DEST (set);
1109 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1114 set = single_set (insn);
1117 cc_status.value1 = SET_SRC (set);
1121 /* Insn doesn't leave CC in a usable state. */
1124 /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1125 set = single_set (insn);
1128 rtx src = SET_SRC (set);
1130 if (GET_CODE (src) == ASHIFTRT
1131 && GET_MODE (src) == QImode)
1133 rtx x = XEXP (src, 1);
1135 if (GET_CODE (x) == CONST_INT
1138 cc_status.value1 = SET_DEST (set);
1139 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1147 /* Return maximum number of consecutive registers of
1148 class CLASS needed to hold a value of mode MODE. */
1151 class_max_nregs (class, mode)
1152 enum reg_class class ATTRIBUTE_UNUSED;
1153 enum machine_mode mode;
1155 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1158 /* Choose mode for jump insn:
1159 1 - relative jump in range -63 <= x <= 62 ;
1160 2 - relative jump in range -2046 <= x <= 2045 ;
1161 3 - absolute jump (only for ATmega[16]03). */
1164 avr_jump_mode (x, insn)
1165 rtx x; /* jump operand */
1166 rtx insn; /* jump insn */
1168 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1169 ? XEXP (x, 0) : x));
1170 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1171 int jump_distance = cur_addr - dest_addr;
1173 if (-63 <= jump_distance && jump_distance <= 62)
1175 else if (-2046 <= jump_distance && jump_distance <= 2045)
1183 /* return a AVR condition jump commands.
1184 LEN is a number returned by avr_jump_mode function. */
1187 ret_cond_branch (cond, len)
1194 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1195 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1197 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1198 AS1 (brmi,_PC_+2) CR_TAB
1200 (AS1 (breq,_PC_+6) CR_TAB
1201 AS1 (brmi,_PC_+4) CR_TAB
1205 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1207 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1208 AS1 (brlt,_PC_+2) CR_TAB
1210 (AS1 (breq,_PC_+6) CR_TAB
1211 AS1 (brlt,_PC_+4) CR_TAB
1214 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1216 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1217 AS1 (brlo,_PC_+2) CR_TAB
1219 (AS1 (breq,_PC_+6) CR_TAB
1220 AS1 (brlo,_PC_+4) CR_TAB
1223 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1224 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1226 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1227 AS1 (brpl,_PC_+2) CR_TAB
1229 (AS1 (breq,_PC_+2) CR_TAB
1230 AS1 (brpl,_PC_+4) CR_TAB
1233 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1235 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1236 AS1 (brge,_PC_+2) CR_TAB
1238 (AS1 (breq,_PC_+2) CR_TAB
1239 AS1 (brge,_PC_+4) CR_TAB
1242 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1244 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1245 AS1 (brsh,_PC_+2) CR_TAB
1247 (AS1 (breq,_PC_+2) CR_TAB
1248 AS1 (brsh,_PC_+4) CR_TAB
1254 return AS1 (br%j1,%0);
1256 return (AS1 (br%k1,_PC_+2) CR_TAB
1259 return (AS1 (br%k1,_PC_+4) CR_TAB
1266 /* Predicate function for immediate operand which fits to byte (8bit) */
1269 byte_immediate_operand (op, mode)
1271 enum machine_mode mode ATTRIBUTE_UNUSED;
1273 return (GET_CODE (op) == CONST_INT
1274 && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1277 /* Output all insn addresses and their sizes into the assembly language
1278 output file. This is helpful for debugging whether the length attributes
1279 in the md file are correct.
1280 Output insn cost for next insn. */
1283 final_prescan_insn (insn, operand, num_operands)
1284 rtx insn, *operand ATTRIBUTE_UNUSED;
1285 int num_operands ATTRIBUTE_UNUSED;
1287 int uid = INSN_UID (insn);
1289 if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1291 fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1292 INSN_ADDRESSES (uid),
1293 INSN_ADDRESSES (uid) - last_insn_address,
1294 rtx_cost (PATTERN (insn), INSN));
1296 last_insn_address = INSN_ADDRESSES (uid);
1298 if (TARGET_RTL_DUMP)
1300 fprintf (asm_out_file, "/*****************\n");
1301 print_rtl_single (asm_out_file, insn);
1302 fprintf (asm_out_file, "*****************/\n");
1306 /* Return 0 if undefined, 1 if always true or always false. */
1309 avr_simplify_comparision_p (mode, operator, x)
1310 enum machine_mode mode;
1314 unsigned int max = (mode == QImode ? 0xff :
1315 mode == HImode ? 0xffff :
1316 mode == SImode ? 0xffffffffU : 0);
1317 if (max && operator && GET_CODE (x) == CONST_INT)
1319 if (unsigned_condition (operator) != operator)
1322 if (max != (INTVAL (x) & max)
1323 && INTVAL (x) != 0xff)
1330 /* Returns nonzero if REGNO is the number of a hard
1331 register in which function arguments are sometimes passed. */
1334 function_arg_regno_p(r)
1337 return (r >= 8 && r <= 25);
1340 /* Initializing the variable cum for the state at the beginning
1341 of the argument list. */
1344 init_cumulative_args (cum, fntype, libname, indirect)
1345 CUMULATIVE_ARGS *cum;
1348 int indirect ATTRIBUTE_UNUSED;
1351 cum->regno = FIRST_CUM_REG;
1354 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1355 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1356 != void_type_node));
1362 /* Returns the number of registers to allocate for a function argument. */
1365 avr_num_arg_regs (mode, type)
1366 enum machine_mode mode;
1371 if (mode == BLKmode)
1372 size = int_size_in_bytes (type);
1374 size = GET_MODE_SIZE (mode);
1376 /* Align all function arguments to start in even-numbered registers.
1377 Odd-sized arguments leave holes above them. */
1379 return (size + 1) & ~1;
1382 /* Controls whether a function argument is passed
1383 in a register, and which register. */
1386 function_arg (cum, mode, type, named)
1387 CUMULATIVE_ARGS *cum;
1388 enum machine_mode mode;
1390 int named ATTRIBUTE_UNUSED;
1392 int bytes = avr_num_arg_regs (mode, type);
1394 if (cum->nregs && bytes <= cum->nregs)
1395 return gen_rtx (REG, mode, cum->regno - bytes);
1400 /* Update the summarizer variable CUM to advance past an argument
1401 in the argument list. */
1404 function_arg_advance (cum, mode, type, named)
1405 CUMULATIVE_ARGS *cum; /* current arg information */
1406 enum machine_mode mode; /* current arg mode */
1407 tree type; /* type of the argument or 0 if lib support */
1408 int named ATTRIBUTE_UNUSED; /* whether or not the argument was named */
1410 int bytes = avr_num_arg_regs (mode, type);
1412 cum->nregs -= bytes;
1413 cum->regno -= bytes;
1415 if (cum->nregs <= 0)
1418 cum->regno = FIRST_CUM_REG;
1422 /***********************************************************************
1423 Functions for outputting various mov's for a various modes
1424 ************************************************************************/
1426 output_movqi (insn, operands, l)
1432 rtx dest = operands[0];
1433 rtx src = operands[1];
1441 if (register_operand (dest, QImode))
1443 if (register_operand (src, QImode)) /* mov r,r */
1445 if (test_hard_reg_class (STACK_REG, dest))
1446 return AS2 (out,%0,%1);
1447 else if (test_hard_reg_class (STACK_REG, src))
1448 return AS2 (in,%0,%1);
1450 return AS2 (mov,%0,%1);
1452 else if (CONSTANT_P (src))
1454 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1455 return AS2 (ldi,%0,lo8(%1));
1457 if (GET_CODE (src) == CONST_INT)
1459 if (src == const0_rtx) /* mov r,L */
1460 return AS1 (clr,%0);
1461 else if (src == const1_rtx)
1463 if (reg_was_0 (insn, dest))
1464 return AS1 (inc,%0 ; reg_was_0);
1467 return (AS1 (clr,%0) CR_TAB
1470 else if (src == constm1_rtx)
1472 /* Immediate constants -1 to any register */
1473 if (reg_was_0 (insn, dest))
1474 return AS1 (dec,%0 ; reg_was_0);
1477 return (AS1 (clr,%0) CR_TAB
1482 int bit_nr = exact_log2 (INTVAL (src));
1486 if (reg_was_0 (insn, dest))
1490 output_asm_insn ("set ; reg_was_0", operands);
1496 output_asm_insn ((AS1 (clr,%0) CR_TAB
1500 avr_output_bld (operands, bit_nr);
1507 /* Last resort, larger than loading from memory. */
1509 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1510 AS2 (ldi,r31,lo8(%1)) CR_TAB
1511 AS2 (mov,%0,r31) CR_TAB
1512 AS2 (mov,r31,__tmp_reg__));
1514 else if (GET_CODE (src) == MEM)
1515 return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1517 else if (GET_CODE (dest) == MEM)
1519 const char *template;
1521 if (src == const0_rtx)
1522 operands[1] = zero_reg_rtx;
1524 template = out_movqi_mr_r (insn, operands, real_l);
1527 output_asm_insn (template, operands);
1536 output_movhi (insn, operands, l)
1542 rtx dest = operands[0];
1543 rtx src = operands[1];
1549 if (register_operand (dest, HImode))
1551 if (register_operand (src, HImode)) /* mov r,r */
1553 if (test_hard_reg_class (STACK_REG, dest))
1555 if (TARGET_TINY_STACK)
1558 return AS2 (out,__SP_L__,%A1);
1560 else if (TARGET_NO_INTERRUPTS)
1563 return (AS2 (out,__SP_H__,%B1) CR_TAB
1564 AS2 (out,__SP_L__,%A1));
1568 return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB
1570 AS2 (out,__SP_H__,%B1) CR_TAB
1571 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1572 AS2 (out,__SP_L__,%A1));
1574 else if (test_hard_reg_class (STACK_REG, src))
1577 return (AS2 (in,%A0,__SP_L__) CR_TAB
1578 AS2 (in,%B0,__SP_H__));
1584 return (AS2 (movw,%0,%1));
1587 if (true_regnum (dest) > true_regnum (src))
1590 return (AS2 (mov,%B0,%B1) CR_TAB
1596 return (AS2 (mov,%A0,%A1) CR_TAB
1600 else if (CONSTANT_P (src))
1602 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1604 if (byte_immediate_operand (src, HImode)
1605 && reg_was_0 (insn, dest))
1608 return (AS2 (ldi,%A0,lo8(%1) ; reg_was_0));
1612 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1613 AS2 (ldi,%B0,hi8(%1)));
1616 if (GET_CODE (src) == CONST_INT)
1618 if (src == const0_rtx) /* mov r,L */
1621 return (AS1 (clr,%A0) CR_TAB
1624 else if (src == const1_rtx)
1626 if (reg_was_0 (insn, dest))
1629 return AS1 (inc,%0 ; reg_was_0);
1633 return (AS1 (clr,%A0) CR_TAB
1634 AS1 (clr,%B0) 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
1654 int bit_nr = exact_log2 (INTVAL (src));
1658 if (reg_was_0 (insn, dest))
1662 output_asm_insn ("set ; reg_was_0", operands);
1668 output_asm_insn ((AS1 (clr,%A0) CR_TAB
1669 AS1 (clr,%B0) CR_TAB
1673 avr_output_bld (operands, bit_nr);
1679 if ((INTVAL (src) & 0xff) == 0)
1682 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1683 AS1 (clr,%A0) CR_TAB
1684 AS2 (ldi,r31,hi8(%1)) CR_TAB
1685 AS2 (mov,%B0,r31) CR_TAB
1686 AS2 (mov,r31,__tmp_reg__));
1688 else if ((INTVAL (src) & 0xff00) == 0)
1691 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1692 AS2 (ldi,r31,lo8(%1)) CR_TAB
1693 AS2 (mov,%A0,r31) CR_TAB
1694 AS1 (clr,%B0) CR_TAB
1695 AS2 (mov,r31,__tmp_reg__));
1699 /* Last resort, equal to loading from memory. */
1701 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1702 AS2 (ldi,r31,lo8(%1)) CR_TAB
1703 AS2 (mov,%A0,r31) CR_TAB
1704 AS2 (ldi,r31,hi8(%1)) CR_TAB
1705 AS2 (mov,%B0,r31) CR_TAB
1706 AS2 (mov,r31,__tmp_reg__));
1708 else if (GET_CODE (src) == MEM)
1709 return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1711 else if (GET_CODE (dest) == MEM)
1713 const char *template;
1715 if (src == const0_rtx)
1716 operands[1] = zero_reg_rtx;
1718 template = out_movhi_mr_r (insn, operands, real_l);
1721 output_asm_insn (template, operands);
1726 fatal_insn ("Invalid insn:", insn);
1731 out_movqi_r_mr (insn, op, l)
1734 int *l; /* instruction length */
1738 rtx x = XEXP (src, 0);
1744 if (CONSTANT_ADDRESS_P (x))
1746 if (io_address_p (x, 1))
1749 return AS2 (in,%0,%1-0x20);
1752 return AS2 (lds,%0,%1);
1754 /* memory access by reg+disp */
1755 else if (GET_CODE (x) == PLUS
1756 && REG_P (XEXP (x,0))
1757 && GET_CODE (XEXP (x,1)) == CONST_INT)
1759 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1761 int disp = INTVAL (XEXP (x,1));
1762 if (REGNO (XEXP (x,0)) != REG_Y)
1763 fatal_insn ("Incorrect insn:",insn);
1764 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1767 op[4] = XEXP (x, 1);
1768 return (AS2 (adiw, r28, %4-63) CR_TAB
1769 AS2 (ldd, %0,Y+63) CR_TAB
1770 AS2 (sbiw, r28, %4-63));
1776 return (AS2 (subi, r28, lo8(-%4)) CR_TAB
1777 AS2 (sbci, r29, hi8(-%4)) CR_TAB
1778 AS2 (ld, %0,Y) CR_TAB
1779 AS2 (subi, r28, lo8(%4)) CR_TAB
1780 AS2 (sbci, r29, hi8(%4)));
1783 else if (REGNO (XEXP (x,0)) == REG_X)
1785 op[4] = XEXP (x, 1);
1786 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1787 it but I have this situation with extremal optimizing options. */
1788 if (reg_overlap_mentioned_p (dest, XEXP (x,0))
1789 || reg_unused_after (insn, XEXP (x,0)))
1792 return (AS2 (adiw,r26,%4) CR_TAB
1796 return (AS2 (adiw,r26,%4) CR_TAB
1797 AS2 (ld,%0,X) CR_TAB
1801 return AS2 (ldd,%0,%1);
1804 return AS2 (ld,%0,%1);
1808 out_movhi_r_mr (insn, op, l)
1811 int *l; /* instruction length */
1815 rtx base = XEXP (src, 0);
1816 int reg_dest = true_regnum (dest);
1817 int reg_base = true_regnum (base);
1825 if (reg_dest == reg_base) /* R = (R) */
1828 return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1829 AS2 (ld,%B0,%1) CR_TAB
1830 AS2 (mov,%A0,__tmp_reg__));
1832 else if (reg_base == REG_X) /* (R26) */
1834 if (reg_unused_after (insn, base))
1837 return (AS2 (ld,%A0,X+) CR_TAB
1841 return (AS2 (ld,%A0,X+) CR_TAB
1842 AS2 (ld,%B0,X) CR_TAB
1848 return (AS2 (ld,%A0,%1) CR_TAB
1849 AS2 (ldd,%B0,%1+1));
1852 else if (GET_CODE (base) == PLUS) /* (R + i) */
1854 int disp = INTVAL (XEXP (base, 1));
1855 int reg_base = true_regnum (XEXP (base, 0));
1857 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
1859 op[4] = XEXP (base, 1);
1861 if (REGNO (XEXP (base, 0)) != REG_Y)
1862 fatal_insn ("Incorrect insn:",insn);
1864 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1867 return (AS2 (adiw,r28,%4-62) CR_TAB
1868 AS2 (ldd,%A0,Y+62) CR_TAB
1869 AS2 (ldd,%B0,Y+63) CR_TAB
1870 AS2 (sbiw,r28,%4-62));
1875 return (AS2 (subi,r28,lo8(-%4)) CR_TAB
1876 AS2 (sbci,r29,hi8(-%4)) CR_TAB
1877 AS2 (ld,%A0,Y) CR_TAB
1878 AS2 (ldd,%B0,Y+1) CR_TAB
1879 AS2 (subi,r28,lo8(%4)) CR_TAB
1880 AS2 (sbci,r29,hi8(%4)));
1883 if (reg_base == REG_X)
1885 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1886 it but I have this situation with extremal
1887 optimization options. */
1889 op[4] = XEXP (base, 1);
1891 if (reg_base == reg_dest)
1894 return (AS2 (adiw,r26,%4) CR_TAB
1895 AS2 (ld,__tmp_reg__,X+) CR_TAB
1896 AS2 (ld,%B0,X) CR_TAB
1897 AS2 (mov,%A0,__tmp_reg__));
1900 if (INTVAL (op[4]) == 63)
1903 return (AS2 (adiw,r26,%4) CR_TAB
1904 AS2 (ld,%A0,X+) CR_TAB
1905 AS2 (ld,%B0,X) CR_TAB
1906 AS2 (subi,r26,%4+1) CR_TAB
1910 return (AS2 (adiw,r26,%4) CR_TAB
1911 AS2 (ld,%A0,X+) CR_TAB
1912 AS2 (ld,%B0,X) CR_TAB
1913 AS2 (sbiw,r26,%4+1));
1916 if (reg_base == reg_dest)
1919 return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
1920 AS2 (ldd,%B0,%B1) CR_TAB
1921 AS2 (mov,%A0,__tmp_reg__));
1925 return (AS2 (ldd,%A0,%A1) CR_TAB
1928 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
1930 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1931 fatal_insn ("Incorrect insn:", insn);
1934 return (AS2 (ld,%B0,%1) CR_TAB
1937 else if (GET_CODE (base) == POST_INC) /* (R++) */
1939 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1940 fatal_insn ("Incorrect insn:", insn);
1943 return (AS2 (ld,%A0,%1) CR_TAB
1946 else if (CONSTANT_ADDRESS_P (base))
1948 if (io_address_p (base, 2))
1951 return (AS2 (in,%A0,%A1-0x20) CR_TAB
1952 AS2 (in,%B0,%B1-0x20));
1955 return (AS2 (lds,%A0,%A1) CR_TAB
1959 fatal_insn ("Unknown move insn:",insn);
1964 out_movsi_r_mr (insn, op, l)
1967 int *l; /* instruction length */
1971 rtx base = XEXP (src, 0);
1972 int reg_dest = true_regnum (dest);
1973 int reg_base = true_regnum (base);
1981 if (reg_base == REG_X) /* (R26) */
1983 if (reg_dest == REG_X)
1984 return *l=6, (AS2 (adiw,r26,3) CR_TAB
1985 AS2 (ld,%D0,X) CR_TAB
1986 AS2 (ld,%C0,-X) CR_TAB
1987 AS2 (ld,__tmp_reg__,-X) CR_TAB
1988 AS2 (ld,%A0,-X) CR_TAB
1989 AS2 (mov,%B0,__tmp_reg__));
1990 else if (reg_dest == REG_X - 2)
1991 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
1992 AS2 (ld,%B0,X+) CR_TAB
1993 AS2 (ld,__tmp_reg__,X+) CR_TAB
1994 AS2 (ld,%D0,X) CR_TAB
1995 AS2 (mov,%C0,__tmp_reg__));
1996 else if (reg_unused_after (insn, base))
1997 return *l=4, (AS2 (ld,%A0,X+) CR_TAB
1998 AS2 (ld,%B0,X+) CR_TAB
1999 AS2 (ld,%C0,X+) CR_TAB
2002 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2003 AS2 (ld,%B0,X+) CR_TAB
2004 AS2 (ld,%C0,X+) CR_TAB
2005 AS2 (ld,%D0,X) CR_TAB
2010 if (reg_dest == reg_base)
2011 return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
2012 AS2 (ldd,%C0,%1+2) CR_TAB
2013 AS2 (ldd,__tmp_reg__,%1+1) CR_TAB
2014 AS2 (ld,%A0,%1) CR_TAB
2015 AS2 (mov,%B0,__tmp_reg__));
2016 else if (reg_base == reg_dest + 2)
2017 return *l=5, (AS2 (ld ,%A0,%1) CR_TAB
2018 AS2 (ldd,%B0,%1+1) CR_TAB
2019 AS2 (ldd,__tmp_reg__,%1+2) CR_TAB
2020 AS2 (ldd,%D0,%1+3) CR_TAB
2021 AS2 (mov,%C0,__tmp_reg__));
2023 return *l=4, (AS2 (ld ,%A0,%1) CR_TAB
2024 AS2 (ldd,%B0,%1+1) CR_TAB
2025 AS2 (ldd,%C0,%1+2) CR_TAB
2026 AS2 (ldd,%D0,%1+3));
2029 else if (GET_CODE (base) == PLUS) /* (R + i) */
2031 int disp = INTVAL (XEXP (base, 1));
2033 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2035 if (REGNO (XEXP (base, 0)) != REG_Y)
2036 fatal_insn ("Incorrect insn:",insn);
2037 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2039 op[4] = GEN_INT (disp - 60);
2040 return *l=6,(AS2 (adiw, r28, %4) CR_TAB
2041 AS2 (ldd, %A0,Y+60) CR_TAB
2042 AS2 (ldd, %B0,Y+61) CR_TAB
2043 AS2 (ldd, %C0,Y+62) CR_TAB
2044 AS2 (ldd, %D0,Y+63) CR_TAB
2045 AS2 (sbiw, r28, %4));
2049 op[4] = XEXP (base, 1);
2050 return *l=8,(AS2 (subi, r28, lo8(-%4)) CR_TAB
2051 AS2 (sbci, r29, hi8(-%4)) CR_TAB
2052 AS2 (ld, %A0,Y) CR_TAB
2053 AS2 (ldd, %B0,Y+1) CR_TAB
2054 AS2 (ldd, %C0,Y+2) CR_TAB
2055 AS2 (ldd, %D0,Y+3) CR_TAB
2056 AS2 (subi, r28, lo8(%4)) CR_TAB
2057 AS2 (sbci, r29, hi8(%4)));
2061 reg_base = true_regnum (XEXP (base, 0));
2062 if (reg_dest == reg_base)
2063 return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2064 AS2 (ldd,%C0,%C1) CR_TAB
2065 AS2 (ldd,__tmp_reg__,%B1) CR_TAB
2066 AS2 (ldd,%A0,%A1) CR_TAB
2067 AS2 (mov,%B0,__tmp_reg__));
2068 else if (reg_dest == reg_base - 2)
2069 return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2070 AS2 (ldd,%B0,%B1) CR_TAB
2071 AS2 (ldd,__tmp_reg__,%C1) CR_TAB
2072 AS2 (ldd,%D0,%D1) CR_TAB
2073 AS2 (mov,%C0,__tmp_reg__));
2074 return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2075 AS2 (ldd,%B0,%B1) CR_TAB
2076 AS2 (ldd,%C0,%C1) CR_TAB
2079 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2080 return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2081 AS2 (ld,%C0,%1) CR_TAB
2082 AS2 (ld,%B0,%1) CR_TAB
2084 else if (GET_CODE (base) == POST_INC) /* (R++) */
2085 return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2086 AS2 (ld,%B0,%1) CR_TAB
2087 AS2 (ld,%C0,%1) CR_TAB
2089 else if (CONSTANT_ADDRESS_P (base))
2090 return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2091 AS2 (lds,%B0,%B1) CR_TAB
2092 AS2 (lds,%C0,%C1) CR_TAB
2095 fatal_insn ("Unknown move insn:",insn);
2100 out_movsi_mr_r (insn, op, l)
2107 rtx base = XEXP (dest, 0);
2108 int reg_base = true_regnum (base);
2109 int reg_src = true_regnum (src);
2115 if (CONSTANT_ADDRESS_P (base))
2116 return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2117 AS2 (sts,%B0,%B1) CR_TAB
2118 AS2 (sts,%C0,%C1) CR_TAB
2120 if (reg_base > 0) /* (r) */
2122 if (reg_base == REG_X) /* (R26) */
2124 if (reg_src == REG_X)
2126 if (reg_unused_after (insn, base))
2127 return *l=5, (AS2 (mov,__tmp_reg__,%B1) CR_TAB
2128 AS2 (st,%0+,%A1) CR_TAB
2129 AS2 (st,%0+,__tmp_reg__) CR_TAB
2130 AS2 (st,%0+,%C1) CR_TAB
2133 return *l=6, (AS2 (mov,__tmp_reg__,%B1) CR_TAB
2134 AS2 (st,%0+,%A1) CR_TAB
2135 AS2 (st,%0+,__tmp_reg__) CR_TAB
2136 AS2 (st,%0+,%C1) CR_TAB
2137 AS2 (st,%0,%D1) CR_TAB
2140 else if (reg_base == reg_src + 2)
2142 if (reg_unused_after (insn, base))
2143 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2144 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2145 AS2 (st,%0+,%A1) CR_TAB
2146 AS2 (st,%0+,%B1) CR_TAB
2147 AS2 (st,%0+,__zero_reg__) CR_TAB
2148 AS2 (st,%0,__tmp_reg__) CR_TAB
2149 AS1 (clr,__zero_reg__));
2151 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2152 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2153 AS2 (st,%0+,%A1) CR_TAB
2154 AS2 (st,%0+,%B1) CR_TAB
2155 AS2 (st,%0+,__zero_reg__) CR_TAB
2156 AS2 (st,%0,__tmp_reg__) CR_TAB
2157 AS1 (clr,__zero_reg__) CR_TAB
2160 return *l=5, (AS2 (st,%0+,%A1) CR_TAB
2161 AS2 (st,%0+,%B1) CR_TAB
2162 AS2 (st,%0+,%C1) CR_TAB
2163 AS2 (st,%0,%D1) CR_TAB
2167 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2168 AS2 (std,%0+1,%B1) CR_TAB
2169 AS2 (std,%0+2,%C1) CR_TAB
2170 AS2 (std,%0+3,%D1));
2172 else if (GET_CODE (base) == PLUS) /* (R + i) */
2174 int disp = INTVAL (XEXP (base, 1));
2175 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2177 if (REGNO (XEXP (base, 0)) != REG_Y)
2178 fatal_insn ("Incorrect insn:",insn);
2179 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2181 op[4] = GEN_INT (disp - 60);
2182 return *l=6,(AS2 (adiw, r28, %4) CR_TAB
2183 AS2 (std, Y+60,%A1) CR_TAB
2184 AS2 (std, Y+61,%B1) CR_TAB
2185 AS2 (std, Y+62,%C1) CR_TAB
2186 AS2 (std, Y+63,%D1) CR_TAB
2187 AS2 (sbiw, r28, %4));
2191 op[4] = XEXP (base, 1);
2192 return *l=8,(AS2 (subi, r28, lo8(-%4)) CR_TAB
2193 AS2 (sbci, r29, hi8(-%4)) CR_TAB
2194 AS2 (st, Y,%A1) CR_TAB
2195 AS2 (std, Y+1,%B1) CR_TAB
2196 AS2 (std, Y+2,%C1) CR_TAB
2197 AS2 (std, Y+3,%D1) CR_TAB
2198 AS2 (subi, r28, lo8(%4)) CR_TAB
2199 AS2 (sbci, r29, hi8(%4)));
2202 return *l=4, (AS2 (std,%A0,%A1) CR_TAB
2203 AS2 (std,%B0,%B1) CR_TAB
2204 AS2 (std,%C0,%C1) CR_TAB
2207 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2208 return *l=4, (AS2 (st,%0,%D1) CR_TAB
2209 AS2 (st,%0,%C1) CR_TAB
2210 AS2 (st,%0,%B1) CR_TAB
2212 else if (GET_CODE (base) == POST_INC) /* (R++) */
2213 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2214 AS2 (st,%0,%B1) CR_TAB
2215 AS2 (st,%0,%C1) CR_TAB
2217 fatal_insn ("Unknown move insn:",insn);
2222 output_movsisf(insn, operands, l)
2228 rtx dest = operands[0];
2229 rtx src = operands[1];
2235 if (register_operand (dest, VOIDmode))
2237 if (register_operand (src, VOIDmode)) /* mov r,r */
2239 if (true_regnum (dest) > true_regnum (src))
2244 return (AS2 (movw,%C0,%C1) CR_TAB
2245 AS2 (movw,%A0,%A1));
2248 return (AS2 (mov,%D0,%D1) CR_TAB
2249 AS2 (mov,%C0,%C1) CR_TAB
2250 AS2 (mov,%B0,%B1) CR_TAB
2258 return (AS2 (movw,%A0,%A1) CR_TAB
2259 AS2 (movw,%C0,%C1));
2262 return (AS2 (mov,%A0,%A1) CR_TAB
2263 AS2 (mov,%B0,%B1) CR_TAB
2264 AS2 (mov,%C0,%C1) CR_TAB
2268 else if (CONSTANT_P (src))
2270 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2272 if (byte_immediate_operand (src, SImode)
2273 && reg_was_0 (insn, dest))
2276 return (AS2 (ldi,%A0,lo8(%1) ; reg_was_0));
2280 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
2281 AS2 (ldi,%B0,hi8(%1)) CR_TAB
2282 AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2283 AS2 (ldi,%D0,hhi8(%1)));
2286 if (GET_CODE (src) == CONST_INT)
2288 const char *clr_op0 =
2289 AVR_ENHANCED ? (AS1 (clr,%A0) CR_TAB
2290 AS1 (clr,%B0) CR_TAB
2292 : (AS1 (clr,%A0) CR_TAB
2293 AS1 (clr,%B0) CR_TAB
2294 AS1 (clr,%C0) CR_TAB
2297 if (src == const0_rtx) /* mov r,L */
2299 *l = AVR_ENHANCED ? 3 : 4;
2302 else if (src == const1_rtx)
2304 if (reg_was_0 (insn, dest))
2307 return AS1 (inc,%A0 ; reg_was_0);
2310 output_asm_insn (clr_op0, operands);
2311 *l = AVR_ENHANCED ? 4 : 5;
2312 return AS1 (inc,%A0);
2314 else if (src == constm1_rtx)
2316 /* Immediate constants -1 to any register */
2317 if (reg_was_0 (insn, dest))
2322 return (AS1 (dec,%A0) CR_TAB
2323 AS1 (dec,%B0) CR_TAB
2324 AS2 (movw,%C0,%A0));
2327 return (AS1 (dec,%D0 ; reg_was_0) CR_TAB
2328 AS1 (dec,%C0) CR_TAB
2329 AS1 (dec,%B0) CR_TAB
2335 return (AS1 (clr,%A0) CR_TAB
2336 AS1 (dec,%A0) CR_TAB
2337 AS2 (mov,%B0,%A0) CR_TAB
2338 AS2 (movw,%C0,%A0));
2341 return (AS1 (clr,%A0) CR_TAB
2342 AS1 (dec,%A0) CR_TAB
2343 AS2 (mov,%B0,%A0) CR_TAB
2344 AS2 (mov,%C0,%A0) CR_TAB
2349 int bit_nr = exact_log2 (INTVAL (src));
2353 if (reg_was_0 (insn, dest))
2357 output_asm_insn ("set ; reg_was_0", operands);
2361 *l = AVR_ENHANCED ? 5 : 6;
2364 output_asm_insn (clr_op0, operands);
2365 output_asm_insn ("set", operands);
2369 avr_output_bld (operands, bit_nr);
2376 /* Last resort, better than loading from memory. */
2378 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2379 AS2 (ldi,r31,lo8(%1)) CR_TAB
2380 AS2 (mov,%A0,r31) CR_TAB
2381 AS2 (ldi,r31,hi8(%1)) CR_TAB
2382 AS2 (mov,%B0,r31) CR_TAB
2383 AS2 (ldi,r31,hlo8(%1)) CR_TAB
2384 AS2 (mov,%C0,r31) CR_TAB
2385 AS2 (ldi,r31,hhi8(%1)) CR_TAB
2386 AS2 (mov,%D0,r31) CR_TAB
2387 AS2 (mov,r31,__tmp_reg__));
2389 else if (GET_CODE (src) == MEM)
2390 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2392 else if (GET_CODE (dest) == MEM)
2394 const char *template;
2396 if (src == const0_rtx)
2397 operands[1] = zero_reg_rtx;
2399 template = out_movsi_mr_r (insn, operands, real_l);
2402 output_asm_insn (template, operands);
2407 fatal_insn ("Invalid insn:", insn);
2412 out_movqi_mr_r (insn, op, l)
2415 int *l; /* instruction length */
2419 rtx x = XEXP (dest, 0);
2425 if (CONSTANT_ADDRESS_P (x))
2427 if (io_address_p (x, 1))
2430 return AS2 (out,%0-0x20,%1);
2433 return AS2 (sts,%0,%1);
2435 /* memory access by reg+disp */
2436 else if (GET_CODE (x) == PLUS
2437 && REG_P (XEXP (x,0))
2438 && GET_CODE (XEXP (x,1)) == CONST_INT)
2440 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2442 int disp = INTVAL (XEXP (x,1));
2443 if (REGNO (XEXP (x,0)) != REG_Y)
2444 fatal_insn ("Incorrect insn:",insn);
2445 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2448 op[4] = XEXP (x, 1);
2449 return (AS2 (adiw, r28, %4-63) CR_TAB
2450 AS2 (std, Y+63,%1) CR_TAB
2451 AS2 (sbiw, r28, %4-63));
2457 return (AS2 (subi, r28, lo8(-%4)) CR_TAB
2458 AS2 (sbci, r29, hi8(-%4)) CR_TAB
2459 AS2 (st, Y,%1) CR_TAB
2460 AS2 (subi, r28, lo8(%4)) CR_TAB
2461 AS2 (sbci, r29, hi8(%4)));
2464 else if (REGNO (XEXP (x,0)) == REG_X)
2467 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2469 if (reg_unused_after (insn, XEXP (x,0)))
2472 return (AS2 (mov,__tmp_reg__,%1) CR_TAB
2473 AS2 (adiw,r26,%4) CR_TAB
2474 AS2 (st,X,__tmp_reg__));
2477 return (AS2 (mov,__tmp_reg__,%1) CR_TAB
2478 AS2 (adiw,r26,%4) CR_TAB
2479 AS2 (st,X,__tmp_reg__) CR_TAB
2484 if (reg_unused_after (insn, XEXP (x,0)))
2487 return (AS2 (adiw,r26,%4) CR_TAB
2491 return (AS2 (adiw,r26,%4) CR_TAB
2492 AS2 (st,X,%1) CR_TAB
2497 return AS2 (std,%0,%1);
2500 return AS2 (st,%0,%1);
2504 out_movhi_mr_r (insn, op, l)
2511 rtx base = XEXP (dest, 0);
2512 int reg_base = true_regnum (base);
2513 int reg_src = true_regnum (src);
2517 if (CONSTANT_ADDRESS_P (base))
2519 if (io_address_p (base, 2))
2522 return (AS2 (out,%B0-0x20,%B1) CR_TAB
2523 AS2 (out,%A0-0x20,%A1));
2525 return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2530 if (reg_base == REG_X)
2532 if (reg_src == REG_X)
2534 if (reg_unused_after (insn, src))
2535 return *l=3, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2536 AS2 (st ,X+,r26) CR_TAB
2537 AS2 (st ,X,__tmp_reg__));
2539 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2540 AS2 (st ,X+,r26) CR_TAB
2541 AS2 (st ,X,__tmp_reg__) CR_TAB
2546 if (reg_unused_after (insn, base))
2547 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2550 return *l=3, (AS2 (st ,X+,%A1) CR_TAB
2551 AS2 (st ,X,%B1) CR_TAB
2556 return *l=2, (AS2 (st ,%0,%A1) CR_TAB
2557 AS2 (std,%0+1,%B1));
2559 else if (GET_CODE (base) == PLUS)
2561 int disp = INTVAL (XEXP (base, 1));
2562 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2564 if (REGNO (XEXP (base, 0)) != REG_Y)
2565 fatal_insn ("Incorrect insn:",insn);
2566 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2568 op[4] = GEN_INT (disp - 62);
2569 return *l=4,(AS2 (adiw, r28, %4) CR_TAB
2570 AS2 (std, Y+62,%A1) CR_TAB
2571 AS2 (std, Y+63,%B1) CR_TAB
2572 AS2 (sbiw, r28, %4));
2576 op[4] = XEXP (base, 1);
2577 return *l=6,(AS2 (subi, r28, lo8(-%4)) CR_TAB
2578 AS2 (sbci, r29, hi8(-%4)) CR_TAB
2579 AS2 (st, Y,%A1) CR_TAB
2580 AS2 (std, Y+1,%B1) CR_TAB
2581 AS2 (subi, r28, lo8(%4)) CR_TAB
2582 AS2 (sbci, r29, hi8(%4)));
2585 return *l=2, (AS2 (std,%A0,%A1) CR_TAB
2588 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2589 return *l=2, (AS2 (st,%0,%B1) CR_TAB
2591 else if (GET_CODE (base) == POST_INC) /* (R++) */
2592 return *l=2, (AS2 (st,%0,%A1) CR_TAB
2594 fatal_insn ("Unknown move insn:",insn);
2598 /* Return 1 if frame pointer for current function required */
2601 frame_pointer_required_p ()
2603 return (current_function_calls_alloca
2604 || current_function_args_info.nregs == 0
2605 || current_function_varargs
2606 || get_frame_size () > 0);
2609 /* Return 1 if the next insn is a JUMP_INSN with condition (GT,LE,GTU,LTU) */
2612 compare_diff_p (insn)
2615 rtx next = next_real_insn (insn);
2616 RTX_CODE cond = UNKNOWN;
2617 if (GET_CODE (next) == JUMP_INSN)
2619 rtx pat = PATTERN (next);
2620 rtx src = SET_SRC (pat);
2621 rtx t = XEXP (src,0);
2622 cond = GET_CODE (t);
2624 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2627 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition */
2633 rtx next = next_real_insn (insn);
2634 RTX_CODE cond = UNKNOWN;
2635 if (GET_CODE (next) == JUMP_INSN)
2637 rtx pat = PATTERN (next);
2638 rtx src = SET_SRC (pat);
2639 rtx t = XEXP (src,0);
2640 cond = GET_CODE (t);
2642 return (cond == EQ || cond == NE);
2646 /* Output test instruction for HImode */
2653 if (!compare_eq_p (insn))
2656 return AS1 (tst,%B0);
2658 if (reg_unused_after (insn, SET_SRC (PATTERN (insn))))
2660 /* faster than sbiw if we can clobber the operand */
2662 return AS2 (or,%A0,%B0);
2664 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2667 return AS2 (sbiw,%0,0);
2670 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2671 AS2 (cpc,%B0,__zero_reg__));
2675 /* Output test instruction for SImode */
2682 if (!compare_eq_p (insn))
2685 return AS1 (tst,%D0);
2687 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2690 return (AS2 (sbiw,%A0,0) CR_TAB
2691 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2692 AS2 (cpc,%D0,__zero_reg__));
2695 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2696 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2697 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2698 AS2 (cpc,%D0,__zero_reg__));
2702 /* Generate asm equivalent for various shifts.
2703 Shift count is a CONST_INT, MEM or REG.
2704 This only handles cases that are not already
2705 carefully hand-optimized in ?sh??i3_out. */
2708 out_shift_with_cnt (template, insn, operands, len, t_len)
2709 const char *template;
2713 int t_len; /* Length of template. */
2717 int second_label = 1;
2718 int saved_in_tmp = 0;
2719 int use_zero_reg = 0;
2721 op[0] = operands[0];
2722 op[1] = operands[1];
2723 op[2] = operands[2];
2724 op[3] = operands[3];
2730 if (GET_CODE (operands[2]) == CONST_INT)
2732 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2733 int count = INTVAL (operands[2]);
2734 int max_len = 10; /* If larger than this, always use a loop. */
2736 if (count < 8 && !scratch)
2740 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
2742 if (t_len * count <= max_len)
2744 /* Output shifts inline with no loop - faster. */
2746 *len = t_len * count;
2750 output_asm_insn (template, op);
2759 strcat (str, AS2 (ldi,%3,%2));
2761 else if (use_zero_reg)
2763 /* Hack to save one word: use __zero_reg__ as loop counter.
2764 Set one bit, then shift in a loop until it is 0 again. */
2766 op[3] = zero_reg_rtx;
2770 strcat (str, ("set" CR_TAB
2771 AS2 (bld,%3,%2-1)));
2775 /* No scratch register available, use one from LD_REGS (saved in
2776 __tmp_reg__) that doesn't overlap with registers to shift. */
2778 op[3] = gen_rtx (REG, QImode,
2779 ((true_regnum (operands[0]) - 1) & 15) + 16);
2780 op[4] = tmp_reg_rtx;
2784 *len = 3; /* Includes "mov %3,%4" after the loop. */
2786 strcat (str, (AS2 (mov,%4,%3) CR_TAB
2792 else if (GET_CODE (operands[2]) == MEM)
2796 op[3] = op_mov[0] = tmp_reg_rtx;
2800 out_movqi_r_mr (insn, op_mov, len);
2802 output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2804 else if (register_operand (operands[2], QImode))
2806 if (reg_unused_after (insn, operands[2]))
2810 op[3] = tmp_reg_rtx;
2812 strcat (str, (AS2 (mov,%3,%2) CR_TAB));
2816 fatal_insn ("Bad shift insn:", insn);
2823 strcat (str, AS1 (rjmp,2f));
2827 *len += t_len + 2; /* template + dec + brXX */
2830 strcat (str, "\n1:\t");
2831 strcat (str, template);
2832 strcat (str, second_label ? "\n2:\t" : "\n\t");
2833 strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
2834 strcat (str, CR_TAB);
2835 strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
2837 strcat (str, (CR_TAB AS2 (mov,%3,%4)));
2838 output_asm_insn (str, op);
2843 /* 8bit shift left ((char)x << i) */
2846 ashlqi3_out (insn, operands, len)
2849 int *len; /* insn length (may be NULL) */
2851 if (GET_CODE (operands[2]) == CONST_INT)
2858 switch (INTVAL (operands[2]))
2862 return AS1 (clr,%0);
2866 return AS1 (lsl,%0);
2870 return (AS1 (lsl,%0) CR_TAB
2875 return (AS1 (lsl,%0) CR_TAB
2880 if (test_hard_reg_class (LD_REGS, operands[0]))
2883 return (AS1 (swap,%0) CR_TAB
2884 AS2 (andi,%0,0xf0));
2887 return (AS1 (lsl,%0) CR_TAB
2893 if (test_hard_reg_class (LD_REGS, operands[0]))
2896 return (AS1 (swap,%0) CR_TAB
2898 AS2 (andi,%0,0xe0));
2901 return (AS1 (lsl,%0) CR_TAB
2908 if (test_hard_reg_class (LD_REGS, operands[0]))
2911 return (AS1 (swap,%0) CR_TAB
2914 AS2 (andi,%0,0xc0));
2917 return (AS1 (lsl,%0) CR_TAB
2926 return (AS1 (ror,%0) CR_TAB
2931 else if (CONSTANT_P (operands[2]))
2932 fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
2934 out_shift_with_cnt (AS1 (lsl,%0),
2935 insn, operands, len, 1);
2940 /* 16bit shift left ((short)x << i) */
2943 ashlhi3_out (insn, operands, len)
2948 if (GET_CODE (operands[2]) == CONST_INT)
2950 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2951 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
2958 switch (INTVAL (operands[2]))
2961 if (optimize_size && scratch)
2966 return (AS1 (swap,%A0) CR_TAB
2967 AS1 (swap,%B0) CR_TAB
2968 AS2 (andi,%B0,0xf0) CR_TAB
2969 AS2 (eor,%B0,%A0) CR_TAB
2970 AS2 (andi,%A0,0xf0) CR_TAB
2976 return (AS1 (swap,%A0) CR_TAB
2977 AS1 (swap,%B0) CR_TAB
2978 AS2 (ldi,%3,0xf0) CR_TAB
2979 AS2 (and,%B0,%3) CR_TAB
2980 AS2 (eor,%B0,%A0) CR_TAB
2981 AS2 (and,%A0,%3) CR_TAB
2984 break; /* optimize_size ? 6 : 8 */
2988 break; /* scratch ? 5 : 6 */
2992 return (AS1 (lsl,%A0) CR_TAB
2993 AS1 (rol,%B0) CR_TAB
2994 AS1 (swap,%A0) CR_TAB
2995 AS1 (swap,%B0) CR_TAB
2996 AS2 (andi,%B0,0xf0) CR_TAB
2997 AS2 (eor,%B0,%A0) CR_TAB
2998 AS2 (andi,%A0,0xf0) CR_TAB
3004 return (AS1 (lsl,%A0) CR_TAB
3005 AS1 (rol,%B0) CR_TAB
3006 AS1 (swap,%A0) CR_TAB
3007 AS1 (swap,%B0) CR_TAB
3008 AS2 (ldi,%3,0xf0) CR_TAB
3009 AS2 (and,%B0,%3) CR_TAB
3010 AS2 (eor,%B0,%A0) CR_TAB
3011 AS2 (and,%A0,%3) CR_TAB
3018 break; /* scratch ? 5 : 6 */
3020 return (AS1 (clr,__tmp_reg__) CR_TAB
3021 AS1 (lsr,%B0) CR_TAB
3022 AS1 (ror,%A0) CR_TAB
3023 AS1 (ror,__tmp_reg__) CR_TAB
3024 AS1 (lsr,%B0) CR_TAB
3025 AS1 (ror,%A0) CR_TAB
3026 AS1 (ror,__tmp_reg__) CR_TAB
3027 AS2 (mov,%B0,%A0) CR_TAB
3028 AS2 (mov,%A0,__tmp_reg__));
3032 return (AS1 (lsr,%B0) CR_TAB
3033 AS2 (mov,%B0,%A0) CR_TAB
3034 AS1 (clr,%A0) CR_TAB
3035 AS1 (ror,%B0) CR_TAB
3039 if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
3040 return *len = 1, AS1 (clr,%A0);
3042 return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3047 return (AS2 (mov,%B0,%A0) CR_TAB
3048 AS1 (clr,%A0) CR_TAB
3053 return (AS2 (mov,%B0,%A0) CR_TAB
3054 AS1 (clr,%A0) CR_TAB
3055 AS1 (lsl,%B0) CR_TAB
3060 return (AS2 (mov,%B0,%A0) CR_TAB
3061 AS1 (clr,%A0) CR_TAB
3062 AS1 (lsl,%B0) CR_TAB
3063 AS1 (lsl,%B0) CR_TAB
3070 return (AS2 (mov,%B0,%A0) CR_TAB
3071 AS1 (clr,%A0) CR_TAB
3072 AS1 (swap,%B0) CR_TAB
3073 AS2 (andi,%B0,0xf0));
3078 return (AS2 (mov,%B0,%A0) CR_TAB
3079 AS1 (clr,%A0) CR_TAB
3080 AS1 (swap,%B0) CR_TAB
3081 AS2 (ldi,%3,0xf0) CR_TAB
3085 return (AS2 (mov,%B0,%A0) CR_TAB
3086 AS1 (clr,%A0) CR_TAB
3087 AS1 (lsl,%B0) CR_TAB
3088 AS1 (lsl,%B0) CR_TAB
3089 AS1 (lsl,%B0) CR_TAB
3096 return (AS2 (mov,%B0,%A0) CR_TAB
3097 AS1 (clr,%A0) CR_TAB
3098 AS1 (swap,%B0) CR_TAB
3099 AS1 (lsl,%B0) CR_TAB
3100 AS2 (andi,%B0,0xe0));
3102 if (AVR_ENHANCED && scratch)
3105 return (AS2 (ldi,%3,0x20) CR_TAB
3106 AS2 (mul,%A0,%3) CR_TAB
3107 AS2 (mov,%B0,r0) CR_TAB
3108 AS1 (clr,%A0) CR_TAB
3109 AS1 (clr,__zero_reg__));
3111 if (optimize_size && scratch)
3116 return (AS2 (mov,%B0,%A0) CR_TAB
3117 AS1 (clr,%A0) CR_TAB
3118 AS1 (swap,%B0) CR_TAB
3119 AS1 (lsl,%B0) CR_TAB
3120 AS2 (ldi,%3,0xe0) CR_TAB
3126 return ("set" CR_TAB
3127 AS2 (bld,r1,5) CR_TAB
3128 AS2 (mul,%A0,r1) CR_TAB
3129 AS2 (mov,%B0,r0) CR_TAB
3130 AS1 (clr,%A0) CR_TAB
3131 AS1 (clr,__zero_reg__));
3134 return (AS2 (mov,%B0,%A0) CR_TAB
3135 AS1 (clr,%A0) CR_TAB
3136 AS1 (lsl,%B0) CR_TAB
3137 AS1 (lsl,%B0) CR_TAB
3138 AS1 (lsl,%B0) CR_TAB
3139 AS1 (lsl,%B0) CR_TAB
3143 if (AVR_ENHANCED && ldi_ok)
3146 return (AS2 (ldi,%B0,0x40) CR_TAB
3147 AS2 (mul,%A0,%B0) CR_TAB
3148 AS2 (mov,%B0,r0) CR_TAB
3149 AS1 (clr,%A0) CR_TAB
3150 AS1 (clr,__zero_reg__));
3152 if (AVR_ENHANCED && scratch)
3155 return (AS2 (ldi,%3,0x40) CR_TAB
3156 AS2 (mul,%A0,%3) CR_TAB
3157 AS2 (mov,%B0,r0) CR_TAB
3158 AS1 (clr,%A0) CR_TAB
3159 AS1 (clr,__zero_reg__));
3161 if (optimize_size && ldi_ok)
3164 return (AS2 (mov,%B0,%A0) CR_TAB
3165 AS2 (ldi,%A0,6) "\n1:\t"
3166 AS1 (lsl,%B0) CR_TAB
3167 AS1 (dec,%A0) CR_TAB
3170 if (optimize_size && scratch)
3173 return (AS1 (clr,%B0) CR_TAB
3174 AS1 (lsr,%A0) CR_TAB
3175 AS1 (ror,%B0) CR_TAB
3176 AS1 (lsr,%A0) CR_TAB
3177 AS1 (ror,%B0) CR_TAB
3182 return (AS1 (clr,%B0) CR_TAB
3183 AS1 (lsr,%A0) CR_TAB
3184 AS1 (ror,%B0) CR_TAB
3189 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3191 insn, operands, len, 2);
3196 /* 32bit shift left ((long)x << i) */
3199 ashlsi3_out (insn, operands, len)
3204 if (GET_CODE (operands[2]) == CONST_INT)
3212 switch (INTVAL (operands[2]))
3216 int reg0 = true_regnum (operands[0]);
3217 int reg1 = true_regnum (operands[1]);
3220 return (AS2 (mov,%D0,%C1) CR_TAB
3221 AS2 (mov,%C0,%B1) CR_TAB
3222 AS2 (mov,%B0,%A1) CR_TAB
3224 else if (reg0 + 1 == reg1)
3227 return AS1 (clr,%A0);
3230 return (AS1 (clr,%A0) CR_TAB
3231 AS2 (mov,%B0,%A1) CR_TAB
3232 AS2 (mov,%C0,%B1) CR_TAB
3238 int reg0 = true_regnum (operands[0]);
3239 int reg1 = true_regnum (operands[1]);
3241 if (AVR_ENHANCED && (reg0 + 2 != reg1))
3244 return (AS2 (movw,%C0,%A1) CR_TAB
3245 AS1 (clr,%B0) CR_TAB
3248 if (reg0 + 1 >= reg1)
3249 return (AS2 (mov,%D0,%B1) CR_TAB
3250 AS2 (mov,%C0,%A1) CR_TAB
3251 AS1 (clr,%B0) CR_TAB
3253 if (reg0 + 2 == reg1)
3256 return (AS1 (clr,%B0) CR_TAB
3260 return (AS2 (mov,%C0,%A1) CR_TAB
3261 AS2 (mov,%D0,%B1) CR_TAB
3262 AS1 (clr,%B0) CR_TAB
3268 if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
3269 return (AS2 (mov,%D0,%A1) CR_TAB
3270 AS1 (clr,%C0) CR_TAB
3271 AS1 (clr,%B0) CR_TAB
3276 return (AS1 (clr,%C0) CR_TAB
3277 AS1 (clr,%B0) CR_TAB
3283 return (AS1 (clr,%D0) CR_TAB
3284 AS1 (lsr,%A0) CR_TAB
3285 AS1 (ror,%D0) CR_TAB
3286 AS1 (clr,%C0) CR_TAB
3287 AS1 (clr,%B0) CR_TAB
3292 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3293 AS1 (rol,%B0) CR_TAB
3294 AS1 (rol,%C0) CR_TAB
3296 insn, operands, len, 4);
3300 /* 8bit arithmetic shift right ((signed char)x >> i) */
3303 ashrqi3_out (insn, operands, len)
3306 int *len; /* insn length */
3308 if (GET_CODE (operands[2]) == CONST_INT)
3315 switch (INTVAL (operands[2]))
3319 return AS1 (asr,%0);
3323 return (AS1 (asr,%0) CR_TAB
3328 return (AS1 (asr,%0) CR_TAB
3334 return (AS1 (asr,%0) CR_TAB
3341 return (AS1 (asr,%0) CR_TAB
3349 return (AS2 (bst,%0,6) CR_TAB
3351 AS2 (sbc,%0,%0) CR_TAB
3357 return (AS1 (lsl,%0) CR_TAB
3361 else if (CONSTANT_P (operands[2]))
3362 fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
3364 out_shift_with_cnt (AS1 (asr,%0),
3365 insn, operands, len, 1);
3370 /* 16bit arithmetic shift right ((signed short)x >> i) */
3373 ashrhi3_out (insn, operands, len)
3378 if (GET_CODE (operands[2]) == CONST_INT)
3380 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3381 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3388 switch (INTVAL (operands[2]))
3392 /* XXX try to optimize this too? */
3397 break; /* scratch ? 5 : 6 */
3399 return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3400 AS2 (mov,%A0,%B0) CR_TAB
3401 AS1 (lsl,__tmp_reg__) CR_TAB
3402 AS1 (rol,%A0) CR_TAB
3403 AS2 (sbc,%B0,%B0) CR_TAB
3404 AS1 (lsl,__tmp_reg__) CR_TAB
3405 AS1 (rol,%A0) CR_TAB
3410 return (AS1 (lsl,%A0) CR_TAB
3411 AS2 (mov,%A0,%B0) CR_TAB
3412 AS1 (rol,%A0) CR_TAB
3417 int reg0 = true_regnum (operands[0]);
3418 int reg1 = true_regnum (operands[1]);
3421 return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3422 AS1 (lsl,%B0) CR_TAB
3424 else if (reg0 == reg1 + 1)
3425 return *len = 3, (AS1 (clr,%B0) CR_TAB
3426 AS2 (sbrc,%A0,7) CR_TAB
3429 return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3430 AS1 (clr,%B0) CR_TAB
3431 AS2 (sbrc,%A0,7) CR_TAB
3437 return (AS2 (mov,%A0,%B0) CR_TAB
3438 AS1 (lsl,%B0) CR_TAB
3439 AS2 (sbc,%B0,%B0) CR_TAB
3444 return (AS2 (mov,%A0,%B0) CR_TAB
3445 AS1 (lsl,%B0) CR_TAB
3446 AS2 (sbc,%B0,%B0) CR_TAB
3447 AS1 (asr,%A0) CR_TAB
3451 if (AVR_ENHANCED && ldi_ok)
3454 return (AS2 (ldi,%A0,0x20) CR_TAB
3455 AS2 (muls,%B0,%A0) CR_TAB
3456 AS2 (mov,%A0,r1) CR_TAB
3457 AS2 (sbc,%B0,%B0) CR_TAB
3458 AS1 (clr,__zero_reg__));
3460 if (optimize_size && scratch)
3463 return (AS2 (mov,%A0,%B0) CR_TAB
3464 AS1 (lsl,%B0) CR_TAB
3465 AS2 (sbc,%B0,%B0) CR_TAB
3466 AS1 (asr,%A0) CR_TAB
3467 AS1 (asr,%A0) CR_TAB
3471 if (AVR_ENHANCED && ldi_ok)
3474 return (AS2 (ldi,%A0,0x10) CR_TAB
3475 AS2 (muls,%B0,%A0) CR_TAB
3476 AS2 (mov,%A0,r1) CR_TAB
3477 AS2 (sbc,%B0,%B0) CR_TAB
3478 AS1 (clr,__zero_reg__));
3480 if (optimize_size && scratch)
3483 return (AS2 (mov,%A0,%B0) CR_TAB
3484 AS1 (lsl,%B0) CR_TAB
3485 AS2 (sbc,%B0,%B0) CR_TAB
3486 AS1 (asr,%A0) CR_TAB
3487 AS1 (asr,%A0) CR_TAB
3488 AS1 (asr,%A0) CR_TAB
3492 if (AVR_ENHANCED && ldi_ok)
3495 return (AS2 (ldi,%A0,0x08) CR_TAB
3496 AS2 (muls,%B0,%A0) CR_TAB
3497 AS2 (mov,%A0,r1) CR_TAB
3498 AS2 (sbc,%B0,%B0) CR_TAB
3499 AS1 (clr,__zero_reg__));
3502 break; /* scratch ? 5 : 7 */
3504 return (AS2 (mov,%A0,%B0) CR_TAB
3505 AS1 (lsl,%B0) CR_TAB
3506 AS2 (sbc,%B0,%B0) CR_TAB
3507 AS1 (asr,%A0) CR_TAB
3508 AS1 (asr,%A0) CR_TAB
3509 AS1 (asr,%A0) CR_TAB
3510 AS1 (asr,%A0) CR_TAB
3515 return (AS1 (lsl,%B0) CR_TAB
3516 AS2 (sbc,%A0,%A0) CR_TAB
3517 AS1 (lsl,%B0) CR_TAB
3518 AS2 (mov,%B0,%A0) CR_TAB
3522 return *len = 3, (AS1 (lsl,%B0) CR_TAB
3523 AS2 (sbc,%A0,%A0) CR_TAB
3528 out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3530 insn, operands, len, 2);
3535 /* 32bit arithmetic shift right ((signed long)x >> i) */
3538 ashrsi3_out (insn, operands, len)
3543 if (GET_CODE (operands[2]) == CONST_INT)
3551 switch (INTVAL (operands[2]))
3555 int reg0 = true_regnum (operands[0]);
3556 int reg1 = true_regnum (operands[1]);
3559 return (AS2 (mov,%A0,%B1) CR_TAB
3560 AS2 (mov,%B0,%C1) CR_TAB
3561 AS2 (mov,%C0,%D1) CR_TAB
3562 AS1 (clr,%D0) CR_TAB
3563 AS2 (sbrc,%C0,7) CR_TAB
3565 else if (reg0 == reg1 + 1)
3568 return (AS1 (clr,%D0) CR_TAB
3569 AS2 (sbrc,%C0,7) CR_TAB
3573 return (AS1 (clr,%D0) CR_TAB
3574 AS2 (sbrc,%D1,7) CR_TAB
3575 AS1 (dec,%D0) CR_TAB
3576 AS2 (mov,%C0,%D1) CR_TAB
3577 AS2 (mov,%B0,%C1) CR_TAB
3583 int reg0 = true_regnum (operands[0]);
3584 int reg1 = true_regnum (operands[1]);
3586 if (AVR_ENHANCED && (reg0 != reg1 + 2))
3589 return (AS2 (movw,%A0,%C1) CR_TAB
3590 AS1 (clr,%D0) CR_TAB
3591 AS2 (sbrc,%B0,7) CR_TAB
3592 AS1 (com,%D0) CR_TAB
3595 if (reg0 <= reg1 + 1)
3596 return (AS2 (mov,%A0,%C1) CR_TAB
3597 AS2 (mov,%B0,%D1) CR_TAB
3598 AS1 (clr,%D0) CR_TAB
3599 AS2 (sbrc,%B0,7) CR_TAB
3600 AS1 (com,%D0) CR_TAB
3602 else if (reg0 == reg1 + 2)
3603 return *len = 4, (AS1 (clr,%D0) CR_TAB
3604 AS2 (sbrc,%B0,7) CR_TAB
3605 AS1 (com,%D0) CR_TAB
3608 return (AS2 (mov,%B0,%D1) CR_TAB
3609 AS2 (mov,%A0,%C1) CR_TAB
3610 AS1 (clr,%D0) CR_TAB
3611 AS2 (sbrc,%B0,7) CR_TAB
3612 AS1 (com,%D0) CR_TAB
3617 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3618 return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3619 AS1 (clr,%D0) CR_TAB
3620 AS2 (sbrc,%A0,7) CR_TAB
3621 AS1 (com,%D0) CR_TAB
3622 AS2 (mov,%B0,%D0) CR_TAB
3625 return *len = 5, (AS1 (clr,%D0) CR_TAB
3626 AS2 (sbrc,%A0,7) CR_TAB
3627 AS1 (com,%D0) CR_TAB
3628 AS2 (mov,%B0,%D0) CR_TAB
3633 return *len = 4, (AS1 (lsl,%D0) CR_TAB
3634 AS2 (sbc,%A0,%A0) CR_TAB
3635 AS2 (mov,%B0,%A0) CR_TAB
3636 AS2 (movw,%C0,%A0));
3638 return *len = 5, (AS1 (lsl,%D0) CR_TAB
3639 AS2 (sbc,%A0,%A0) CR_TAB
3640 AS2 (mov,%B0,%A0) CR_TAB
3641 AS2 (mov,%C0,%A0) CR_TAB
3646 out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
3647 AS1 (ror,%C0) CR_TAB
3648 AS1 (ror,%B0) CR_TAB
3650 insn, operands, len, 4);
3654 /* 8bit logic shift right ((unsigned char)x >> i) */
3657 lshrqi3_out (insn, operands, len)
3662 if (GET_CODE (operands[2]) == CONST_INT)
3669 switch (INTVAL (operands[2]))
3673 return AS1 (clr,%0);
3677 return AS1 (lsr,%0);
3681 return (AS1 (lsr,%0) CR_TAB
3685 return (AS1 (lsr,%0) CR_TAB
3690 if (test_hard_reg_class (LD_REGS, operands[0]))
3693 return (AS1 (swap,%0) CR_TAB
3694 AS2 (andi,%0,0x0f));
3697 return (AS1 (lsr,%0) CR_TAB
3703 if (test_hard_reg_class (LD_REGS, operands[0]))
3706 return (AS1 (swap,%0) CR_TAB
3711 return (AS1 (lsr,%0) CR_TAB
3718 if (test_hard_reg_class (LD_REGS, operands[0]))
3721 return (AS1 (swap,%0) CR_TAB
3727 return (AS1 (lsr,%0) CR_TAB
3736 return (AS1 (rol,%0) CR_TAB
3741 else if (CONSTANT_P (operands[2]))
3742 fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
3744 out_shift_with_cnt (AS1 (lsr,%0),
3745 insn, operands, len, 1);
3749 /* 16bit logic shift right ((unsigned short)x >> i) */
3752 lshrhi3_out (insn, operands, len)
3757 if (GET_CODE (operands[2]) == CONST_INT)
3759 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3760 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3767 switch (INTVAL (operands[2]))
3770 if (optimize_size && scratch)
3775 return (AS1 (swap,%B0) CR_TAB
3776 AS1 (swap,%A0) CR_TAB
3777 AS2 (andi,%A0,0x0f) CR_TAB
3778 AS2 (eor,%A0,%B0) CR_TAB
3779 AS2 (andi,%B0,0x0f) CR_TAB
3785 return (AS1 (swap,%B0) CR_TAB
3786 AS1 (swap,%A0) CR_TAB
3787 AS2 (ldi,%3,0x0f) CR_TAB
3788 AS2 (and,%A0,%3) CR_TAB
3789 AS2 (eor,%A0,%B0) CR_TAB
3790 AS2 (and,%B0,%3) CR_TAB
3793 break; /* optimize_size ? 6 : 8 */
3797 break; /* scratch ? 5 : 6 */
3801 return (AS1 (lsr,%B0) CR_TAB
3802 AS1 (ror,%A0) CR_TAB
3803 AS1 (swap,%B0) CR_TAB
3804 AS1 (swap,%A0) CR_TAB
3805 AS2 (andi,%A0,0x0f) CR_TAB
3806 AS2 (eor,%A0,%B0) CR_TAB
3807 AS2 (andi,%B0,0x0f) CR_TAB
3813 return (AS1 (lsr,%B0) CR_TAB
3814 AS1 (ror,%A0) CR_TAB
3815 AS1 (swap,%B0) CR_TAB
3816 AS1 (swap,%A0) CR_TAB
3817 AS2 (ldi,%3,0x0f) CR_TAB
3818 AS2 (and,%A0,%3) CR_TAB
3819 AS2 (eor,%A0,%B0) CR_TAB
3820 AS2 (and,%B0,%3) CR_TAB
3827 break; /* scratch ? 5 : 6 */
3829 return (AS1 (clr,__tmp_reg__) CR_TAB
3830 AS1 (lsl,%A0) CR_TAB
3831 AS1 (rol,%B0) CR_TAB
3832 AS1 (rol,__tmp_reg__) CR_TAB
3833 AS1 (lsl,%A0) CR_TAB
3834 AS1 (rol,%B0) CR_TAB
3835 AS1 (rol,__tmp_reg__) CR_TAB
3836 AS2 (mov,%A0,%B0) CR_TAB
3837 AS2 (mov,%B0,__tmp_reg__));
3841 return (AS1 (lsl,%A0) CR_TAB
3842 AS2 (mov,%A0,%B0) CR_TAB
3843 AS1 (rol,%A0) CR_TAB
3844 AS2 (sbc,%B0,%B0) CR_TAB
3848 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
3849 return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
3852 return *len = 1, AS1 (clr,%B0);
3856 return (AS2 (mov,%A0,%B0) CR_TAB
3857 AS1 (clr,%B0) CR_TAB
3862 return (AS2 (mov,%A0,%B0) CR_TAB
3863 AS1 (clr,%B0) CR_TAB
3864 AS1 (lsr,%A0) CR_TAB
3869 return (AS2 (mov,%A0,%B0) CR_TAB
3870 AS1 (clr,%B0) CR_TAB
3871 AS1 (lsr,%A0) CR_TAB
3872 AS1 (lsr,%A0) CR_TAB
3879 return (AS2 (mov,%A0,%B0) CR_TAB
3880 AS1 (clr,%B0) CR_TAB
3881 AS1 (swap,%A0) CR_TAB
3882 AS2 (andi,%A0,0x0f));
3887 return (AS2 (mov,%A0,%B0) CR_TAB
3888 AS1 (clr,%B0) CR_TAB
3889 AS1 (swap,%A0) CR_TAB
3890 AS2 (ldi,%3,0x0f) CR_TAB
3894 return (AS2 (mov,%A0,%B0) CR_TAB
3895 AS1 (clr,%B0) CR_TAB
3896 AS1 (lsr,%A0) CR_TAB
3897 AS1 (lsr,%A0) CR_TAB
3898 AS1 (lsr,%A0) CR_TAB
3905 return (AS2 (mov,%A0,%B0) CR_TAB
3906 AS1 (clr,%B0) CR_TAB
3907 AS1 (swap,%A0) CR_TAB
3908 AS1 (lsr,%A0) CR_TAB
3909 AS2 (andi,%A0,0x07));
3911 if (AVR_ENHANCED && scratch)
3914 return (AS2 (ldi,%3,0x08) CR_TAB
3915 AS2 (mul,%B0,%3) CR_TAB
3916 AS2 (mov,%A0,r1) CR_TAB
3917 AS1 (clr,%B0) CR_TAB
3918 AS1 (clr,__zero_reg__));
3920 if (optimize_size && scratch)
3925 return (AS2 (mov,%A0,%B0) CR_TAB
3926 AS1 (clr,%B0) CR_TAB
3927 AS1 (swap,%A0) CR_TAB
3928 AS1 (lsr,%A0) CR_TAB
3929 AS2 (ldi,%3,0x07) CR_TAB
3935 return ("set" CR_TAB
3936 AS2 (bld,r1,3) CR_TAB
3937 AS2 (mul,%B0,r1) CR_TAB
3938 AS2 (mov,%A0,r1) CR_TAB
3939 AS1 (clr,%B0) CR_TAB
3940 AS1 (clr,__zero_reg__));
3943 return (AS2 (mov,%A0,%B0) CR_TAB
3944 AS1 (clr,%B0) CR_TAB
3945 AS1 (lsr,%A0) CR_TAB
3946 AS1 (lsr,%A0) CR_TAB
3947 AS1 (lsr,%A0) CR_TAB
3948 AS1 (lsr,%A0) CR_TAB
3952 if (AVR_ENHANCED && ldi_ok)
3955 return (AS2 (ldi,%A0,0x04) CR_TAB
3956 AS2 (mul,%B0,%A0) CR_TAB
3957 AS2 (mov,%A0,r1) CR_TAB
3958 AS1 (clr,%B0) CR_TAB
3959 AS1 (clr,__zero_reg__));
3961 if (AVR_ENHANCED && scratch)
3964 return (AS2 (ldi,%3,0x04) CR_TAB
3965 AS2 (mul,%B0,%3) CR_TAB
3966 AS2 (mov,%A0,r1) CR_TAB
3967 AS1 (clr,%B0) CR_TAB
3968 AS1 (clr,__zero_reg__));
3970 if (optimize_size && ldi_ok)
3973 return (AS2 (mov,%A0,%B0) CR_TAB
3974 AS2 (ldi,%B0,6) "\n1:\t"
3975 AS1 (lsr,%A0) CR_TAB
3976 AS1 (dec,%B0) CR_TAB
3979 if (optimize_size && scratch)
3982 return (AS1 (clr,%A0) CR_TAB
3983 AS1 (lsl,%B0) CR_TAB
3984 AS1 (rol,%A0) CR_TAB
3985 AS1 (lsl,%B0) CR_TAB
3986 AS1 (rol,%A0) CR_TAB
3991 return (AS1 (clr,%A0) CR_TAB
3992 AS1 (lsl,%B0) CR_TAB
3993 AS1 (rol,%A0) CR_TAB
3998 out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
4000 insn, operands, len, 2);
4004 /* 32bit logic shift right ((unsigned int)x >> i) */
4007 lshrsi3_out (insn, operands, len)
4012 if (GET_CODE (operands[2]) == CONST_INT)
4020 switch (INTVAL (operands[2]))
4024 int reg0 = true_regnum (operands[0]);
4025 int reg1 = true_regnum (operands[1]);
4028 return (AS2 (mov,%A0,%B1) CR_TAB
4029 AS2 (mov,%B0,%C1) CR_TAB
4030 AS2 (mov,%C0,%D1) CR_TAB
4032 else if (reg0 == reg1 + 1)
4033 return *len = 1, AS1 (clr,%D0);
4035 return (AS1 (clr,%D0) CR_TAB
4036 AS2 (mov,%C0,%D1) CR_TAB
4037 AS2 (mov,%B0,%C1) CR_TAB
4043 int reg0 = true_regnum (operands[0]);
4044 int reg1 = true_regnum (operands[1]);
4046 if (AVR_ENHANCED && (reg0 != reg1 + 2))
4049 return (AS2 (movw,%A0,%C1) CR_TAB
4050 AS1 (clr,%C0) CR_TAB
4053 if (reg0 <= reg1 + 1)
4054 return (AS2 (mov,%A0,%C1) CR_TAB
4055 AS2 (mov,%B0,%D1) CR_TAB
4056 AS1 (clr,%C0) CR_TAB
4058 else if (reg0 == reg1 + 2)
4059 return *len = 2, (AS1 (clr,%C0) CR_TAB
4062 return (AS2 (mov,%B0,%D1) CR_TAB
4063 AS2 (mov,%A0,%C1) CR_TAB
4064 AS1 (clr,%C0) CR_TAB
4069 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
4070 return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4071 AS1 (clr,%B0) CR_TAB
4072 AS1 (clr,%C0) CR_TAB
4075 return *len = 3, (AS1 (clr,%B0) CR_TAB
4076 AS1 (clr,%C0) CR_TAB
4081 return (AS1 (clr,%A0) CR_TAB
4082 AS2 (sbrc,%D0,7) CR_TAB
4083 AS1 (inc,%A0) CR_TAB
4084 AS1 (clr,%B0) CR_TAB
4085 AS1 (clr,%C0) CR_TAB
4090 out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4091 AS1 (ror,%C0) CR_TAB
4092 AS1 (ror,%B0) CR_TAB
4094 insn, operands, len, 4);
4098 /* Modifies the length assigned to instruction INSN
4099 LEN is the initially computed length of the insn. */
4102 adjust_insn_length (insn, len)
4106 rtx patt = PATTERN (insn);
4109 if (GET_CODE (patt) == SET)
4112 op[1] = SET_SRC (patt);
4113 op[0] = SET_DEST (patt);
4114 if (general_operand (op[1], VOIDmode)
4115 && general_operand (op[0], VOIDmode))
4117 switch (GET_MODE (op[0]))
4120 output_movqi (insn, op, &len);
4123 output_movhi (insn, op, &len);
4127 output_movsisf (insn, op, &len);
4133 else if (op[0] == cc0_rtx && REG_P (op[1]))
4135 switch (GET_MODE (op[1]))
4137 case HImode: out_tsthi (insn,&len); break;
4138 case SImode: out_tstsi (insn,&len); break;
4142 else if (GET_CODE (op[1]) == AND)
4144 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4146 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4147 if (GET_MODE (op[1]) == SImode)
4148 len = (((mask & 0xff) != 0xff)
4149 + ((mask & 0xff00) != 0xff00)
4150 + ((mask & 0xff0000UL) != 0xff0000UL)
4151 + ((mask & 0xff000000UL) != 0xff000000UL));
4152 else if (GET_MODE (op[1]) == HImode)
4153 len = (((mask & 0xff) != 0xff)
4154 + ((mask & 0xff00) != 0xff00));
4157 else if (GET_CODE (op[1]) == IOR)
4159 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4161 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4162 if (GET_MODE (op[1]) == SImode)
4163 len = (((mask & 0xff) != 0)
4164 + ((mask & 0xff00) != 0)
4165 + ((mask & 0xff0000UL) != 0)
4166 + ((mask & 0xff000000UL) != 0));
4167 else if (GET_MODE (op[1]) == HImode)
4168 len = (((mask & 0xff) != 0)
4169 + ((mask & 0xff00) != 0));
4173 set = single_set (insn);
4178 op[1] = SET_SRC (set);
4179 op[0] = SET_DEST (set);
4181 if (GET_CODE (patt) == PARALLEL
4182 && general_operand (op[1], VOIDmode)
4183 && general_operand (op[0], VOIDmode))
4185 if (XVECLEN (patt, 0) == 2)
4186 op[2] = XVECEXP (patt, 0, 1);
4188 switch (GET_MODE (op[0]))
4194 output_reload_inhi (insn, op, &len);
4198 output_reload_insisf (insn, op, &len);
4204 else if (GET_CODE (op[1]) == ASHIFT
4205 || GET_CODE (op[1]) == ASHIFTRT
4206 || GET_CODE (op[1]) == LSHIFTRT)
4210 ops[1] = XEXP (op[1],0);
4211 ops[2] = XEXP (op[1],1);
4212 switch (GET_CODE (op[1]))
4215 switch (GET_MODE (op[0]))
4217 case QImode: ashlqi3_out (insn,ops,&len); break;
4218 case HImode: ashlhi3_out (insn,ops,&len); break;
4219 case SImode: ashlsi3_out (insn,ops,&len); break;
4224 switch (GET_MODE (op[0]))
4226 case QImode: ashrqi3_out (insn,ops,&len); break;
4227 case HImode: ashrhi3_out (insn,ops,&len); break;
4228 case SImode: ashrsi3_out (insn,ops,&len); break;
4233 switch (GET_MODE (op[0]))
4235 case QImode: lshrqi3_out (insn,ops,&len); break;
4236 case HImode: lshrhi3_out (insn,ops,&len); break;
4237 case SImode: lshrsi3_out (insn,ops,&len); break;
4249 /* Return non-zero if register REG dead after INSN */
4252 reg_unused_after (insn, reg)
4256 return (dead_or_set_p (insn, reg)
4257 || (REG_P(reg) && _reg_unused_after (insn, reg)));
4260 /* Return non-zero if REG is not used after INSN.
4261 We assume REG is a reload reg, and therefore does
4262 not live past labels. It may live past calls or jumps though. */
4265 _reg_unused_after (insn, reg)
4272 /* If the reg is set by this instruction, then it is safe for our
4273 case. Disregard the case where this is a store to memory, since
4274 we are checking a register used in the store address. */
4275 set = single_set (insn);
4276 if (set && GET_CODE (SET_DEST (set)) != MEM
4277 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4280 while ((insn = NEXT_INSN (insn)))
4282 code = GET_CODE (insn);
4285 /* If this is a label that existed before reload, then the register
4286 if dead here. However, if this is a label added by reorg, then
4287 the register may still be live here. We can't tell the difference,
4288 so we just ignore labels completely. */
4289 if (code == CODE_LABEL)
4294 if (code == JUMP_INSN)
4297 /* If this is a sequence, we must handle them all at once.
4298 We could have for instance a call that sets the target register,
4299 and a insn in a delay slot that uses the register. In this case,
4300 we must return 0. */
4301 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
4306 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
4308 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
4309 rtx set = single_set (this_insn);
4311 if (GET_CODE (this_insn) == CALL_INSN)
4313 else if (GET_CODE (this_insn) == JUMP_INSN)
4315 if (INSN_ANNULLED_BRANCH_P (this_insn))
4320 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4322 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4324 if (GET_CODE (SET_DEST (set)) != MEM)
4330 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
4335 else if (code == JUMP_INSN)
4339 if (code == CALL_INSN)
4342 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4343 if (GET_CODE (XEXP (tem, 0)) == USE
4344 && REG_P (XEXP (XEXP (tem, 0), 0))
4345 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
4347 if (call_used_regs[REGNO (reg)])
4351 if (GET_RTX_CLASS (code) == 'i')
4353 rtx set = single_set (insn);
4355 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4357 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4358 return GET_CODE (SET_DEST (set)) != MEM;
4359 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
4366 /* Output rtx VALUE as .byte to file FILE */
4369 asm_output_char (file, value)
4373 fprintf (file, "\t.byte ");
4374 output_addr_const (file, value);
4375 fprintf (file, "\n");
4379 /* Output VALUE as .byte to file FILE */
4382 asm_output_byte (file, value)
4386 fprintf (file, "\t.byte 0x%x\n", value & 0xff);
4390 /* Output rtx VALUE as .word to file FILE */
4393 asm_output_short (file, value)
4397 if (SYMBOL_REF_FLAG (value) || GET_CODE (value) == LABEL_REF)
4399 fprintf (file, "\t.word pm(");
4400 output_addr_const (file, (value));
4401 fprintf (file, ")\n");
4405 fprintf (file, "\t.word ");
4406 output_addr_const (file, (value));
4407 fprintf (file, "\n");
4412 /* Output real N to file FILE */
4415 asm_output_float (file, n)
4422 REAL_VALUE_TO_TARGET_SINGLE (n, val);
4423 REAL_VALUE_TO_DECIMAL (n, "%g", dstr);
4424 fprintf (file, "\t.long 0x%08lx\t/* %s */\n", val, dstr);
4427 /* Sets section name for declaration DECL */
4430 unique_section (decl, reloc)
4432 int reloc ATTRIBUTE_UNUSED;
4435 const char *name, *prefix;
4437 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
4438 /* Strip off any encoding in name. */
4439 STRIP_NAME_ENCODING (name, name);
4441 if (TREE_CODE (decl) == FUNCTION_DECL)
4443 if (flag_function_sections)
4449 fatal ("Strange situation: unique section is not a FUNCTION_DECL");
4451 if (flag_function_sections)
4453 len = strlen (name) + strlen (prefix);
4454 string = alloca (len + 1);
4455 sprintf (string, "%s%s", prefix, name);
4456 DECL_SECTION_NAME (decl) = build_string (len, string);
4461 /* Output section name to file FILE
4462 We make the section read-only and executable for a function decl,
4463 read-only for a const data decl, and writable for a non-const data decl. */
4466 asm_output_section_name(file, decl, name, reloc)
4470 int reloc ATTRIBUTE_UNUSED;
4472 fprintf (file, ".section %s, \"%s\", @progbits\n", name,
4473 decl && TREE_CODE (decl) == FUNCTION_DECL ? "ax" :
4474 decl && TREE_READONLY (decl) ? "a" : "aw");
4478 /* The routine used to output NUL terminated strings. We use a special
4479 version of this for most svr4 targets because doing so makes the
4480 generated assembly code more compact (and thus faster to assemble)
4481 as well as more readable, especially for targets like the i386
4482 (where the only alternative is to output character sequences as
4483 comma separated lists of numbers). */
4486 gas_output_limited_string(file, str)
4490 const unsigned char *_limited_str = (unsigned char *) str;
4492 fprintf (file, "%s\"", STRING_ASM_OP);
4493 for (; (ch = *_limited_str); _limited_str++)
4496 switch (escape = ESCAPES[ch])
4502 fprintf (file, "\\%03o", ch);
4506 putc (escape, file);
4510 fprintf (file, "\"\n");
4513 /* The routine used to output sequences of byte values. We use a special
4514 version of this for most svr4 targets because doing so makes the
4515 generated assembly code more compact (and thus faster to assemble)
4516 as well as more readable. Note that if we find subparts of the
4517 character sequence which end with NUL (and which are shorter than
4518 STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
4521 gas_output_ascii(file, str, length)
4526 const unsigned char *_ascii_bytes = (const unsigned char *) str;
4527 const unsigned char *limit = _ascii_bytes + length;
4528 unsigned bytes_in_chunk = 0;
4529 for (; _ascii_bytes < limit; _ascii_bytes++)
4531 const unsigned char *p;
4532 if (bytes_in_chunk >= 60)
4534 fprintf (file, "\"\n");
4537 for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
4539 if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
4541 if (bytes_in_chunk > 0)
4543 fprintf (file, "\"\n");
4546 gas_output_limited_string (file, (char*)_ascii_bytes);
4553 if (bytes_in_chunk == 0)
4554 fprintf (file, "\t.ascii\t\"");
4555 switch (escape = ESCAPES[ch = *_ascii_bytes])
4562 fprintf (file, "\\%03o", ch);
4563 bytes_in_chunk += 4;
4567 putc (escape, file);
4568 bytes_in_chunk += 2;
4573 if (bytes_in_chunk > 0)
4574 fprintf (file, "\"\n");
4577 /* Return value is nonzero if pseudos that have been
4578 assigned to registers of class CLASS would likely be spilled
4579 because registers of CLASS are needed for spill registers. */
4582 class_likely_spilled_p (c)
4585 return (c != ALL_REGS && c != ADDW_REGS);
4588 /* Only `progmem' attribute valid for type. */
4591 valid_machine_type_attribute(type, attributes, identifier, args)
4592 tree type ATTRIBUTE_UNUSED;
4593 tree attributes ATTRIBUTE_UNUSED;
4595 tree args ATTRIBUTE_UNUSED;
4597 return is_attribute_p ("progmem", identifier);
4600 /* If IDENTIFIER with arguments ARGS is a valid machine specific
4601 attribute for DECL return 1.
4603 progmem - put data to program memory;
4604 signal - make a function to be hardware interrupt. After function
4605 prologue interrupts are disabled;
4606 interrupt - make a function to be hardware interrupt. After function
4607 prologue interrupts are enabled;
4608 naked - don't generate function prologue/epilogue and `ret' command. */
4611 valid_machine_decl_attribute (decl, attributes, attr, args)
4613 tree attributes ATTRIBUTE_UNUSED;
4615 tree args ATTRIBUTE_UNUSED;
4617 if (is_attribute_p ("interrupt", attr)
4618 || is_attribute_p ("signal", attr)
4619 || is_attribute_p ("naked", attr))
4620 return TREE_CODE (decl) == FUNCTION_DECL;
4622 if (is_attribute_p ("progmem", attr)
4623 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
4625 if (DECL_INITIAL (decl) == NULL_TREE && !DECL_EXTERNAL (decl))
4627 warning ("Only initialized variables can be placed into "
4628 "program memory area.");
4637 /* Look for attribute `progmem' in DECL
4638 if found return 1, otherwise 0. */
4641 avr_progmem_p (decl)
4646 if (TREE_CODE (decl) != VAR_DECL)
4650 != lookup_attribute ("progmem", DECL_MACHINE_ATTRIBUTES (decl)))
4656 while (TREE_CODE (a) == ARRAY_TYPE);
4658 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
4664 /* Encode section information about tree DECL */
4667 encode_section_info (decl)
4670 if (TREE_CODE (decl) == FUNCTION_DECL)
4671 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
4673 if ((TREE_STATIC (decl) || DECL_EXTERNAL (decl))
4674 && TREE_CODE (decl) == VAR_DECL
4675 && avr_progmem_p (decl))
4677 const char *dsec = ".progmem.data";
4678 DECL_SECTION_NAME (decl) = build_string (strlen (dsec), dsec);
4679 TREE_READONLY (decl) = 1;
4683 /* Outputs to the stdio stream FILE some
4684 appropriate text to go at the start of an assembler file. */
4687 asm_file_start (file)
4690 output_file_directive (file, main_input_filename);
4691 fprintf (file, "\t.arch %s\n", avr_mcu_name);
4692 fputs ("__SREG__ = 0x3f\n"
4694 "__SP_L__ = 0x3d\n", file);
4696 fputs ("__tmp_reg__ = 0\n"
4697 "__zero_reg__ = 1\n"
4698 "_PC_ = 2\n", file);
4700 commands_in_file = 0;
4701 commands_in_prologues = 0;
4702 commands_in_epilogues = 0;
4705 /* Outputs to the stdio stream FILE some
4706 appropriate text to go at the end of an assembler file. */
4713 "/* File %s: code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
4714 main_input_filename,
4717 commands_in_file - commands_in_prologues - commands_in_epilogues,
4718 commands_in_prologues, commands_in_epilogues);
4721 /* Choose the order in which to allocate hard registers for
4722 pseudo-registers local to a basic block.
4724 Store the desired register order in the array `reg_alloc_order'.
4725 Element 0 should be the register to allocate first; element 1, the
4726 next register; and so on. */
4729 order_regs_for_local_alloc ()
4740 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4752 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4765 15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4770 int *order = (TARGET_ORDER_1 ? order_1 :
4771 TARGET_ORDER_2 ? order_2 :
4773 for (i=0; i < ARRAY_SIZE (order_0); ++i)
4774 reg_alloc_order[i] = order[i];
4777 /* Calculate the cost of X code of the expression in which it is contained,
4778 found in OUTER_CODE */
4781 default_rtx_costs (X, code, outer_code)
4784 enum rtx_code outer_code;
4791 cost = 2 * GET_MODE_SIZE (GET_MODE (X));
4794 if (outer_code != SET)
4796 if (GET_CODE (XEXP (X,0)) == SYMBOL_REF)
4797 cost += 2 * GET_MODE_SIZE (GET_MODE (X));
4799 cost += GET_MODE_SIZE (GET_MODE (X));
4805 if (outer_code == SET)
4806 cost = GET_MODE_SIZE (GET_MODE (X));
4808 cost = -GET_MODE_SIZE (GET_MODE (X));
4811 if (outer_code == SET)
4812 cost = GET_MODE_SIZE (GET_MODE (X));
4818 if (outer_code == SET)
4820 if (X == stack_pointer_rtx)
4822 else if (GET_CODE (XEXP (X,1)) == CONST_INT)
4823 cost = (INTVAL (XEXP (X,1)) <= 63 ? 1 :
4824 GET_MODE_SIZE (GET_MODE (X)));
4826 cost = GET_MODE_SIZE (GET_MODE (X));
4830 if (GET_CODE (XEXP (X,1)) == CONST_INT)
4831 cost = GET_MODE_SIZE (GET_MODE (XEXP (X,0)));
4839 /* Calculate the cost of a memory address */
4842 avr_address_cost (x)
4845 if (GET_CODE (x) == PLUS
4846 && GET_CODE (XEXP (x,1)) == CONST_INT
4847 && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
4848 && INTVAL (XEXP (x,1)) >= 61)
4850 if (CONSTANT_ADDRESS_P (x))
4852 if (io_address_p (x, 1))
4859 /* EXTRA_CONSTRAINT helper */
4862 extra_constraint (x, c)
4867 && GET_CODE (x) == MEM
4868 && GET_CODE (XEXP (x,0)) == PLUS)
4870 if (TARGET_ALL_DEBUG)
4872 fprintf (stderr, ("extra_constraint:\n"
4873 "reload_completed: %d\n"
4874 "reload_in_progress: %d\n"),
4875 reload_completed, reload_in_progress);
4878 if (GET_CODE (x) == MEM
4879 && GET_CODE (XEXP (x,0)) == PLUS
4880 && REG_P (XEXP (XEXP (x,0), 0))
4881 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
4882 && (INTVAL (XEXP (XEXP (x,0), 1))
4883 <= MAX_LD_OFFSET (GET_MODE (x))))
4885 rtx xx = XEXP (XEXP (x,0), 0);
4886 int regno = REGNO (xx);
4887 if (TARGET_ALL_DEBUG)
4889 fprintf (stderr, ("extra_constraint:\n"
4890 "reload_completed: %d\n"
4891 "reload_in_progress: %d\n"),
4892 reload_completed, reload_in_progress);
4895 if (regno >= FIRST_PSEUDO_REGISTER)
4896 return 1; /* allocate pseudos */
4897 else if (regno == REG_Z || regno == REG_Y)
4898 return 1; /* strictly check */
4899 else if (xx == frame_pointer_rtx
4900 || xx == arg_pointer_rtx)
4901 return 1; /* XXX frame & arg pointer checks */
4907 /* Convert condition code CONDITION to the valid AVR condition code */
4910 avr_normalize_condition (condition)
4924 fatal ("Wrong condition: %s", GET_RTX_NAME (condition));
4928 /* This fnction optimizes conditional jumps */
4931 machine_dependent_reorg (first_insn)
4937 for (insn = first_insn; insn; insn = NEXT_INSN (insn))
4939 if (! (insn == 0 || GET_CODE (insn) == INSN
4940 || GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN)
4941 || !single_set (insn))
4944 pattern = PATTERN (insn);
4946 cc_prev_status = cc_status;
4947 NOTICE_UPDATE_CC (pattern, insn);
4949 if (GET_CODE (pattern) == PARALLEL)
4950 pattern = XVECEXP (pattern, 0, 0);
4951 if (GET_CODE (pattern) == SET
4952 && SET_DEST (pattern) == cc0_rtx
4953 && compare_diff_p (insn))
4955 if (GET_CODE (SET_SRC (pattern)) == COMPARE)
4957 /* Now we work under compare insn */
4959 pattern = SET_SRC (pattern);
4960 if (true_regnum (XEXP (pattern,0)) >= 0
4961 && true_regnum (XEXP (pattern,1)) >= 0 )
4963 rtx x = XEXP (pattern,0);
4964 rtx next = next_real_insn (insn);
4965 rtx pat = PATTERN (next);
4966 rtx src = SET_SRC (pat);
4967 rtx t = XEXP (src,0);
4968 PUT_CODE (t, swap_condition (GET_CODE (t)));
4969 XEXP (pattern,0) = XEXP (pattern,1);
4970 XEXP (pattern,1) = x;
4971 INSN_CODE (next) = -1;
4973 else if (true_regnum (XEXP (pattern,0)) >= 0
4974 && GET_CODE (XEXP (pattern,1)) == CONST_INT)
4976 rtx x = XEXP (pattern,1);
4977 rtx next = next_real_insn (insn);
4978 rtx pat = PATTERN (next);
4979 rtx src = SET_SRC (pat);
4980 rtx t = XEXP (src,0);
4982 if (avr_simplify_comparision_p (GET_MODE (XEXP (pattern,0)),
4985 XEXP (pattern,1) = GEN_INT (INTVAL (x)+1);
4986 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
4987 INSN_CODE (next) = -1;
4988 INSN_CODE (insn) = -1;
4992 else if (true_regnum (SET_SRC (pattern)) >= 0)
4994 /* This is a tst insn */
4995 rtx next = next_real_insn (insn);
4996 rtx pat = PATTERN (next);
4997 rtx src = SET_SRC (pat);
4998 rtx t = XEXP (src,0);
5000 if (!(cc_prev_status.value1 != 0 && cc_status.value1 != 0
5001 && rtx_equal_p (cc_status.value1, cc_prev_status.value1)))
5003 PUT_CODE (t, swap_condition (GET_CODE (t)));
5004 SET_SRC (pattern) = gen_rtx (NEG,
5005 GET_MODE (SET_SRC (pattern)),
5007 INSN_CODE (next) = -1;
5008 INSN_CODE (insn) = -1;
5015 /* Returns register number for function return value.*/
5023 /* Ceate an RTX representing the place where a
5024 library function returns a value of mode MODE. */
5027 avr_libcall_value (mode)
5028 enum machine_mode mode;
5030 int offs = GET_MODE_SIZE (mode);
5033 return gen_rtx (REG, mode, RET_REGISTER + 2 - offs);
5036 /* Create an RTX representing the place where a
5037 function returns a value of data type VALTYPE. */
5040 avr_function_value (type, func)
5042 tree func ATTRIBUTE_UNUSED;
5045 if (TYPE_MODE (type) != BLKmode)
5046 return avr_libcall_value (TYPE_MODE (type));
5048 offs = int_size_in_bytes (type);
5051 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
5052 offs = GET_MODE_SIZE (SImode);
5053 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
5054 offs = GET_MODE_SIZE (DImode);
5056 return gen_rtx (REG, BLKmode, RET_REGISTER + 2 - offs);
5059 /* Returns non-zero if the number MASK has only one bit set. */
5062 mask_one_bit_p (mask)
5066 unsigned HOST_WIDE_INT n=mask;
5067 for (i = 0; i < 32; ++i)
5069 if (n & 0x80000000UL)
5071 if (n & 0x7fffffffUL)
5082 /* Places additional restrictions on the register class to
5083 use when it is necessary to copy value X into a register
5087 preferred_reload_class (x, class)
5088 rtx x ATTRIBUTE_UNUSED;
5089 enum reg_class class;
5095 test_hard_reg_class (class, x)
5096 enum reg_class class;
5099 int regno = true_regnum (x);
5102 return TEST_HARD_REG_CLASS (class, regno);
5106 debug_hard_reg_set (set)
5110 for (i=0; i < FIRST_PSEUDO_REGISTER; ++i)
5112 if (TEST_HARD_REG_BIT (set, i))
5114 fprintf (stderr, "r%-2d ", i);
5117 fprintf (stderr, "\n");
5121 jump_over_one_insn_p (insn, dest)
5125 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
5128 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
5129 int dest_addr = INSN_ADDRESSES (uid);
5130 return dest_addr - jump_addr == 2;
5133 /* Returns 1 if a value of mode MODE can be stored starting with hard
5134 register number REGNO. On the enhanced core, anything larger than
5135 1 byte must start in even numbered register for "movw" to work
5136 (this way we don't have to check for odd registers everywhere). */
5139 avr_hard_regno_mode_ok (regno, mode)
5141 enum machine_mode mode;
5145 /* if (regno < 24 && !AVR_ENHANCED)
5147 return !(regno & 1);
5150 /* Returns 1 if we know register operand OP was 0 before INSN. */
5153 reg_was_0 (insn, op)
5158 return (optimize > 0 && insn && op && REG_P (op)
5159 && (link = find_reg_note (insn, REG_WAS_0, 0))
5160 /* Make sure the insn that stored the 0 is still present. */
5161 && ! INSN_DELETED_P (XEXP (link, 0))
5162 && GET_CODE (XEXP (link, 0)) != NOTE
5163 /* Make sure cross jumping didn't happen here. */
5164 && no_labels_between_p (XEXP (link, 0), insn)
5165 /* Make sure the reg hasn't been clobbered. */
5166 && ! reg_set_between_p (op, XEXP (link, 0), insn));
5169 /* Returns 1 if X is a valid address for an I/O register of size SIZE
5170 (1 or 2). Used for lds/sts -> in/out optimization. */
5173 io_address_p (x, size)
5177 return (optimize > 0 && GET_CODE (x) == CONST_INT
5178 && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size);
5181 /* Returns nonzero (bit number + 1) if X, or -X, is a constant power of 2. */
5184 const_int_pow2_p (x)
5187 if (GET_CODE (x) == CONST_INT)
5189 HOST_WIDE_INT d = INTVAL (x);
5190 HOST_WIDE_INT abs_d = (d >= 0) ? d : -d;
5191 return exact_log2 (abs_d) + 1;
5197 output_reload_inhi (insn, operands, len)
5198 rtx insn ATTRIBUTE_UNUSED;
5206 if (GET_CODE (operands[1]) == CONST_INT)
5208 int val = INTVAL (operands[1]);
5209 if ((val & 0xff) == 0)
5212 return (AS2 (mov,%A0,__zero_reg__) CR_TAB
5213 AS2 (ldi,%2,hi8(%1)) CR_TAB
5216 else if ((val & 0xff00) == 0)
5219 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5220 AS2 (mov,%A0,%2) CR_TAB
5221 AS2 (mov,%B0,__zero_reg__));
5223 else if ((val & 0xff) == ((val & 0xff00) >> 8))
5226 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5227 AS2 (mov,%A0,%2) CR_TAB
5232 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5233 AS2 (mov,%A0,%2) CR_TAB
5234 AS2 (ldi,%2,hi8(%1)) CR_TAB
5240 output_reload_insisf (insn, operands, len)
5241 rtx insn ATTRIBUTE_UNUSED;
5245 rtx src = operands[1];
5246 int cnst = (GET_CODE (src) == CONST_INT);
5251 *len = 4 + ((INTVAL (src) & 0xff) != 0)
5252 + ((INTVAL (src) & 0xff00) != 0)
5253 + ((INTVAL (src) & 0xff0000) != 0)
5254 + ((INTVAL (src) & 0xff000000U) != 0);
5261 if (cnst && ((INTVAL (src) & 0xff) == 0))
5262 output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
5265 output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
5266 output_asm_insn (AS2 (mov, %A0, %2), operands);
5268 if (cnst && ((INTVAL (src) & 0xff00) == 0))
5269 output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
5272 output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
5273 output_asm_insn (AS2 (mov, %B0, %2), operands);
5275 if (cnst && ((INTVAL (src) & 0xff0000) == 0))
5276 output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
5279 output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
5280 output_asm_insn (AS2 (mov, %C0, %2), operands);
5282 if (cnst && ((INTVAL (src) & 0xff000000U) == 0))
5283 output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
5286 output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
5287 output_asm_insn (AS2 (mov, %D0, %2), operands);
5293 avr_output_bld (operands, bit_nr)
5297 static char s[] = "bld %A0,0";
5299 s[5] = 'A' + (bit_nr >> 3);
5300 s[8] = '0' + (bit_nr & 7);
5301 output_asm_insn (s, operands);
5305 avr_output_addr_vec_elt (stream, value)
5310 fprintf (stream, "\t.word pm(.L%d)\n", value);
5312 fprintf (stream, "\trjmp .L%d\n", value);