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"
44 static int avr_naked_function_p PARAMS ((tree));
45 static int interrupt_function_p PARAMS ((tree));
46 static int signal_function_p PARAMS ((tree));
47 static int sequent_regs_live PARAMS ((void));
48 static char * ptrreg_to_str PARAMS ((int));
49 static char * cond_string PARAMS ((enum rtx_code));
52 /* Allocate registers from r25 to r8 for parameters for function calls */
53 #define FIRST_CUM_REG 26
55 /* Temporary register RTX (gen_rtx (REG,QImode,TMP_REGNO)) */
58 /* Zeroed register RTX (gen_rtx (REG,QImode,ZERO_REGNO)) */
61 /* AVR register names {"r0", "r1", ..., "r31"} */
62 char * avr_regnames[] = REGISTER_NAMES;
64 /* This holds the last insn address. */
65 static int last_insn_address = 0;
67 /* Commands count in the compiled file */
68 static int commands_in_file;
70 /* Commands in the functions prologues in the compiled file */
71 static int commands_in_prologues;
73 /* Commands in the functions epilogues in the compiled file */
74 static int commands_in_epilogues;
76 /* Prologue/Epilogue size in words */
77 static int prologue_size;
78 static int epilogue_size;
80 /* Initial stack value specified by the `-minit-stack=' option */
81 const char *avr_ram_end = NULL;
83 /* Numeric representation */
84 static const char *initial_stack;
86 /* Default MCU name */
87 const char *avr_mcu_name = "at90s8515";
90 struct mcu_type_s *avr_mcu_type;
92 /* MCU names, initial stack value, flag 'mega' */
93 static struct mcu_type_s mcu_types[] =
94 {{"at90s2313", 224-1, 0},
95 {"at90s2323", 224-1, 0},
96 {"at90s2333", 224-1, 0},
97 {"attiny22", 224-1, 0},
98 {"at90s2343", 224-1, 0},
99 {"at90s4433", 224-1, 0},
100 {"at90s4414", 0x15f, 0},
101 {"at90s4434", 0x15f, 0},
102 {"at90s8515", 0x25f, 0},
103 {"at90s8535", 0x25f, 0},
104 {"atmega603", 0x0fff,1},
105 {"atmega103", 0x0fff,1},
111 avr_override_options (void)
113 for (avr_mcu_type = mcu_types; avr_mcu_type->name; ++avr_mcu_type)
114 if (strcmp (avr_mcu_type->name, avr_mcu_name) == 0)
116 if (!avr_mcu_type->name)
120 "Wrong mcu `%s' specified\n"
121 "Allowed mcu's:\n", avr_mcu_name);
122 for (i = 0; mcu_types[i].name; ++i)
123 fprintf (stderr," %s\n", mcu_types[i].name);
124 fatal ("select right mcu name");
128 /* Initialize TMP_REG_RTX and ZERO_REG_RTX */
132 tmp_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
133 memset (tmp_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
134 PUT_CODE (tmp_reg_rtx, REG);
135 PUT_MODE (tmp_reg_rtx, QImode);
136 XINT (tmp_reg_rtx, 0) = TMP_REGNO;
138 zero_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
139 memset (zero_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
140 PUT_CODE (zero_reg_rtx, REG);
141 PUT_MODE (zero_reg_rtx, QImode);
142 XINT (zero_reg_rtx, 0) = ZERO_REGNO;
145 /* return register class from register number */
147 static int reg_class_tab[]={
148 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
149 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
150 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
151 GENERAL_REGS, /* r0 - r15 */
152 LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
153 LD_REGS, /* r16 - 23 */
154 ADDW_REGS,ADDW_REGS, /* r24,r25 */
155 POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
156 POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
157 POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
158 STACK_REG,STACK_REG /* SPL,SPH */
161 /* Return register class for register R */
164 avr_regno_reg_class (r)
168 return reg_class_tab[r];
173 /* A C expression which defines the machine-dependent operand
174 constraint letters for register classes. If C is such a
175 letter, the value should be the register class corresponding to
176 it. Otherwise, the value should be `NO_REGS'. The register
177 letter `r', corresponding to class `GENERAL_REGS', will not be
178 passed to this macro; you do not need to handle it. */
181 avr_reg_class_from_letter (c)
186 case 't' : return R0_REG;
187 case 'b' : return BASE_POINTER_REGS;
188 case 'e' : return POINTER_REGS;
189 case 'w' : return ADDW_REGS;
190 case 'd' : return LD_REGS;
191 case 'l' : return NO_LD_REGS;
192 case 'a' : return SIMPLE_LD_REGS;
193 case 'x' : return POINTER_X_REGS;
194 case 'y' : return POINTER_Y_REGS;
195 case 'z' : return POINTER_Z_REGS;
196 case 'q' : return STACK_REG;
202 /* Return non-zero if FUNC is a naked function. */
205 avr_naked_function_p (func)
210 if (TREE_CODE (func) != FUNCTION_DECL)
213 a = lookup_attribute ("naked", DECL_MACHINE_ATTRIBUTES (func));
214 return a != NULL_TREE;
217 /* Return nonzero if FUNC is an interrupt function as specified
218 by the "interrupt" attribute. */
221 interrupt_function_p (func)
226 if (TREE_CODE (func) != FUNCTION_DECL)
229 a = lookup_attribute ("interrupt", DECL_MACHINE_ATTRIBUTES (func));
230 return a != NULL_TREE;
233 /* Return nonzero if FUNC is an signal function as specified
234 by the "signal" attribute. */
237 signal_function_p (func)
242 if (TREE_CODE (func) != FUNCTION_DECL)
245 a = lookup_attribute ("signal", DECL_MACHINE_ATTRIBUTES (func));
246 return a != NULL_TREE;
249 /* Compute offset between arg_pointer and frame_pointer */
252 initial_elimination_offset (from,to)
253 int from ATTRIBUTE_UNUSED;
254 int to ATTRIBUTE_UNUSED;
257 int interrupt_func_p = interrupt_function_p (current_function_decl);
258 int signal_func_p = signal_function_p (current_function_decl);
259 int leaf_func_p = leaf_function_p ();
260 int offset= frame_pointer_needed ? 2 : 0;
262 for (reg = 0; reg < 32; ++reg)
264 if ((!leaf_func_p && (call_used_regs[reg]
265 && (interrupt_func_p || signal_func_p)))
266 || (regs_ever_live[reg]
267 && (!call_used_regs[reg] || interrupt_func_p || signal_func_p)
268 && ! (frame_pointer_needed
269 && (reg == REG_Y || reg == (REG_Y+1)))))
274 return get_frame_size () + 2 + 1 + offset;
277 /* This function checks sequence of live registers */
286 for (reg = 0; reg < 18; ++reg)
288 if (!call_used_regs[reg])
290 if (regs_ever_live[reg])
300 if (!frame_pointer_needed)
302 if (regs_ever_live[REG_Y])
310 if (regs_ever_live[REG_Y+1])
323 return (cur_seq == live_seq) ? live_seq : 0;
327 /* Output function prologue */
330 function_prologue (FILE *file, int size)
333 int interrupt_func_p;
340 if (avr_naked_function_p (current_function_decl))
342 fprintf (file, "/* prologue: naked */\n");
346 interrupt_func_p = interrupt_function_p (current_function_decl);
347 signal_func_p = signal_function_p (current_function_decl);
348 leaf_func_p = leaf_function_p ();
349 main_p = ! strcmp ("main", current_function_name);
350 live_seq = sequent_regs_live ();
351 minimize = (TARGET_CALL_PROLOGUES
352 && !interrupt_func_p && !signal_func_p && live_seq);
354 last_insn_address = 0;
356 fprintf (file, "/* prologue: frame size=%d */\n", size);
358 if (interrupt_func_p)
360 fprintf (file,"\tsei\n");
363 if (interrupt_func_p | signal_func_p)
366 AS1 (push,__zero_reg__) CR_TAB
367 AS1 (push,__tmp_reg__) CR_TAB
368 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
369 AS1 (push,__tmp_reg__) CR_TAB
370 AS1 (clr,__zero_reg__) "\n");
376 AS2 (ldi, r28, lo8(%s - %d)) CR_TAB
377 AS2 (ldi, r29, hi8(%s - %d)) CR_TAB
378 AS2 (out,__SP_L__,r28) CR_TAB
379 AS2 (out,__SP_H__,r29) "\n"),
380 initial_stack, size, initial_stack, size);
384 else if (minimize && (frame_pointer_needed || live_seq > 6))
387 AS2 (ldi, r26, %d) CR_TAB
388 AS2 (ldi, r27, %d) CR_TAB), size & 0xff, size / 0x100);
390 fprintf (file, (AS2 (ldi, r30, pm_lo8(.L_%s_body)) CR_TAB
391 AS2 (ldi, r31, pm_hi8(.L_%s_body)) CR_TAB)
392 ,current_function_name, current_function_name);
398 fprintf (file, AS1 (jmp,__prologue_saves__+%d) "\n",
399 (18 - live_seq) * 2);
404 fprintf (file, AS1 (rjmp,__prologue_saves__+%d) "\n",
405 (18 - live_seq) * 2);
408 fprintf (file, ".L_%s_body:\n", current_function_name);
412 for (reg = 0; reg < 32; ++reg)
415 && (call_used_regs[reg]
416 && (interrupt_func_p || signal_func_p)
417 && !(reg == TMP_REGNO || reg == ZERO_REGNO)))
418 || (regs_ever_live[reg]
419 && (!call_used_regs[reg]
420 || interrupt_func_p || signal_func_p)
421 && ! (frame_pointer_needed
422 && (reg == REG_Y || reg == (REG_Y+1)))))
424 fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
428 if (frame_pointer_needed)
432 AS1 (push,r28) CR_TAB
433 AS1 (push,r29) CR_TAB
434 AS2 (in,r28,__SP_L__) CR_TAB
435 AS2 (in,r29,__SP_H__) "\n");
442 AS2 (subi,r28,%d) CR_TAB
443 AS2 (sbci,r29,%d) CR_TAB)
444 , size & 0xff, size / 0x100);
449 fprintf (file, "\t" AS2 (sbiw,r28,%d) CR_TAB, size);
452 if (interrupt_func_p)
456 AS2 (out,__SP_L__,r28) CR_TAB
458 AS2 (out,__SP_H__,r29) "\n");
461 else if (signal_func_p || TARGET_NO_INTERRUPTS)
464 AS2 (out,__SP_L__,r28) CR_TAB
465 AS2 (out,__SP_H__,r29) "\n");
471 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
473 AS2 (out,__SP_L__,r28) CR_TAB
474 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
475 AS2 (out,__SP_H__,r29) "\n");
482 fprintf (file, "/* prologue end (size=%d) */\n", prologue_size);
485 /* Output function epilogue */
488 function_epilogue (FILE *file, int size)
491 int interrupt_func_p;
499 if (avr_naked_function_p (current_function_decl))
501 fprintf (file, "/* epilogue: naked */\n");
505 interrupt_func_p = interrupt_function_p (current_function_decl);
506 signal_func_p = signal_function_p (current_function_decl);
507 leaf_func_p = leaf_function_p ();
508 main_p = ! strcmp ("main", current_function_name);
509 function_size = (insn_addresses[INSN_UID (get_last_insn ())]
510 - insn_addresses[INSN_UID (get_insns ())]);
511 live_seq = sequent_regs_live ();
512 minimize = (TARGET_CALL_PROLOGUES
513 && !interrupt_func_p && !signal_func_p && live_seq);
516 fprintf (file, "/* epilogue: frame size=%d */\n", size);
519 fprintf (file, "__stop_progIi__:\n\trjmp __stop_progIi__\n");
522 else if (minimize && (frame_pointer_needed || live_seq > 4))
524 fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
526 if (frame_pointer_needed)
532 fprintf (file, AS2 (subi,r28,lo8(-%d)) CR_TAB, size);
533 fprintf (file, AS2 (sbci,r29,hi8(-%d)) CR_TAB, size);
538 fprintf (file, AS2 (adiw,r28,%d) CR_TAB, size);
545 fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
546 AS2 (in , r29, __SP_H__) CR_TAB));
552 fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
553 (18 - live_seq) * 2);
558 fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
559 (18 - live_seq) * 2);
565 if (frame_pointer_needed)
571 fprintf (file, "\t" AS2 (subi,r28,lo8(-%d)) CR_TAB, size);
572 fprintf (file, AS2 (sbci,r29,hi8(-%d)) CR_TAB, size);
577 fprintf (file, "\t" AS2 (adiw,r28,%d) CR_TAB, size);
580 if (interrupt_func_p | signal_func_p)
584 AS2 (out,__SP_L__,r28) CR_TAB
585 AS2 (out,__SP_H__,r29) "\n");
588 else if (TARGET_NO_INTERRUPTS)
591 AS2 (out,__SP_L__,r28) CR_TAB
592 AS2 (out,__SP_H__,r29) "\n");
598 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
600 AS2 (out,__SP_L__,r28) CR_TAB
601 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
602 AS2 (out,__SP_H__,r29) "\n");
612 for (reg = 31; reg >= 0; --reg)
615 && (call_used_regs[reg]
616 && (interrupt_func_p || signal_func_p)
617 && !(reg == TMP_REGNO || reg == ZERO_REGNO)))
618 || (regs_ever_live[reg]
619 && (!call_used_regs[reg]
620 || interrupt_func_p || signal_func_p)
621 && ! (frame_pointer_needed
622 && (reg == REG_Y || reg == (REG_Y+1)))))
624 fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
629 if (interrupt_func_p | signal_func_p)
632 AS1 (pop,__tmp_reg__) CR_TAB
633 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
634 AS1 (pop,__tmp_reg__) CR_TAB
635 AS1 (pop,__zero_reg__) "\n");
637 fprintf (file, "\treti\n");
640 fprintf (file, "\tret\n");
644 fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
645 fprintf (file, "/* function %s size %d (%d) */\n", current_function_name,
646 prologue_size + function_size + epilogue_size, function_size);
647 commands_in_file += prologue_size + function_size + epilogue_size;
648 commands_in_prologues += prologue_size;
649 commands_in_epilogues += epilogue_size;
653 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
654 machine for a memory operand of mode MODE. */
657 legitimate_address_p (mode, x, strict)
658 enum machine_mode mode;
663 if (TARGET_ALL_DEBUG)
665 fprintf (stderr, "mode: (%s) %s %s %s %s:",
667 strict ? "(strict)": "",
668 reload_completed ? "(reload_completed)": "",
669 reload_in_progress ? "(reload_in_progress)": "",
670 reg_renumber ? "(reg_renumber)" : "");
671 if (GET_CODE (x) == PLUS
672 && REG_P (XEXP (x, 0))
673 && GET_CODE (XEXP (x, 1)) == CONST_INT
674 && INTVAL (XEXP (x, 1)) >= 0
675 && INTVAL (XEXP (x, 1)) <= (64 - GET_MODE_SIZE (mode))
678 fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
679 true_regnum (XEXP (x, 0)));
682 if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
683 : REG_OK_FOR_BASE_NOSTRICT_P (x)))
685 else if (CONSTANT_ADDRESS_P (x))
687 else if (GET_CODE (x) == PLUS
688 && REG_P (XEXP (x, 0))
689 && GET_CODE (XEXP (x, 1)) == CONST_INT
690 && INTVAL (XEXP (x, 1)) >= 0)
692 int fit = INTVAL (XEXP (x, 1)) <= (64 - GET_MODE_SIZE (mode));
696 || REGNO (XEXP (x,0)) == REG_Y || REGNO (XEXP (x,0)) == REG_Z)
698 if (XEXP (x,0) == frame_pointer_rtx
699 || XEXP (x,0) == arg_pointer_rtx)
702 else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
705 else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
706 && REG_P (XEXP (x, 0))
707 && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
708 : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
712 if (TARGET_ALL_DEBUG)
714 fprintf (stderr, " ret = %c\n", r);
719 /* Attempts to replace X with a valid
720 memory address for an operand of mode MODE */
723 legitimize_address (x, oldx, mode)
726 enum machine_mode mode;
729 if (TARGET_ALL_DEBUG)
731 fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
735 if (GET_CODE (oldx) == PLUS
736 && REG_P (XEXP (oldx,0)))
738 if (REG_P (XEXP (oldx,1)))
739 x = force_reg (GET_MODE (oldx), oldx);
740 else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
742 int offs = INTVAL (XEXP (oldx,1));
743 if (frame_pointer_rtx != XEXP (oldx,0))
744 if (offs > 64 - GET_MODE_SIZE (mode))
746 if (TARGET_ALL_DEBUG)
747 fprintf (stderr, "force_reg (big offset)\n");
748 x = force_reg (GET_MODE (oldx), oldx);
756 /* Return a pointer register name as a string */
759 ptrreg_to_str (regno)
764 case REG_X: return "X";
765 case REG_Y: return "Y";
766 case REG_Z: return "Z";
768 fatal ("register r%d isn't a pointer\n", regno);
773 /* Return the condition name as a string.
774 Used in conditional jump constructing */
787 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
792 fatal ("Internal compiler bug: command `bgt'");
794 fatal ("Internal compiler bug: command `ble'");
796 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
803 fatal ("Internal compiler bug: command `bgtu'");
805 fatal ("Internal compiler bug: command `bleu'");
813 /* Output ADDR to FILE as address */
816 print_operand_address (file, addr)
820 switch (GET_CODE (addr))
823 fprintf (file, ptrreg_to_str (REGNO (addr)));
827 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
831 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
835 if (CONSTANT_ADDRESS_P (addr)
836 && (SYMBOL_REF_FLAG (addr) || GET_CODE (addr) == LABEL_REF))
838 fprintf (file, "pm(");
839 output_addr_const (file,addr);
843 output_addr_const (file, addr);
848 /* Output X as assembler operand to file FILE */
851 print_operand (file, x, code)
858 if (code >= 'A' && code <= 'D')
863 if (x == zero_reg_rtx)
864 fprintf (file,"__zero_reg__");
866 fprintf (file, reg_names[true_regnum (x) + abcd]);
868 else if (GET_CODE (x) == CONST_INT)
869 fprintf (file, "%d", INTVAL (x) + abcd);
870 else if (GET_CODE (x) == MEM)
872 rtx addr = XEXP (x,0);
875 if (CONSTANT_P (addr))
877 else if (GET_CODE (addr) == PLUS)
880 else if (CONSTANT_P (addr) && abcd)
883 output_address (addr);
884 fprintf (file, ")+%d", abcd);
886 else if (GET_CODE (addr) == PLUS)
888 print_operand_address (file, XEXP (addr,0));
889 if (REGNO (XEXP (addr, 0)) == REG_X)
890 fatal_insn ("Internal compiler bug.\nBad address:"
893 print_operand (file, XEXP (addr,1), code);
896 print_operand_address (file, addr);
898 else if (GET_CODE (x) == CONST_DOUBLE)
902 if (GET_MODE (x) != SFmode)
903 fatal_insn ("Internal compiler bug. Unknown mode:", x);
904 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
905 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
906 asm_fprintf (file, "0x%x", val);
908 else if (code == 'j')
909 asm_fprintf (file, cond_string (GET_CODE (x)));
910 else if (code == 'k')
911 asm_fprintf (file, cond_string (reverse_condition (GET_CODE (x))));
913 print_operand_address (file, x);
916 /* Recognise operand OP of mode MODE used in call instructions */
919 call_insn_operand (op, mode)
921 enum machine_mode mode ATTRIBUTE_UNUSED;
923 if (GET_CODE (op) == MEM)
925 rtx inside = XEXP (op, 0);
926 if (register_operand (inside, Pmode))
928 if (CONSTANT_ADDRESS_P (inside))
934 /* Update the condition code in the INSN. */
937 notice_update_cc (body, insn)
938 rtx body ATTRIBUTE_UNUSED;
941 switch (get_attr_cc (insn))
944 /* Insn does not affect CC at all. */
953 rtx set = single_set (insn);
957 cc_status.flags |= CC_NO_OVERFLOW;
958 cc_status.value1 = SET_DEST (set);
964 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
965 The V flag may or may not be known but that's ok because
966 alter_cond will change tests to use EQ/NE. */
968 rtx set = single_set (insn);
972 cc_status.value1 = SET_DEST (set);
973 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
980 rtx set = single_set (insn);
983 cc_status.value1 = SET_SRC (set);
988 /* Insn doesn't leave CC in a usable state. */
994 /* Return maximum number of consecutive registers of
995 class CLASS needed to hold a value of mode MODE. */
998 class_max_nregs (class, mode)
999 enum reg_class class ATTRIBUTE_UNUSED;
1000 enum machine_mode mode;
1002 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1005 /* Choose mode for jump insn:
1006 1 - relative jump in range -63 <= x <= 62 ;
1007 2 - relative jump in range -2046 <= x <= 2045 ;
1008 3 - absolute jump (only for ATmega[16]03). */
1011 avr_jump_mode (x,insn)
1012 rtx x; /* jump operand */
1013 rtx insn; /* jump insn */
1015 int dest_addr = insn_addresses[INSN_UID (GET_MODE (x) == LABEL_REF
1016 ? XEXP (x, 0) : x)];
1017 int cur_addr = insn_addresses[INSN_UID (insn)];
1018 int jump_distance = cur_addr - dest_addr;
1020 if (-63 <= jump_distance && jump_distance <= 62)
1022 else if (-2046 <= jump_distance && jump_distance <= 2045)
1030 /* return a AVR condition jump commands.
1031 LEN is a number returned by avr_jump_mode function. */
1034 ret_cond_branch (cond,len)
1041 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1042 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1044 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1045 AS1 (brmi,_PC_+2) CR_TAB
1047 (AS1 (breq,_PC_+6) CR_TAB
1048 AS1 (brmi,_PC_+4) CR_TAB
1052 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1054 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1055 AS1 (brlt,_PC_+2) CR_TAB
1057 (AS1 (breq,_PC_+6) CR_TAB
1058 AS1 (brlt,_PC_+4) CR_TAB
1061 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1063 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1064 AS1 (brlo,_PC_+2) CR_TAB
1066 (AS1 (breq,_PC_+6) CR_TAB
1067 AS1 (brlo,_PC_+4) CR_TAB
1070 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1071 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1073 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1074 AS1 (brpl,_PC_+2) CR_TAB
1076 (AS1 (breq,_PC_+2) CR_TAB
1077 AS1 (brpl,_PC_+4) CR_TAB
1080 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1082 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1083 AS1 (brge,_PC_+2) CR_TAB
1085 (AS1 (breq,_PC_+2) CR_TAB
1086 AS1 (brge,_PC_+4) CR_TAB
1089 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1091 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1092 AS1 (brsh,_PC_+2) CR_TAB
1094 (AS1 (breq,_PC_+2) CR_TAB
1095 AS1 (brsh,_PC_+4) CR_TAB
1101 return AS1 (br%j1,%0);
1103 return (AS1 (br%k1,_PC_+2) CR_TAB
1106 return (AS1 (br%k1,_PC_+4) CR_TAB
1113 /* Predicate function for immediate operand which fits to byte (8bit) */
1116 byte_immediate_operand (op, mode)
1118 enum machine_mode mode ATTRIBUTE_UNUSED;
1120 return (GET_CODE (op) == CONST_INT
1121 && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1124 /* Output all insn addresses and their sizes into the assembly language
1125 output file. This is helpful for debugging whether the length attributes
1126 in the md file are correct.
1127 Output insn cost for next insn. */
1130 final_prescan_insn (insn, operand, num_operands)
1131 rtx insn, *operand ATTRIBUTE_UNUSED;
1132 int num_operands ATTRIBUTE_UNUSED;
1134 int uid = INSN_UID (insn);
1136 if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1138 fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n", insn_addresses[uid],
1139 insn_addresses[uid] - last_insn_address,
1140 rtx_cost (PATTERN (insn),INSN));
1142 last_insn_address = insn_addresses[uid];
1144 if (TARGET_RTL_DUMP)
1146 fprintf (asm_out_file, "/*****************\n");
1147 print_rtl_single (asm_out_file, insn);
1148 fprintf (asm_out_file, "*****************/\n");
1152 /* return 1 if undefined,
1153 1 if always true or always false */
1156 avr_simplify_comparision_p (mode, operator, x)
1157 enum machine_mode mode;
1161 unsigned int max = (mode == QImode ? 0xff :
1162 mode == HImode ? 0xffff :
1163 mode == SImode ? 0xffffffffU : 0);
1164 if (max && operator && GET_CODE (x) == CONST_INT)
1166 if (unsigned_condition (operator) != operator)
1169 if (max != (INTVAL (x) & max)
1170 && INTVAL (x) != 0xff)
1177 /* Returns nonzero if REGNO is the number of a hard
1178 register in which function arguments are sometimes passed. */
1181 function_arg_regno_p(r)
1184 return (r >= 8 && r <= 25);
1187 /* Initializing the variable cum for the state at the beginning
1188 of the argument list. */
1191 init_cumulative_args (cum, fntype, libname, indirect)
1192 CUMULATIVE_ARGS *cum;
1195 int indirect ATTRIBUTE_UNUSED;
1198 cum->regno = FIRST_CUM_REG;
1201 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1202 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1203 != void_type_node));
1209 /* Controls whether a function argument is passed
1210 in a register, and which register. */
1213 function_arg (cum, mode, type, named)
1214 CUMULATIVE_ARGS *cum;
1215 enum machine_mode mode;
1217 int named ATTRIBUTE_UNUSED;
1221 bytes = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
1223 if (cum->nregs && bytes <= cum->nregs)
1224 return gen_rtx (REG, mode, cum->regno - bytes);
1228 /* Update the summarizer variable CUM to advance past an argument
1229 in the argument list. */
1232 function_arg_advance (cum, mode, type, named)
1233 CUMULATIVE_ARGS *cum; /* current arg information */
1234 enum machine_mode mode; /* current arg mode */
1235 tree type; /* type of the argument or 0 if lib support */
1236 int named ATTRIBUTE_UNUSED; /* whether or not the argument was named */
1240 bytes = (mode == BLKmode ? int_size_in_bytes (type) : GET_MODE_SIZE (mode));
1241 cum->nregs -= bytes;
1242 cum->regno -= bytes;
1244 if (cum->nregs <= 0)
1247 cum->regno = FIRST_CUM_REG;
1253 /***********************************************************************
1254 Functions for outputting various mov's for a various modes
1255 ************************************************************************/
1257 out_movqi_r_mr (insn, op, l)
1260 int *l; /* instruction length */
1262 /* We handle CONSTANT_ADDRESS_P case in adjust_insn_length */
1264 if (GET_CODE (op[1]) == MEM)
1266 rtx x = XEXP (op[1],0);
1267 if (GET_CODE (x) == PLUS
1268 && REG_P (XEXP (x,0))
1269 && GET_CODE (XEXP (x,1)) == CONST_INT)
1271 if((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (op[1]))) >= 63)
1273 int disp = INTVAL (XEXP (x,1));
1274 if (REGNO (XEXP (x,0)) != REG_Y)
1275 fatal_insn ("Incorrect insn:",insn);
1276 if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[1])))
1282 op[4] = GEN_INT (disp - 63);
1283 return (AS2 (adiw, r28, %4) CR_TAB
1284 AS2 (ldd, %0,Y+63) CR_TAB
1285 AS2 (sbiw, r28, %4));
1294 return (AS2 (subi, r28, lo8(-%4)) CR_TAB
1295 AS2 (sbci, r29, hi8(-%4)) CR_TAB
1296 AS2 (ld, %0,Y) CR_TAB
1297 AS2 (subi, r28, lo8(%4)) CR_TAB
1298 AS2 (sbci, r29, hi8(%4)));
1301 else if (REGNO (XEXP (x,0)) == REG_X)
1303 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1304 it but I have this situation with extremal optimizing options
1310 output_asm_insn (AS2 (adiw, r26, %0),&XEXP (x,1));
1311 output_asm_insn (AS2 (ld ,%0,X),op);
1312 if (!reg_overlap_mentioned_p (op[0],XEXP (x,0)))
1313 output_asm_insn (AS2 (sbiw, r26, %0),&XEXP (x,1));
1319 return AS2 (ld%K1,%0,%1);
1323 out_movhi_r_mr (insn, op, l)
1326 int *l; /* instruction length */
1328 int reg_dest = true_regnum (op[0]);
1329 int reg_base = true_regnum (XEXP (op[1],0));
1334 l = &tmp, len_p = 0;
1338 if (reg_dest == reg_base) /* R = (R) */
1339 return *l=3, (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1340 AS2 (ld,%B0,%1) CR_TAB
1341 AS2 (mov,%A0,__tmp_reg__));
1342 else if (reg_base == REG_X) /* (R26) */
1344 if (reg_unused_after (insn, XEXP (op[1],0)))
1345 return *l=2, (AS2 (ld,%A0,X+) CR_TAB
1348 return *l=3, (AS2 (ld,%A0,X+) CR_TAB
1349 AS2 (ld,%B0,X) CR_TAB
1353 return *l=2, (AS2 (ld,%A0,%1) CR_TAB
1354 AS2 (ldd,%B0,%1+1));
1356 else if (GET_CODE (XEXP (op[1],0)) == PLUS) /* (R + i) */
1358 int disp = INTVAL(XEXP (XEXP (op[1],0), 1));
1359 int reg_base = true_regnum (XEXP (XEXP (op[1],0), 0));
1361 if (disp > 64 - GET_MODE_SIZE (GET_MODE (op[1])))
1363 rtx x = XEXP (op[1],0);
1364 if (REGNO (XEXP (x,0)) != REG_Y)
1365 fatal_insn ("Incorrect insn:",insn);
1366 if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[1])))
1368 op[4] = GEN_INT (disp - 62);
1369 return *l=4, (AS2 (adiw, r28, %4) CR_TAB
1370 AS2 (ldd, %A0,Y+62) CR_TAB
1371 AS2 (ldd, %B0,Y+63) CR_TAB
1372 AS2 (sbiw, r28, %4));
1377 return *l=6, (AS2 (subi, r28, lo8(-%4)) CR_TAB
1378 AS2 (sbci, r29, hi8(-%4)) CR_TAB
1379 AS2 (ld, %A0,Y) CR_TAB
1380 AS2 (ldd, %B0,Y+1) CR_TAB
1381 AS2 (subi, r28, lo8(%4)) CR_TAB
1382 AS2 (sbci, r29, hi8(%4)));
1385 if (reg_base == REG_X)
1387 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1388 it but I have this situation with extremal optimization options
1391 ops[0] = XEXP (XEXP (op[1],0), 1);
1394 else if (reg_base == reg_dest)
1396 output_asm_insn (AS2 (adiw, r26, %0), ops);
1397 output_asm_insn (AS2 (ld , __tmp_reg__, X+), op);
1398 output_asm_insn (AS2 (ld , %B0, X), op);
1399 output_asm_insn (AS2 (mov, %A0, __tmp_reg__),op);
1403 output_asm_insn (AS2 (adiw, r26, %0), ops);
1404 output_asm_insn (AS2 (ld , %A0, X+), op);
1405 output_asm_insn (AS2 (ld , %B0, X), op);
1406 if (INTVAL (ops[0]) == 63)
1408 output_asm_insn (AS2 (subi, r26, %0+1), ops);
1409 output_asm_insn (AS2 (sbci, r26, 0), ops);
1412 output_asm_insn (AS2 (sbiw, r26, %0+1), ops);
1417 if (reg_base == reg_dest)
1418 return *l=3, (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
1419 AS2 (ldd,%B0,%B1) CR_TAB
1420 AS2 (mov,%A0,__tmp_reg__));
1422 return *l=2, (AS2 (ldd,%A0,%A1) CR_TAB
1425 else if (GET_CODE (XEXP (op[1],0)) == PRE_DEC) /* (--R) */
1427 if (reg_overlap_mentioned_p (op[0], XEXP (XEXP (op[1],0),0)))
1430 fatal ("Internal error. Incorrect insn.");
1432 return *l=2, (AS2 (ld,%B0,%1) CR_TAB
1435 else if (GET_CODE (XEXP (op[1],0)) == POST_INC) /* (R++) */
1437 if (reg_overlap_mentioned_p (op[0], XEXP (XEXP (op[1],0),0)))
1440 fatal ("Internal error. Incorrect insn.");
1442 return *l=2, (AS2 (ld,%A0,%1) CR_TAB
1445 else if (CONSTANT_ADDRESS_P (XEXP (op[1],0)))
1446 return *l=4, (AS2 (lds,%A0,%A1) CR_TAB
1448 fatal_insn ("Unknown move insn:",insn);
1453 out_movsi_r_mr (insn,op,l)
1456 int *l; /* instruction length */
1458 int reg_dest=true_regnum (op[0]);
1459 int reg_base=true_regnum (XEXP (op[1],0));
1465 if (reg_base == REG_X) /* (R26) */
1467 if (reg_dest == REG_X)
1468 return *l=6, (AS2 (adiw,r26,3) CR_TAB
1469 AS2 (ld,%D0,X) CR_TAB
1470 AS2 (ld,%C0,-X) CR_TAB
1471 AS2 (ld,__tmp_reg__,-X) CR_TAB
1472 AS2 (ld,%A0,-X) CR_TAB
1473 AS2 (mov,%B0,__tmp_reg__));
1474 else if (reg_dest == REG_X - 2)
1475 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
1476 AS2 (ld,%B0,X+) CR_TAB
1477 AS2 (ld,__tmp_reg__,X+) CR_TAB
1478 AS2 (ld,%D0,X) CR_TAB
1479 AS2 (mov,%C0,__tmp_reg__));
1480 else if (reg_unused_after (insn,XEXP (op[1],0)))
1481 return *l=4, (AS2 (ld,%A0,X+) CR_TAB
1482 AS2 (ld,%B0,X+) CR_TAB
1483 AS2 (ld,%C0,X+) CR_TAB
1486 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
1487 AS2 (ld,%B0,X+) CR_TAB
1488 AS2 (ld,%C0,X+) CR_TAB
1489 AS2 (ld,%D0,X) CR_TAB
1494 if (reg_dest == reg_base)
1495 return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
1496 AS2 (ldd,%C0,%1+2) CR_TAB
1497 AS2 (ldd,__tmp_reg__,%1+1) CR_TAB
1498 AS2 (ld,%A0,%1) CR_TAB
1499 AS2 (mov,%B0,__tmp_reg__));
1500 else if (reg_base == reg_dest + 2)
1501 return *l=5, (AS2 (ld ,%A0,%1) CR_TAB
1502 AS2 (ldd,%B0,%1+1) CR_TAB
1503 AS2 (ldd,__tmp_reg__,%1+2) CR_TAB
1504 AS2 (ldd,%D0,%1+3) CR_TAB
1505 AS2 (mov,%C0,__tmp_reg__));
1507 return *l=4, (AS2 (ld ,%A0,%1) CR_TAB
1508 AS2 (ldd,%B0,%1+1) CR_TAB
1509 AS2 (ldd,%C0,%1+2) CR_TAB
1510 AS2 (ldd,%D0,%1+3));
1513 else if (GET_CODE (XEXP (op[1],0)) == PLUS) /* (R + i) */
1515 int disp = INTVAL(XEXP (XEXP (op[1],0), 1));
1517 if (disp > 64 - GET_MODE_SIZE (GET_MODE (op[1])))
1519 rtx x = XEXP (op[1],0);
1520 if (REGNO (XEXP (x,0)) != REG_Y)
1521 fatal_insn ("Incorrect insn:",insn);
1522 if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[1])))
1524 op[4] = GEN_INT (disp - 60);
1525 return *l=6,(AS2 (adiw, r28, %4) CR_TAB
1526 AS2 (ldd, %A0,Y+60) CR_TAB
1527 AS2 (ldd, %B0,Y+61) CR_TAB
1528 AS2 (ldd, %C0,Y+62) CR_TAB
1529 AS2 (ldd, %D0,Y+63) CR_TAB
1530 AS2 (sbiw, r28, %4));
1535 return *l=8,(AS2 (subi, r28, lo8(-%4)) CR_TAB
1536 AS2 (sbci, r29, hi8(-%4)) CR_TAB
1537 AS2 (ld, %A0,Y) CR_TAB
1538 AS2 (ldd, %B0,Y+1) CR_TAB
1539 AS2 (ldd, %C0,Y+2) CR_TAB
1540 AS2 (ldd, %D0,Y+3) CR_TAB
1541 AS2 (subi, r28, lo8(%4)) CR_TAB
1542 AS2 (sbci, r29, hi8(%4)));
1546 reg_base = true_regnum (XEXP (XEXP (op[1],0), 0));
1547 if (reg_dest == reg_base)
1548 return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
1549 AS2 (ldd,%C0,%C1) CR_TAB
1550 AS2 (ldd,__tmp_reg__,%B1) CR_TAB
1551 AS2 (ldd,%A0,%A1) CR_TAB
1552 AS2 (mov,%B0,__tmp_reg__));
1553 else if (reg_dest == reg_base - 2)
1554 return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
1555 AS2 (ldd,%B0,%B1) CR_TAB
1556 AS2 (ldd,__tmp_reg__,%C1) CR_TAB
1557 AS2 (ldd,%D0,%D1) CR_TAB
1558 AS2 (mov,%C0,__tmp_reg__));
1559 return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
1560 AS2 (ldd,%B0,%B1) CR_TAB
1561 AS2 (ldd,%C0,%C1) CR_TAB
1564 else if (GET_CODE (XEXP (op[1],0)) == PRE_DEC) /* (--R) */
1565 return *l=4, (AS2 (ld,%D0,%1) CR_TAB
1566 AS2 (ld,%C0,%1) CR_TAB
1567 AS2 (ld,%B0,%1) CR_TAB
1569 else if (GET_CODE (XEXP (op[1],0)) == POST_INC) /* (R++) */
1570 return *l=4, (AS2 (ld,%A0,%1) CR_TAB
1571 AS2 (ld,%B0,%1) CR_TAB
1572 AS2 (ld,%C0,%1) CR_TAB
1574 else if (CONSTANT_ADDRESS_P (XEXP (op[1],0)))
1575 return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
1576 AS2 (lds,%B0,%B1) CR_TAB
1577 AS2 (lds,%C0,%C1) CR_TAB
1580 fatal_insn ("Unknown move insn:",insn);
1585 out_movsi_mr_r (insn,op,l)
1590 int reg_base = true_regnum (XEXP (op[0],0));
1591 int reg_dest = true_regnum (op[1]);
1595 if (CONSTANT_ADDRESS_P (XEXP (op[0],0)))
1596 return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
1597 AS2 (sts,%B0,%B1) CR_TAB
1598 AS2 (sts,%C0,%C1) CR_TAB
1600 if (reg_base > 0) /* (r) */
1602 if (reg_base == REG_X) /* (R26) */
1604 if (reg_dest == REG_X)
1606 if (reg_unused_after (insn,XEXP (op[0],0)))
1607 return *l=5, (AS2 (mov,__tmp_reg__,%B1) CR_TAB
1608 AS2 (st,%0+,%A1) CR_TAB
1609 AS2 (st,%0+,__tmp_reg__) CR_TAB
1610 AS2 (st,%0+,%C1) CR_TAB
1613 return *l=6, (AS2 (mov,__tmp_reg__,%B1) CR_TAB
1614 AS2 (st,%0+,%A1) CR_TAB
1615 AS2 (st,%0+,__tmp_reg__) CR_TAB
1616 AS2 (st,%0+,%C1) CR_TAB
1617 AS2 (st,%0,%D1) CR_TAB
1620 else if (reg_base == reg_dest+2)
1622 if (reg_unused_after (insn,XEXP (op[0],0)))
1623 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
1624 AS2 (mov,__tmp_reg__,%D1) CR_TAB
1625 AS2 (st,%0+,%A1) CR_TAB
1626 AS2 (st,%0+,%B1) CR_TAB
1627 AS2 (st,%0+,__zero_reg__) CR_TAB
1628 AS2 (st,%0,__tmp_reg__) CR_TAB
1629 AS1 (clr,__zero_reg__));
1631 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
1632 AS2 (mov,__tmp_reg__,%D1) CR_TAB
1633 AS2 (st,%0+,%A1) CR_TAB
1634 AS2 (st,%0+,%B1) CR_TAB
1635 AS2 (st,%0+,__zero_reg__) CR_TAB
1636 AS2 (st,%0,__tmp_reg__) CR_TAB
1637 AS1 (clr,__zero_reg__) CR_TAB
1640 return *l=5, (AS2 (st,%0+,%A1) CR_TAB
1641 AS2 (st,%0+,%B1) CR_TAB
1642 AS2 (st,%0+,%C1) CR_TAB
1643 AS2 (st,%0,%D1) CR_TAB
1647 return *l=4, (AS2 (st,%0,%A1) CR_TAB
1648 AS2 (std,%0+1,%B1) CR_TAB
1649 AS2 (std,%0+2,%C1) CR_TAB
1650 AS2 (std,%0+3,%D1));
1652 else if (GET_CODE (XEXP (op[0],0)) == PLUS) /* (R + i) */
1654 int disp = INTVAL(XEXP (XEXP (op[0],0), 1));
1655 if (disp > 64 - GET_MODE_SIZE (GET_MODE (op[0])))
1657 rtx x = XEXP (op[0],0);
1658 if (REGNO (XEXP (x,0)) != REG_Y)
1659 fatal_insn ("Incorrect insn:",insn);
1660 if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[0])))
1662 op[4] = GEN_INT (disp - 60);
1663 return *l=6,(AS2 (adiw, r28, %4) CR_TAB
1664 AS2 (std, Y+60,%A1) CR_TAB
1665 AS2 (std, Y+61,%B1) CR_TAB
1666 AS2 (std, Y+62,%C1) CR_TAB
1667 AS2 (std, Y+63,%D1) CR_TAB
1668 AS2 (sbiw, r28, %4));
1673 return *l=8,(AS2 (subi, r28, lo8(-%4)) CR_TAB
1674 AS2 (sbci, r29, hi8(-%4)) CR_TAB
1675 AS2 (st, Y,%A1) CR_TAB
1676 AS2 (std, Y+1,%B1) CR_TAB
1677 AS2 (std, Y+2,%C1) CR_TAB
1678 AS2 (std, Y+3,%D1) CR_TAB
1679 AS2 (subi, r28, lo8(%4)) CR_TAB
1680 AS2 (sbci, r29, hi8(%4)));
1683 return *l=4, (AS2 (std,%A0,%A1) CR_TAB
1684 AS2 (std,%B0,%B1) CR_TAB
1685 AS2 (std,%C0,%C1) CR_TAB
1688 else if (GET_CODE (XEXP (op[0],0)) == PRE_DEC) /* (--R) */
1689 return *l=4, (AS2 (st,%0,%D1) CR_TAB
1690 AS2 (st,%0,%C1) CR_TAB
1691 AS2 (st,%0,%B1) CR_TAB
1693 else if (GET_CODE (XEXP (op[0],0)) == POST_INC) /* (R++) */
1694 return *l=4, (AS2 (st,%0,%A1) CR_TAB
1695 AS2 (st,%0,%B1) CR_TAB
1696 AS2 (st,%0,%C1) CR_TAB
1698 fatal_insn ("Unknown move insn:",insn);
1703 output_movsisf(insn, operands, which_alternative)
1706 int which_alternative;
1709 switch (which_alternative)
1711 case 0: /* mov r,r */
1712 if (true_regnum (operands[0]) > true_regnum (operands[1]))
1713 return (AS2 (mov,%D0,%D1) CR_TAB
1714 AS2 (mov,%C0,%C1) CR_TAB
1715 AS2 (mov,%B0,%B1) CR_TAB
1718 return (AS2 (mov,%A0,%A1) CR_TAB
1719 AS2 (mov,%B0,%B1) CR_TAB
1720 AS2 (mov,%C0,%C1) CR_TAB
1722 case 1: /* mov r,L */
1723 return (AS1 (clr,%A0) CR_TAB
1724 AS1 (clr,%B0) CR_TAB
1725 AS1 (clr,%C0) CR_TAB
1727 case 2: /* mov r,d */
1728 if (GET_MODE (operands[0]) == SImode
1729 && operands[1] == const1_rtx
1730 && (link = find_reg_note (insn, REG_WAS_0, 0))
1731 /* Make sure the insn that stored the 0 is still present. */
1732 && ! INSN_DELETED_P (XEXP (link, 0))
1733 && GET_CODE (XEXP (link, 0)) != NOTE
1734 /* Make sure cross jumping didn't happen here. */
1735 && no_labels_between_p (XEXP (link, 0), insn)
1736 /* Make sure the reg hasn't been clobbered. */
1737 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1738 /* Fastest way to change a 0 to a 1. */
1739 return AS1 (inc,%A0 ; reg_was_0);
1740 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1741 AS2 (ldi,%B0,hi8(%1)) CR_TAB
1742 AS2 (ldi,%C0,hlo8(%1)) CR_TAB
1743 AS2 (ldi,%D0,hhi8(%1)));
1744 case 3: /* mov r,m*/
1746 return out_movsi_r_mr (insn, operands, NULL);
1747 case 4: /* mov m,r*/
1751 if (operands[1] == const0_rtx)
1753 save1 = operands[1];
1754 operands[1] = zero_reg_rtx;
1756 output_asm_insn (out_movsi_mr_r (insn,operands,NULL), operands);
1758 operands[1] = save1;
1765 out_movqi_mr_r (insn, op, l)
1768 int *l; /* instruction length */
1772 if (GET_CODE (op[0]) == MEM)
1774 rtx x = XEXP (op[0],0);
1775 if (GET_CODE (x) == PLUS
1776 && REG_P (XEXP (x,0))
1777 && GET_CODE (XEXP (x,1)) == CONST_INT)
1779 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (op[0]))) >= 63)
1781 int disp = INTVAL (XEXP (x,1));
1782 if (REGNO (XEXP (x,0)) != REG_Y)
1783 fatal_insn ("Incorrect insn:",insn);
1784 if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[0])))
1790 op[4] = GEN_INT (disp - 63);
1791 return (AS2 (adiw, r28, %4) CR_TAB
1792 AS2 (std, Y+63,%1) CR_TAB
1793 AS2 (sbiw, r28, %4));
1802 return (AS2 (subi, r28, lo8(-%4)) CR_TAB
1803 AS2 (sbci, r29, hi8(-%4)) CR_TAB
1804 AS2 (st, Y,%1) CR_TAB
1805 AS2 (subi, r28, lo8(%4)) CR_TAB
1806 AS2 (sbci, r29, hi8(%4)));
1809 else if (REGNO (XEXP (x,0)) == REG_X)
1815 int overlap_p = reg_overlap_mentioned_p (op[1],XEXP (x,0));
1817 output_asm_insn (AS2 (mov, __tmp_reg__, %1),op);
1818 output_asm_insn (AS2 (adiw, r26,%0),&XEXP (x,1));
1820 output_asm_insn (AS2 (st ,X,__tmp_reg__),op);
1822 output_asm_insn (AS2 (st ,X,%1),op);
1823 output_asm_insn (AS2 (sbiw ,r26,%0),&XEXP (x,1));
1829 return AS2 (st%K0, %0,%1);
1833 out_movhi_mr_r (insn,op,l)
1838 int reg_base = true_regnum (XEXP (op[0],0));
1839 int reg_dest = true_regnum (op[1]);
1843 if (CONSTANT_ADDRESS_P (XEXP (op[0],0)))
1844 return *l=4,(AS2 (sts,%A0,%A1) CR_TAB
1848 if (reg_base == REG_X)
1850 if (reg_dest == REG_X)
1852 if (reg_unused_after (insn, op[1]))
1853 return *l=3, (AS2 (mov,__tmp_reg__,r27) CR_TAB
1854 AS2 (st ,X+,r26) CR_TAB
1855 AS2 (st ,X,__tmp_reg__));
1857 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
1858 AS2 (st ,X+,r26) CR_TAB
1859 AS2 (st ,X,__tmp_reg__) CR_TAB
1864 if (reg_unused_after (insn, XEXP (op[0],0)))
1865 return *l=2, (AS2 (st,X+,%A1) CR_TAB
1868 return *l=3, (AS2 (st ,X+,%A1) CR_TAB
1869 AS2 (st ,X,%B1) CR_TAB
1874 return *l=2, (AS2 (st ,%0,%A1) CR_TAB
1875 AS2 (std,%0+1,%B1));
1877 else if (GET_CODE (XEXP (op[0],0)) == PLUS)
1879 int disp = INTVAL(XEXP (XEXP (op[0],0), 1));
1880 if (disp > 64 - GET_MODE_SIZE (GET_MODE (op[0])))
1882 rtx x = XEXP (op[0],0);
1883 if (REGNO (XEXP (x,0)) != REG_Y)
1884 fatal_insn ("Incorrect insn:",insn);
1885 if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[0])))
1887 op[4] = GEN_INT (disp - 62);
1888 return *l=4,(AS2 (adiw, r28, %4) CR_TAB
1889 AS2 (std, Y+62,%A1) CR_TAB
1890 AS2 (std, Y+63,%B1) CR_TAB
1891 AS2 (sbiw, r28, %4));
1896 return *l=6,(AS2 (subi, r28, lo8(-%4)) CR_TAB
1897 AS2 (sbci, r29, hi8(-%4)) CR_TAB
1898 AS2 (st, Y,%A1) CR_TAB
1899 AS2 (std, Y+1,%B1) CR_TAB
1900 AS2 (subi, r28, lo8(%4)) CR_TAB
1901 AS2 (sbci, r29, hi8(%4)));
1904 return *l=2, (AS2 (std,%A0,%A1) CR_TAB
1907 else if (GET_CODE (XEXP (op[0],0)) == PRE_DEC) /* (--R) */
1908 return *l=2, (AS2 (st,%0,%B1) CR_TAB
1910 else if (GET_CODE (XEXP (op[0],0)) == POST_INC) /* (R++) */
1911 return *l=2, (AS2 (st,%0,%A1) CR_TAB
1913 fatal_insn ("Unknown move insn:",insn);
1917 /* Return 1 if frame pointer for current function required */
1920 frame_pointer_required_p(void)
1922 return (current_function_calls_alloca
1923 || current_function_args_info.nregs == 0
1924 || current_function_varargs
1925 || get_frame_size () > 0);
1928 /* Return 1 if the next insn is a JUMP_INSN with condition (GT,LE,GTU,LTU) */
1931 compare_diff_p (insn)
1934 rtx next = next_real_insn (insn);
1935 RTX_CODE cond = UNKNOWN;
1936 if (GET_CODE (next) == JUMP_INSN)
1938 rtx pat = PATTERN (next);
1939 rtx src = SET_SRC (pat);
1940 rtx t = XEXP (src,0);
1941 cond = GET_CODE (t);
1943 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
1946 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition */
1952 rtx next = next_real_insn (insn);
1953 RTX_CODE cond = UNKNOWN;
1954 if (GET_CODE (next) == JUMP_INSN)
1956 rtx pat = PATTERN (next);
1957 rtx src = SET_SRC (pat);
1958 rtx t = XEXP (src,0);
1959 cond = GET_CODE (t);
1961 return (cond == EQ || cond == NE);
1965 /* Output test instruction for HImode */
1972 if (!compare_eq_p (insn))
1975 return AS1 (tst,%B0);
1977 if (TEST_HARD_REG_CLASS (ADDW_REGS, true_regnum (SET_SRC (PATTERN (insn)))))
1980 return AS2 (sbiw,%0,0);
1982 if (compare_eq_p (insn) && reg_unused_after (insn, SET_SRC (PATTERN (insn))))
1985 return AS2 (or,%A0,%B0);
1988 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
1989 AS2 (cpc,%B0,__zero_reg__));
1993 /* Output test instruction for SImode */
2000 if (!compare_eq_p (insn))
2003 return AS1 (tst,%D0);
2005 if (TEST_HARD_REG_CLASS (ADDW_REGS, true_regnum (SET_SRC (PATTERN (insn)))))
2008 return (AS2 (sbiw,%A0,0) CR_TAB
2009 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2010 AS2 (cpc,%D0,__zero_reg__));
2013 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2014 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2015 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2016 AS2 (cpc,%D0,__zero_reg__));
2020 /* Generate asm equivalent for various shift's.
2021 Shift count are CONST_INT or REG. */
2024 out_shift_with_cnt (template,insn,operands,len)
2033 op[0] = operands[0];
2034 op[1] = operands[1];
2035 op[2] = operands[2];
2036 op[3] = operands[3];
2039 if (CONSTANT_P (operands[2]))
2044 strcat (str, "ldi %3,lo8(%2)");
2046 else if (GET_CODE (operands[2]) == MEM)
2053 op[3] = op_mov[0] = tmp_reg_rtx;
2058 output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2059 strcat (str,(AS2 (or,%3,%3) CR_TAB
2060 AS1 (breq,L_hi%=)));
2064 out_movqi_r_mr (insn, op_mov, &mov_len);
2068 else if (register_operand (operands[2],QImode))
2074 strcat (str, (AS2 (or,%2,%2) CR_TAB
2075 AS1 (breq,L_hi%=)));
2077 if (reg_unused_after (insn, operands[2]))
2083 op[3] = tmp_reg_rtx;
2087 strcat (str, CR_TAB "mov %3,%2");
2092 strcat (str,"\n\t");
2093 strcat (str, template);
2095 strcat (str, "\nL_hi%=:");
2096 output_asm_insn (str, op);
2101 /* 8bit shift left ((char)x << i) */
2104 ashlqi3_out (insn,operands,len)
2107 int *len; /* insn length (may be NULL) */
2109 if (GET_CODE (operands[2]) == CONST_INT)
2115 switch (INTVAL (operands[2]))
2117 default: len = t; break;
2120 return AS1 (lsl,%0);
2123 return (AS1 (lsl,%0) CR_TAB
2127 return (AS1 (lsl,%0) CR_TAB
2131 if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
2134 return (AS1 (swap,%0) CR_TAB
2135 AS2 (andi,%0,0xf0));
2138 return (AS1 (lsl,%0) CR_TAB
2143 if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
2146 return (AS1 (swap,%0) CR_TAB
2148 AS2 (andi,%0,0xe0));
2151 return (AS1 (lsl,%0) CR_TAB
2157 if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
2160 return (AS1 (swap,%0) CR_TAB
2163 AS2 (andi,%0,0xc0));
2166 return (AS1 (lsl,%0) CR_TAB
2174 return (AS1 (ror,%0) CR_TAB
2181 out_shift_with_cnt (AS1 (lsl,%0) CR_TAB
2184 insn, operands, len);
2189 /* 16bit shift left ((short)x << i) */
2192 ashlhi3_out (insn,operands,len)
2197 if (GET_CODE (operands[2]) == CONST_INT)
2203 switch (INTVAL (operands[2]))
2205 default: len = t; break;
2208 return (AS1 (lsl,%A0) CR_TAB
2212 return (AS1 (lsl,%A0) CR_TAB
2213 AS1 (rol,%B0) CR_TAB
2217 if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
2218 return *len = 1, AS1 (clr,%A0);
2220 return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
2226 out_shift_with_cnt (AS1 (lsl,%0) CR_TAB
2227 AS1 (rol,%B0) CR_TAB
2230 insn, operands, len);
2235 /* 32bit shift left ((long)x << i) */
2238 ashlsi3_out (insn,operands,len)
2243 if (GET_CODE (operands[2]) == CONST_INT)
2249 switch (INTVAL (operands[2]))
2251 default: len = t; break;
2254 return (AS1 (lsl,%A0) CR_TAB
2255 AS1 (rol,%B0) CR_TAB
2256 AS1 (rol,%C0) CR_TAB
2260 int reg0 = true_regnum (operands[0]);
2261 int reg1 = true_regnum (operands[1]);
2264 return (AS2 (mov,%D0,%C1) CR_TAB
2265 AS2 (mov,%C0,%B1) CR_TAB
2266 AS2 (mov,%B0,%A1) CR_TAB
2268 else if (reg0 + 1 == reg1)
2269 return *len = 1, AS1 (clr,%A0);
2271 return (AS1 (clr,%A0) CR_TAB
2272 AS2 (mov,%B0,%A1) CR_TAB
2273 AS2 (mov,%C0,%B1) CR_TAB
2278 int reg0 = true_regnum (operands[0]);
2279 int reg1 = true_regnum (operands[1]);
2281 if (reg0 + 1 >= reg1)
2282 return (AS2 (mov,%D0,%B1) CR_TAB
2283 AS2 (mov,%C0,%A1) CR_TAB
2284 AS1 (clr,%B0) CR_TAB
2286 if (reg0 + 2 == reg1)
2287 return *len = 2, (AS1 (clr,%B0) CR_TAB
2290 return (AS2 (mov,%C0,%A1) CR_TAB
2291 AS2 (mov,%D0,%B1) CR_TAB
2292 AS1 (clr,%B0) CR_TAB
2297 if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
2298 return (AS2 (mov,%D0,%A1) CR_TAB
2299 AS1 (clr,%C0) CR_TAB
2300 AS1 (clr,%B0) CR_TAB
2303 return *len = 3, (AS1 (clr,%C0) CR_TAB
2304 AS1 (clr,%B0) CR_TAB
2310 out_shift_with_cnt (AS1 (lsl,%0) CR_TAB
2311 AS1 (rol,%B0) CR_TAB
2312 AS1 (rol,%C0) CR_TAB
2313 AS1 (rol,%D0) CR_TAB
2316 insn, operands, len);
2320 /* 8bit arithmetic shift right ((signed char)x >> i) */
2323 ashrqi3_out (insn,operands,len)
2326 int *len; /* insn length */
2328 if (GET_CODE (operands[2]) == CONST_INT)
2334 switch (INTVAL (operands[2]))
2336 default: len = t; break;
2339 return AS1 (asr,%0);
2342 return (AS1 (asr,%0) CR_TAB
2346 return (AS1 (asr,%0) CR_TAB
2351 return (AS1 (asr,%0) CR_TAB
2359 out_shift_with_cnt (AS1 (asr,%0) CR_TAB
2362 insn, operands, len);
2367 /* 16bit arithmetic shift right ((signed short)x >> i) */
2370 ashrhi3_out (insn,operands,len)
2375 if (GET_CODE (operands[2]) == CONST_INT)
2381 switch (INTVAL (operands[2]))
2383 default: len = t; break;
2386 return (AS1 (asr,%B0) CR_TAB
2390 return (AS1 (asr,%B0) CR_TAB
2391 AS1 (ror,%A0) CR_TAB
2392 AS1 (asr,%B0) CR_TAB
2395 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
2396 return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
2397 AS1 (clr,%B0) CR_TAB
2398 AS2 (sbrc,%A0,7) CR_TAB
2401 return *len = 3, (AS1 (clr,%B0) CR_TAB
2402 AS2 (sbrc,%A0,7) CR_TAB
2408 out_shift_with_cnt (AS1 (asr,%B0) CR_TAB
2409 AS1 (ror,%A0) CR_TAB
2412 insn, operands, len);
2417 /* 32bit arithmetic shift right ((signed long)x >> i) */
2420 ashrsi3_out (insn,operands,len)
2425 if (GET_CODE (operands[2]) == CONST_INT)
2431 switch (INTVAL (operands[2]))
2433 default: len = t; break;
2436 return (AS1 (asr,%D0) CR_TAB
2437 AS1 (ror,%C0) CR_TAB
2438 AS1 (ror,%B0) CR_TAB
2442 int reg0 = true_regnum (operands[0]);
2443 int reg1 = true_regnum (operands[1]);
2446 return (AS2 (mov,%A0,%B1) CR_TAB
2447 AS2 (mov,%B0,%C1) CR_TAB
2448 AS2 (mov,%C0,%D1) CR_TAB
2449 AS1 (clr,%D0) CR_TAB
2450 AS2 (sbrc,%C0,7) CR_TAB
2452 else if (reg0 == reg1 + 1)
2453 return *len = 3, (AS1 (clr,%D0) CR_TAB
2454 AS2 (sbrc,%C0,7) CR_TAB
2457 return (AS1 (clr,%D0) CR_TAB
2458 AS2 (sbrc,%C0,7) CR_TAB
2459 AS1 (dec,%D0) CR_TAB
2460 AS2 (mov,%C0,%D1) CR_TAB
2461 AS2 (mov,%B0,%C1) CR_TAB
2466 int reg0 = true_regnum (operands[0]);
2467 int reg1 = true_regnum (operands[1]);
2469 if (reg0 <= reg1 + 1)
2470 return (AS2 (mov,%A0,%C1) CR_TAB
2471 AS2 (mov,%B0,%D1) CR_TAB
2472 AS1 (clr,%D0) CR_TAB
2473 AS2 (sbrc,%B0,7) CR_TAB
2474 AS1 (com,%D0) CR_TAB
2476 else if (reg0 == reg1 + 2)
2477 return *len = 4, (AS1 (clr,%D0) CR_TAB
2478 AS2 (sbrc,%B0,7) CR_TAB
2479 AS1 (com,%D0) CR_TAB
2482 return (AS2 (mov,%B0,%D1) CR_TAB
2483 AS2 (mov,%A0,%C1) CR_TAB
2484 AS1 (clr,%D0) CR_TAB
2485 AS2 (sbrc,%B0,7) CR_TAB
2486 AS1 (com,%D0) CR_TAB
2490 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
2491 return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
2492 AS1 (clr,%D0) CR_TAB
2493 AS2 (sbrc,%A0,7) CR_TAB
2494 AS1 (com,%D0) CR_TAB
2495 AS2 (mov,%B0,%D0) CR_TAB
2498 return *len = 5, (AS1 (clr,%D0) CR_TAB
2499 AS2 (sbrc,%A0,7) CR_TAB
2500 AS1 (com,%D0) CR_TAB
2501 AS2 (mov,%B0,%D0) CR_TAB
2507 out_shift_with_cnt (AS1 (asr,%D0) CR_TAB
2508 AS1 (ror,%C0) CR_TAB
2509 AS1 (ror,%B0) CR_TAB
2510 AS1 (ror,%A0) CR_TAB
2513 insn, operands, len);
2517 /* 8bit logic shift right ((unsigned char)x >> i) */
2520 lshrqi3_out (insn,operands,len)
2525 if (GET_CODE (operands[2]) == CONST_INT)
2531 switch (INTVAL (operands[2]))
2533 default: len = t; break;
2536 return AS1 (lsr,%0);
2539 return (AS1 (lsr,%0) CR_TAB
2543 return (AS1 (lsr,%0) CR_TAB
2547 if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
2550 return (AS1 (swap,%0) CR_TAB
2551 AS2 (andi,%0,0x0f));
2554 return (AS1 (lsr,%0) CR_TAB
2559 if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
2562 return (AS1 (swap,%0) CR_TAB
2567 return (AS1 (lsr,%0) CR_TAB
2573 if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
2576 return (AS1 (swap,%0) CR_TAB
2582 return (AS1 (lsr,%0) CR_TAB
2590 return (AS1 (rol,%0) CR_TAB
2597 out_shift_with_cnt (AS1 (lsr,%0) CR_TAB
2600 insn, operands, len);
2604 /* 16bit logic shift right ((unsigned short)x >> i) */
2607 lshrhi3_out (insn,operands,len)
2612 if (GET_CODE (operands[2]) == CONST_INT)
2618 switch (INTVAL (operands[2]))
2620 default: len = t; break;
2623 return (AS1 (lsr,%B0) CR_TAB
2627 return (AS1 (lsr,%B0) CR_TAB
2628 AS1 (ror,%A0) CR_TAB
2629 AS1 (lsr,%B0) CR_TAB
2632 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
2633 return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
2636 return *len = 1, AS1 (clr,%B0);
2642 out_shift_with_cnt (AS1 (lsr,%B0) CR_TAB
2643 AS1 (ror,%A0) CR_TAB
2646 insn, operands, len);
2650 /* 32bit logic shift right ((unsigned int)x >> i) */
2653 lshrsi3_out (insn,operands,len)
2658 if (GET_CODE (operands[2]) == CONST_INT)
2664 switch (INTVAL (operands[2]))
2666 default: len = t; break;
2669 return (AS1 (lsr,%D0) CR_TAB
2670 AS1 (ror,%C0) CR_TAB
2671 AS1 (ror,%B0) CR_TAB
2675 int reg0 = true_regnum (operands[0]);
2676 int reg1 = true_regnum (operands[1]);
2679 return (AS2 (mov,%A0,%B1) CR_TAB
2680 AS2 (mov,%B0,%C1) CR_TAB
2681 AS2 (mov,%C0,%D1) CR_TAB
2683 else if (reg0 == reg1 + 1)
2684 return *len = 1, AS1 (clr,%D0);
2686 return (AS1 (clr,%D0) CR_TAB
2687 AS2 (mov,%C0,%D1) CR_TAB
2688 AS2 (mov,%B0,%C1) CR_TAB
2693 int reg0 = true_regnum (operands[0]);
2694 int reg1 = true_regnum (operands[1]);
2696 if (reg0 <= reg1 + 1)
2697 return (AS2 (mov,%A0,%C1) CR_TAB
2698 AS2 (mov,%B0,%D1) CR_TAB
2699 AS1 (clr,%C0) CR_TAB
2701 else if (reg0 == reg1 + 2)
2702 return *len = 2, (AS1 (clr,%C0) CR_TAB
2705 return (AS2 (mov,%B0,%D1) CR_TAB
2706 AS2 (mov,%A0,%C1) CR_TAB
2707 AS1 (clr,%C0) CR_TAB
2711 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
2712 return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
2713 AS1 (clr,%B0) CR_TAB
2714 AS1 (clr,%C0) CR_TAB
2717 return *len = 3, (AS1 (clr,%B0) CR_TAB
2718 AS1 (clr,%C0) CR_TAB
2724 out_shift_with_cnt (AS1 (lsr,%D0) CR_TAB
2725 AS1 (ror,%C0) CR_TAB
2726 AS1 (ror,%B0) CR_TAB
2727 AS1 (ror,%A0) CR_TAB
2730 insn, operands, len);
2734 /* Modifies the length assigned to instruction INSN
2735 LEN is the initially computed length of the insn. */
2738 adjust_insn_length (insn,len)
2742 rtx patt = PATTERN (insn);
2744 if (GET_CODE (patt) == SET)
2747 op[1] = SET_SRC (patt);
2748 op[0] = SET_DEST (patt);
2749 if (REG_P (op[0]) && GET_CODE (op[1]) == MEM)
2751 if (CONSTANT_ADDRESS_P (XEXP (op[1],0)))
2752 switch (GET_MODE (op[0]))
2754 case QImode: len = 2; break;
2755 case HImode: len = 4; break;
2757 case SFmode: len = 8; break;
2761 switch (GET_MODE (op[0]))
2763 case QImode: out_movqi_r_mr (insn,op,&len); break;
2764 case HImode: out_movhi_r_mr (insn,op,&len); break;
2766 case SFmode: out_movsi_r_mr (insn,op,&len); break;
2770 else if ((REG_P (op[1]) || const0_rtx == op[1])
2771 && GET_CODE (op[0]) == MEM)
2773 if (CONSTANT_ADDRESS_P (XEXP (op[0],0)))
2774 switch (GET_MODE (op[0]))
2776 case QImode: len = 2; break;
2777 case HImode: len = 4; break;
2779 case SFmode: len = 8; break;
2782 else if (GET_CODE (XEXP (op[0],0)) != POST_DEC)
2783 switch (GET_MODE (op[0]))
2785 case QImode: out_movqi_mr_r (insn,op,&len); break;
2786 case HImode: out_movhi_mr_r (insn,op,&len); break;
2788 case SFmode: out_movsi_mr_r (insn,op,&len); break;
2792 else if (op[0] == cc0_rtx && REG_P (op[1]))
2794 switch (GET_MODE (op[1]))
2796 case HImode: out_tsthi (insn,&len); break;
2797 case SImode: out_tstsi (insn,&len); break;
2801 else if (GET_CODE (op[1]) == AND)
2803 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
2805 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
2806 if (GET_MODE (op[1]) == SImode)
2807 len = (((mask & 0xff) != 0xff)
2808 + ((mask & 0xff00) != 0xff00)
2809 + ((mask & 0xff0000UL) != 0xff0000UL)
2810 + ((mask & 0xff000000UL) != 0xff000000UL));
2811 else if (GET_MODE (op[1]) == HImode)
2812 len = (((mask & 0xff) != 0xff)
2813 + ((mask & 0xff00) != 0xff00));
2816 else if (GET_CODE (op[1]) == IOR)
2818 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
2820 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
2821 if (GET_MODE (op[1]) == SImode)
2822 len = (((mask & 0xff) == 0)
2823 + ((mask & 0xff00) == 0)
2824 + ((mask & 0xff0000UL) == 0)
2825 + ((mask & 0xff000000UL) ==0));
2826 else if (GET_MODE (op[1]) == HImode)
2827 len = (((mask & 0xff) == 0)
2828 + ((mask & 0xff00) == 0));
2832 set = single_set (insn);
2836 op[1] = SET_SRC (set);
2837 op[0] = SET_DEST (set);
2838 if (GET_CODE (op[1]) == ASHIFT
2839 || GET_CODE (op[1]) == ASHIFTRT
2840 || GET_CODE (op[1]) == LSHIFTRT)
2844 ops[1] = XEXP (op[1],0);
2845 ops[2] = XEXP (op[1],1);
2846 switch (GET_CODE (op[1]))
2849 switch (GET_MODE (op[0]))
2851 case QImode: ashlqi3_out (insn,ops,&len); break;
2852 case HImode: ashlhi3_out (insn,ops,&len); break;
2853 case SImode: ashlsi3_out (insn,ops,&len); break;
2858 switch (GET_MODE (op[0]))
2860 case QImode: ashrqi3_out (insn,ops,&len); break;
2861 case HImode: ashrhi3_out (insn,ops,&len); break;
2862 case SImode: ashrsi3_out (insn,ops,&len); break;
2867 switch (GET_MODE (op[0]))
2869 case QImode: lshrqi3_out (insn,ops,&len); break;
2870 case HImode: lshrhi3_out (insn,ops,&len); break;
2871 case SImode: lshrsi3_out (insn,ops,&len); break;
2883 /* Return non-zero if register REG dead after INSN */
2886 reg_unused_after (insn, reg)
2891 /* In egcs 1.1.x dead_or_set_p give buggy result after reload
2892 #ifdef PRESERVE_DEATH_INFO_REGNO_P
2893 || dead_or_set_p (insn,reg)
2897 || (REG_P(reg) && _reg_unused_after (insn, reg)));
2900 /* Return non-zero if REG is not used after INSN.
2901 We assume REG is a reload reg, and therefore does
2902 not live past labels. It may live past calls or jumps though. */
2905 _reg_unused_after (insn, reg)
2912 /* If the reg is set by this instruction, then it is safe for our
2913 case. Disregard the case where this is a store to memory, since
2914 we are checking a register used in the store address. */
2915 set = single_set (insn);
2916 if (set && GET_CODE (SET_DEST (set)) != MEM
2917 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
2920 while ((insn = NEXT_INSN (insn)))
2922 code = GET_CODE (insn);
2925 /* If this is a label that existed before reload, then the register
2926 if dead here. However, if this is a label added by reorg, then
2927 the register may still be live here. We can't tell the difference,
2928 so we just ignore labels completely. */
2929 if (code == CODE_LABEL)
2934 if (code == JUMP_INSN)
2937 /* If this is a sequence, we must handle them all at once.
2938 We could have for instance a call that sets the target register,
2939 and a insn in a delay slot that uses the register. In this case,
2940 we must return 0. */
2941 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
2946 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2948 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
2949 rtx set = single_set (this_insn);
2951 if (GET_CODE (this_insn) == CALL_INSN)
2953 else if (GET_CODE (this_insn) == JUMP_INSN)
2955 if (INSN_ANNULLED_BRANCH_P (this_insn))
2960 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
2962 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
2964 if (GET_CODE (SET_DEST (set)) != MEM)
2970 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
2975 else if (code == JUMP_INSN)
2979 if (code == CALL_INSN)
2982 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
2983 if (GET_CODE (XEXP (tem, 0)) == USE
2984 && REG_P (XEXP (XEXP (tem, 0), 0))
2985 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
2987 if (call_used_regs[REGNO (reg)])
2991 if (GET_RTX_CLASS (code) == 'i')
2993 rtx set = single_set (insn);
2995 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
2997 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
2998 return GET_CODE (SET_DEST (set)) != MEM;
2999 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
3006 /* Output rtx VALUE as .byte to file FILE */
3009 asm_output_char(file,value)
3013 fprintf (file, "\t.byte ");
3014 output_addr_const (file, value);
3015 fprintf (file, "\n");
3019 /* Output VALUE as .byte to file FILE */
3022 asm_output_byte (file,value)
3026 fprintf (file, "\t.byte 0x%x\n",value & 0xff);
3030 /* Output rtx VALUE as .word to file FILE */
3033 asm_output_short (file, value)
3037 if (SYMBOL_REF_FLAG (value) || GET_CODE (value) == LABEL_REF)
3039 fprintf (file, "\t.word pm(");
3040 output_addr_const (file, (value));
3041 fprintf (file, ")\n");
3045 fprintf (file, "\t.word ");
3046 output_addr_const (file, (value));
3047 fprintf (file, "\n");
3052 /* Output real N to file FILE */
3055 asm_output_float (file, n)
3062 REAL_VALUE_TO_TARGET_SINGLE (n, val);
3063 REAL_VALUE_TO_DECIMAL (n, "%g", dstr);
3064 fprintf (file, "\t.long 0x%08lx\t/* %s */\n",val, dstr);
3067 /* Sets section name for declaration DECL */
3070 unique_section (decl, reloc)
3072 int reloc ATTRIBUTE_UNUSED;
3077 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
3078 /* Strip off any encoding in name. */
3079 STRIP_NAME_ENCODING (name, name);
3081 if (TREE_CODE (decl) == FUNCTION_DECL)
3083 if (flag_function_sections)
3089 fatal ("Strange situation: unique section is not a FUNCTION_DECL");
3091 if (flag_function_sections)
3093 len = strlen (name) + strlen (prefix);
3094 string = alloca (len + 1);
3095 sprintf (string, "%s%s", prefix, name);
3096 DECL_SECTION_NAME (decl) = build_string (len, string);
3101 /* Output section name to file FILE */
3104 asm_output_section_name(file, decl, name, reloc)
3106 tree decl ATTRIBUTE_UNUSED;
3108 int reloc ATTRIBUTE_UNUSED;
3110 fprintf (file, ".section %s\n", name);
3114 /* The routine used to output NUL terminated strings. We use a special
3115 version of this for most svr4 targets because doing so makes the
3116 generated assembly code more compact (and thus faster to assemble)
3117 as well as more readable, especially for targets like the i386
3118 (where the only alternative is to output character sequences as
3119 comma separated lists of numbers). */
3122 gas_output_limited_string(file, str)
3123 FILE * file ATTRIBUTE_UNUSED;
3126 unsigned char *_limited_str = (unsigned char *) str;
3128 fprintf (file, "\t%s\t\"", STRING_ASM_OP);
3129 for (; (ch = *_limited_str); _limited_str++)
3132 switch (escape = ESCAPES[ch])
3138 fprintf (file, "\\%03o", ch);
3142 putc (escape, file);
3146 fprintf (file, "\"\n");
3149 /* The routine used to output sequences of byte values. We use a special
3150 version of this for most svr4 targets because doing so makes the
3151 generated assembly code more compact (and thus faster to assemble)
3152 as well as more readable. Note that if we find subparts of the
3153 character sequence which end with NUL (and which are shorter than
3154 STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
3157 gas_output_ascii(file, str, length)
3162 unsigned char *_ascii_bytes = (unsigned char *) str;
3163 unsigned char *limit = _ascii_bytes + length;
3164 unsigned bytes_in_chunk = 0;
3165 for (; _ascii_bytes < limit; _ascii_bytes++)
3167 register unsigned char *p;
3168 if (bytes_in_chunk >= 60)
3170 fprintf (file, "\"\n");
3173 for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
3175 if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
3177 if (bytes_in_chunk > 0)
3179 fprintf (file, "\"\n");
3182 gas_output_limited_string (file, _ascii_bytes);
3189 if (bytes_in_chunk == 0)
3190 fprintf (file, "\t.ascii\t\"");
3191 switch (escape = ESCAPES[ch = *_ascii_bytes])
3198 fprintf (file, "\\%03o", ch);
3199 bytes_in_chunk += 4;
3203 putc (escape, file);
3204 bytes_in_chunk += 2;
3209 if (bytes_in_chunk > 0)
3210 fprintf (file, "\"\n");
3213 /* Return value is nonzero if pseudos that have been
3214 assigned to registers of class CLASS would likely be spilled
3215 because registers of CLASS are needed for spill registers. */
3218 class_likely_spilled_p(int c)
3220 return (c != ALL_REGS && c != ADDW_REGS);
3223 /* Only `progmem' attribute valid for type. */
3226 valid_machine_type_attribute(type, attributes, identifier, args)
3227 tree type ATTRIBUTE_UNUSED;
3228 tree attributes ATTRIBUTE_UNUSED;
3230 tree args ATTRIBUTE_UNUSED;
3232 return is_attribute_p ("progmem", identifier);
3235 /* If IDENTIFIER with arguments ARGS is a valid machine specific
3236 attribute for DECL return 1.
3238 progmem - put data to program memory;
3239 signal - make a function to be hardware interrupt. After function
3240 epilogue interrupts are disabled;
3241 interrupt - make a function to be hardware interrupt. After function
3242 epilogue interrupts are enabled;
3243 naked - don't generate function prologue/epilogue and `ret' command. */
3246 valid_machine_decl_attribute (decl, attributes, attr, args)
3248 tree attributes ATTRIBUTE_UNUSED;
3250 tree args ATTRIBUTE_UNUSED;
3252 if (is_attribute_p ("interrupt", attr)
3253 || is_attribute_p ("signal", attr)
3254 || is_attribute_p ("naked", attr))
3255 return TREE_CODE (decl) == FUNCTION_DECL;
3257 if (is_attribute_p ("progmem", attr)
3258 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
3260 if (DECL_INITIAL (decl) == NULL_TREE)
3262 warning ("Only initialized variables can be placed into "
3263 "program memory area.");
3272 /* Look for attribute `progmem' in DECL
3273 founded - 1 otherwise 0 */
3276 avr_progmem_p (decl)
3281 if (TREE_CODE (decl) != VAR_DECL)
3285 != lookup_attribute ("progmem", DECL_MACHINE_ATTRIBUTES (decl)))
3291 while (TREE_CODE (a) == ARRAY_TYPE);
3293 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
3299 /* Encode section information about tree DECL */
3302 encode_section_info (decl)
3305 if (TREE_CODE (decl) == FUNCTION_DECL)
3306 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
3308 if ((TREE_STATIC (decl) || DECL_EXTERNAL (decl))
3309 && TREE_CODE (decl) == VAR_DECL
3310 && avr_progmem_p (decl))
3312 char * dsec = ".progmem.data";
3313 DECL_SECTION_NAME (decl) = build_string (strlen (dsec), dsec);
3317 /* Outputs to the stdio stream FILE some
3318 appropriate text to go at the start of an assembler file. */
3321 asm_file_start (file)
3324 output_file_directive (file, main_input_filename);
3325 fprintf (file, "\t.arch %s\n", avr_mcu_type->name);
3326 fputs ("__SREG__ = 0x3f\n"
3328 "__SP_L__ = 0x3d\n", file);
3331 initial_stack = avr_ram_end;
3334 static char buf[30];
3335 initial_stack = buf;
3336 sprintf (buf, "0x%x", avr_mcu_type->stack);
3339 fputs ("__tmp_reg__ = 0\n"
3340 "__zero_reg__ = 1\n"
3341 "_PC_ = 2\n", file);
3343 commands_in_file = 0;
3344 commands_in_prologues = 0;
3345 commands_in_epilogues = 0;
3348 /* Outputs to the stdio stream FILE some
3349 appropriate text to go at the end of an assembler file. */
3356 "/* File %s: code %4d (%4d), prologues %3d, epilogues %3d */\n",
3357 main_input_filename,
3359 commands_in_file - commands_in_prologues - commands_in_epilogues,
3360 commands_in_prologues, commands_in_epilogues);
3363 /* Choose the order in which to allocate hard registers for
3364 pseudo-registers local to a basic block.
3366 Store the desired register order in the array `reg_alloc_order'.
3367 Element 0 should be the register to allocate first; element 1, the
3368 next register; and so on. */
3371 order_regs_for_local_alloc (void)
3382 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
3394 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
3407 15,14,13,12,11,10,9,8,7,6,5,4,3,2,
3412 int *order = (TARGET_ORDER_1 ? order_1 :
3413 TARGET_ORDER_2 ? order_2 :
3415 for (i=0; i < sizeof (order_0) / sizeof (order_0[0]); ++i)
3416 reg_alloc_order[i] = order[i];
3419 /* Calculate the cost of X code of the expression in which it is contained,
3420 found in OUTER_CODE */
3423 default_rtx_costs (X, code, outer_code)
3426 enum rtx_code outer_code;
3433 cost = 2 * GET_MODE_SIZE (GET_MODE (X));
3436 if (outer_code != SET)
3438 if (GET_CODE (XEXP (X,0)) == SYMBOL_REF)
3439 cost += 2 * GET_MODE_SIZE (GET_MODE (X));
3441 cost += GET_MODE_SIZE (GET_MODE (X));
3447 if (outer_code == SET)
3448 cost = GET_MODE_SIZE (GET_MODE (X));
3450 cost = -GET_MODE_SIZE (GET_MODE (X));
3453 if (outer_code == SET)
3454 cost = GET_MODE_SIZE (GET_MODE (X));
3460 if (outer_code == SET)
3462 if (X == stack_pointer_rtx)
3464 else if (GET_CODE (XEXP (X,1)) == CONST_INT)
3465 cost = (INTVAL (XEXP (X,1)) <= 63 ? 1 :
3466 GET_MODE_SIZE (GET_MODE (X)));
3468 cost = GET_MODE_SIZE (GET_MODE (X));
3472 if (GET_CODE (XEXP (X,1)) == CONST_INT)
3473 cost = GET_MODE_SIZE (GET_MODE (XEXP (X,0)));
3481 /* Calculate the cost of a memory address */
3484 avr_address_cost (rtx x)
3486 if (GET_CODE (x) == PLUS
3487 && GET_CODE (XEXP (x,1)) == CONST_INT
3488 && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
3489 && INTVAL (XEXP (x,1)) >= 61)
3491 if (CONSTANT_ADDRESS_P (x))
3496 /* EXTRA_CONSTRAINT helper */
3499 extra_constraint (x,c)
3504 && GET_CODE (x) == MEM
3505 && GET_CODE (XEXP (x,0)) == PLUS)
3507 if (TARGET_ALL_DEBUG)
3509 fprintf (stderr, ("extra_constraint:\n"
3510 "reload_completed: %d\n"
3511 "reload_in_progress: %d\n"),
3512 reload_completed, reload_in_progress);
3515 if (GET_CODE (x) == MEM
3516 && GET_CODE (XEXP (x,0)) == PLUS
3517 && REG_P (XEXP (XEXP (x,0), 0))
3518 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
3519 && (INTVAL (XEXP (XEXP (x,0), 1))
3520 <= (64 - GET_MODE_SIZE (GET_MODE (x)))))
3522 rtx xx = XEXP (XEXP (x,0), 0);
3523 int regno = REGNO (xx);
3524 if (TARGET_ALL_DEBUG)
3526 fprintf (stderr, ("extra_constraint:\n"
3527 "reload_completed: %d\n"
3528 "reload_in_progress: %d\n"),
3529 reload_completed, reload_in_progress);
3532 if (regno >= FIRST_PSEUDO_REGISTER)
3533 return 1; /* allocate pseudos */
3534 else if (regno == REG_Z || regno == REG_Y)
3535 return 1; /* strictly check */
3536 else if (xx == frame_pointer_rtx
3537 || xx == arg_pointer_rtx)
3538 return 1; /* XXX frame & arg pointer checks */
3544 /* Convert condition code CONDITION to the valid AVR condition code */
3547 avr_normalize_condition (condition)
3561 fatal ("Wrong condition: %s", GET_RTX_NAME (condition));
3565 /* This fnction optimizes conditional jumps */
3568 machine_dependent_reorg (first_insn)
3574 for (insn = first_insn; insn; insn = NEXT_INSN (insn))
3576 if (! (insn == 0 || GET_CODE (insn) == INSN
3577 || GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN)
3578 || !single_set (insn))
3581 pattern = PATTERN (insn);
3583 cc_prev_status = cc_status;
3584 NOTICE_UPDATE_CC (pattern, insn);
3586 if (GET_CODE (pattern) == PARALLEL)
3587 pattern = XVECEXP (pattern, 0, 0);
3588 if (GET_CODE (pattern) == SET
3589 && SET_DEST (pattern) == cc0_rtx
3590 && compare_diff_p (insn))
3592 if (GET_CODE (SET_SRC (pattern)) == COMPARE)
3594 /* Now we work under compare insn */
3596 pattern = SET_SRC (pattern);
3597 if (true_regnum (XEXP (pattern,0)) >= 0
3598 && true_regnum (XEXP (pattern,1)) >= 0 )
3600 rtx x = XEXP (pattern,0);
3601 rtx next = next_real_insn (insn);
3602 rtx pat = PATTERN (next);
3603 rtx src = SET_SRC (pat);
3604 rtx t = XEXP (src,0);
3605 PUT_CODE (t, swap_condition (GET_CODE (t)));
3606 XEXP (pattern,0) = XEXP (pattern,1);
3607 XEXP (pattern,1) = x;
3608 INSN_CODE (next) = -1;
3610 else if (true_regnum (XEXP (pattern,0)) >= 0
3611 && GET_CODE (XEXP (pattern,1)) == CONST_INT)
3613 rtx x = XEXP (pattern,1);
3614 rtx next = next_real_insn (insn);
3615 rtx pat = PATTERN (next);
3616 rtx src = SET_SRC (pat);
3617 rtx t = XEXP (src,0);
3619 if (avr_simplify_comparision_p (GET_MODE (XEXP (pattern,0)),
3622 XEXP (pattern,1) = GEN_INT (INTVAL (x)+1);
3623 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
3624 INSN_CODE (next) = -1;
3625 INSN_CODE (insn) = -1;
3629 else if (true_regnum (SET_SRC (pattern)) >= 0)
3631 /* This is a tst insn */
3632 rtx next = next_real_insn (insn);
3633 rtx pat = PATTERN (next);
3634 rtx src = SET_SRC (pat);
3635 rtx t = XEXP (src,0);
3637 if (!(cc_prev_status.value1 != 0 && cc_status.value1 != 0
3638 && rtx_equal_p (cc_status.value1, cc_prev_status.value1)))
3640 PUT_CODE (t, swap_condition (GET_CODE (t)));
3641 SET_SRC (pattern) = gen_rtx (NEG,
3642 GET_MODE (SET_SRC (pattern)),
3644 INSN_CODE (next) = -1;
3645 INSN_CODE (insn) = -1;
3652 /* Returns register number for function return value.*/
3655 avr_ret_register (void)
3660 /* Ceate an RTX representing the place where a
3661 library function returns a value of mode MODE. */
3664 avr_libcall_value (mode)
3665 enum machine_mode mode;
3667 int offs = GET_MODE_SIZE (mode);
3670 return gen_rtx (REG, mode, RET_REGISTER + 2 - offs);
3673 /* Create an RTX representing the place where a
3674 function returns a value of data type VALTYPE. */
3677 avr_function_value (type,func)
3679 tree func ATTRIBUTE_UNUSED;
3682 if (TYPE_MODE (type) != BLKmode)
3683 return avr_libcall_value (TYPE_MODE (type));
3685 offs = int_size_in_bytes (type);
3688 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
3689 offs = GET_MODE_SIZE (SImode);
3690 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
3691 offs = GET_MODE_SIZE (DImode);
3693 return gen_rtx (REG, BLKmode, RET_REGISTER + 2 - offs);
3696 /* Returns non-zero if number MASK have only one setted bit */
3699 mask_one_bit_p (mask)
3703 unsigned HOST_WIDE_INT n=mask;
3704 for (i = 0; i < 32; ++i)
3706 if (n & 0x80000000UL)
3708 if (n & 0x7fffffffUL)
3719 /* Places additional restrictions on the register class to
3720 use when it is necessary to copy value X into a register
3724 preferred_reload_class(x,class)
3726 enum reg_class class;
3728 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0)
3730 if (CONSTANT_P (x) && (class == NO_LD_REGS
3731 || class == ALL_REGS
3732 || class == GENERAL_REGS))
3740 debug_hard_reg_set (HARD_REG_SET set)
3743 for (i=0; i < FIRST_PSEUDO_REGISTER; ++i)
3745 if (TEST_HARD_REG_BIT (set, i))
3747 fprintf (stderr, "r%-2d ", i);
3750 fprintf (stderr, "\n");