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. */
27 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-flags.h"
33 #include "insn-attr.h"
45 static int avr_naked_function_p PARAMS ((tree));
46 static int interrupt_function_p PARAMS ((tree));
47 static int signal_function_p PARAMS ((tree));
48 static int sequent_regs_live PARAMS ((void));
49 static char * ptrreg_to_str PARAMS ((int));
50 static char * cond_string PARAMS ((enum rtx_code));
53 /* Allocate registers from r25 to r8 for parameters for function calls */
54 #define FIRST_CUM_REG 26
56 /* Temporary register RTX (gen_rtx (REG,QImode,TMP_REGNO)) */
59 /* Zeroed register RTX (gen_rtx (REG,QImode,ZERO_REGNO)) */
62 /* AVR register names {"r0", "r1", ..., "r31"} */
63 char * avr_regnames[] = REGISTER_NAMES;
65 /* This holds the last insn address. */
66 static int last_insn_address = 0;
68 /* Commands count in the compiled file */
69 static int commands_in_file;
71 /* Commands in the functions prologues in the compiled file */
72 static int commands_in_prologues;
74 /* Commands in the functions epilogues in the compiled file */
75 static int commands_in_epilogues;
77 /* Prologue/Epilogue size in words */
78 static int prologue_size;
79 static int epilogue_size;
81 /* Initial stack value specified by the `-minit-stack=' option */
82 const char *avr_ram_end = NULL;
84 /* Numeric representation */
85 static const char *initial_stack;
87 /* Default MCU name */
88 const char *avr_mcu_name = "at90s8515";
91 struct mcu_type_s *avr_mcu_type;
93 /* MCU names, initial stack value, flag 'mega' */
94 static struct mcu_type_s mcu_types[] =
95 {{"at90s2313", 224-1, 0},
96 {"at90s2323", 224-1, 0},
97 {"at90s2333", 224-1, 0},
98 {"attiny22", 224-1, 0},
99 {"at90s2343", 224-1, 0},
100 {"at90s4433", 224-1, 0},
101 {"at90s4414", 0x15f, 0},
102 {"at90s4434", 0x15f, 0},
103 {"at90s8515", 0x25f, 0},
104 {"at90s8535", 0x25f, 0},
105 {"atmega603", 0x0fff,1},
106 {"atmega103", 0x0fff,1},
112 avr_override_options (void)
114 for (avr_mcu_type = mcu_types; avr_mcu_type->name; ++avr_mcu_type)
115 if (strcmp (avr_mcu_type->name, avr_mcu_name) == 0)
117 if (!avr_mcu_type->name)
121 "Wrong mcu `%s' specified\n"
122 "Allowed mcu's:\n", avr_mcu_name);
123 for (i = 0; mcu_types[i].name; ++i)
124 fprintf (stderr," %s\n", mcu_types[i].name);
125 fatal ("select right mcu name");
129 /* Initialize TMP_REG_RTX and ZERO_REG_RTX */
133 tmp_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
134 memset (tmp_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
135 PUT_CODE (tmp_reg_rtx, REG);
136 PUT_MODE (tmp_reg_rtx, QImode);
137 XINT (tmp_reg_rtx, 0) = TMP_REGNO;
139 zero_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
140 memset (zero_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
141 PUT_CODE (zero_reg_rtx, REG);
142 PUT_MODE (zero_reg_rtx, QImode);
143 XINT (zero_reg_rtx, 0) = ZERO_REGNO;
146 /* return register class from register number */
148 static int reg_class_tab[]={
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,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
152 GENERAL_REGS, /* r0 - r15 */
153 LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
154 LD_REGS, /* r16 - 23 */
155 ADDW_REGS,ADDW_REGS, /* r24,r25 */
156 POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
157 POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
158 POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
159 STACK_REG,STACK_REG /* SPL,SPH */
162 /* Return register class for register R */
165 avr_regno_reg_class (r)
169 return reg_class_tab[r];
174 /* A C expression which defines the machine-dependent operand
175 constraint letters for register classes. If C is such a
176 letter, the value should be the register class corresponding to
177 it. Otherwise, the value should be `NO_REGS'. The register
178 letter `r', corresponding to class `GENERAL_REGS', will not be
179 passed to this macro; you do not need to handle it. */
182 avr_reg_class_from_letter (c)
187 case 't' : return R0_REG;
188 case 'b' : return BASE_POINTER_REGS;
189 case 'e' : return POINTER_REGS;
190 case 'w' : return ADDW_REGS;
191 case 'd' : return LD_REGS;
192 case 'l' : return NO_LD_REGS;
193 case 'a' : return SIMPLE_LD_REGS;
194 case 'x' : return POINTER_X_REGS;
195 case 'y' : return POINTER_Y_REGS;
196 case 'z' : return POINTER_Z_REGS;
197 case 'q' : return STACK_REG;
203 /* Return non-zero if FUNC is a naked function. */
206 avr_naked_function_p (func)
211 if (TREE_CODE (func) != FUNCTION_DECL)
214 a = lookup_attribute ("naked", DECL_MACHINE_ATTRIBUTES (func));
215 return a != NULL_TREE;
218 /* Return nonzero if FUNC is an interrupt function as specified
219 by the "interrupt" attribute. */
222 interrupt_function_p (func)
227 if (TREE_CODE (func) != FUNCTION_DECL)
230 a = lookup_attribute ("interrupt", DECL_MACHINE_ATTRIBUTES (func));
231 return a != NULL_TREE;
234 /* Return nonzero if FUNC is an signal function as specified
235 by the "signal" attribute. */
238 signal_function_p (func)
243 if (TREE_CODE (func) != FUNCTION_DECL)
246 a = lookup_attribute ("signal", DECL_MACHINE_ATTRIBUTES (func));
247 return a != NULL_TREE;
250 /* Compute offset between arg_pointer and frame_pointer */
253 initial_elimination_offset (from,to)
254 int from ATTRIBUTE_UNUSED;
255 int to ATTRIBUTE_UNUSED;
258 int interrupt_func_p = interrupt_function_p (current_function_decl);
259 int signal_func_p = signal_function_p (current_function_decl);
260 int leaf_func_p = leaf_function_p ();
261 int offset= frame_pointer_needed ? 2 : 0;
263 for (reg = 0; reg < 32; ++reg)
265 if ((!leaf_func_p && (call_used_regs[reg]
266 && (interrupt_func_p || signal_func_p)))
267 || (regs_ever_live[reg]
268 && (!call_used_regs[reg] || interrupt_func_p || signal_func_p)
269 && ! (frame_pointer_needed
270 && (reg == REG_Y || reg == (REG_Y+1)))))
275 return get_frame_size () + 2 + 1 + offset;
278 /* This function checks sequence of live registers */
287 for (reg = 0; reg < 18; ++reg)
289 if (!call_used_regs[reg])
291 if (regs_ever_live[reg])
301 if (!frame_pointer_needed)
303 if (regs_ever_live[REG_Y])
311 if (regs_ever_live[REG_Y+1])
324 return (cur_seq == live_seq) ? live_seq : 0;
328 /* Output function prologue */
331 function_prologue (FILE *file, int size)
334 int interrupt_func_p;
341 if (avr_naked_function_p (current_function_decl))
343 fprintf (file, "/* prologue: naked */\n");
347 interrupt_func_p = interrupt_function_p (current_function_decl);
348 signal_func_p = signal_function_p (current_function_decl);
349 leaf_func_p = leaf_function_p ();
350 main_p = ! strcmp ("main", current_function_name);
351 live_seq = sequent_regs_live ();
352 minimize = (TARGET_CALL_PROLOGUES
353 && !interrupt_func_p && !signal_func_p && live_seq);
355 last_insn_address = 0;
357 fprintf (file, "/* prologue: frame size=%d */\n", size);
359 if (interrupt_func_p)
361 fprintf (file,"\tsei\n");
364 if (interrupt_func_p | signal_func_p)
367 AS1 (push,__zero_reg__) CR_TAB
368 AS1 (push,__tmp_reg__) CR_TAB
369 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
370 AS1 (push,__tmp_reg__) CR_TAB
371 AS1 (clr,__zero_reg__) "\n");
377 AS2 (ldi, r28, lo8(%s - %d)) CR_TAB
378 AS2 (ldi, r29, hi8(%s - %d)) CR_TAB
379 AS2 (out,__SP_L__,r28) CR_TAB
380 AS2 (out,__SP_H__,r29) "\n"),
381 initial_stack, size, initial_stack, size);
385 else if (minimize && (frame_pointer_needed || live_seq > 6))
388 AS2 (ldi, r26, %d) CR_TAB
389 AS2 (ldi, r27, %d) CR_TAB), size & 0xff, size / 0x100);
391 fprintf (file, (AS2 (ldi, r30, pm_lo8(.L_%s_body)) CR_TAB
392 AS2 (ldi, r31, pm_hi8(.L_%s_body)) CR_TAB)
393 ,current_function_name, current_function_name);
399 fprintf (file, AS1 (jmp,__prologue_saves__+%d) "\n",
400 (18 - live_seq) * 2);
405 fprintf (file, AS1 (rjmp,__prologue_saves__+%d) "\n",
406 (18 - live_seq) * 2);
409 fprintf (file, ".L_%s_body:\n", current_function_name);
413 for (reg = 0; reg < 32; ++reg)
416 && (call_used_regs[reg]
417 && (interrupt_func_p || signal_func_p)
418 && !(reg == TMP_REGNO || reg == ZERO_REGNO)))
419 || (regs_ever_live[reg]
420 && (!call_used_regs[reg]
421 || interrupt_func_p || signal_func_p)
422 && ! (frame_pointer_needed
423 && (reg == REG_Y || reg == (REG_Y+1)))))
425 fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
429 if (frame_pointer_needed)
433 AS1 (push,r28) CR_TAB
434 AS1 (push,r29) CR_TAB
435 AS2 (in,r28,__SP_L__) CR_TAB
436 AS2 (in,r29,__SP_H__) "\n");
443 AS2 (subi,r28,%d) CR_TAB
444 AS2 (sbci,r29,%d) CR_TAB)
445 , size & 0xff, size / 0x100);
450 fprintf (file, "\t" AS2 (sbiw,r28,%d) CR_TAB, size);
453 if (interrupt_func_p)
457 AS2 (out,__SP_L__,r28) CR_TAB
459 AS2 (out,__SP_H__,r29) "\n");
462 else if (signal_func_p || TARGET_NO_INTERRUPTS)
465 AS2 (out,__SP_L__,r28) CR_TAB
466 AS2 (out,__SP_H__,r29) "\n");
472 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
474 AS2 (out,__SP_L__,r28) CR_TAB
475 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
476 AS2 (out,__SP_H__,r29) "\n");
483 fprintf (file, "/* prologue end (size=%d) */\n", prologue_size);
486 /* Output function epilogue */
489 function_epilogue (FILE *file, int size)
492 int interrupt_func_p;
500 if (avr_naked_function_p (current_function_decl))
502 fprintf (file, "/* epilogue: naked */\n");
506 interrupt_func_p = interrupt_function_p (current_function_decl);
507 signal_func_p = signal_function_p (current_function_decl);
508 leaf_func_p = leaf_function_p ();
509 main_p = ! strcmp ("main", current_function_name);
510 function_size = (insn_addresses[INSN_UID (get_last_insn ())]
511 - insn_addresses[INSN_UID (get_insns ())]);
512 live_seq = sequent_regs_live ();
513 minimize = (TARGET_CALL_PROLOGUES
514 && !interrupt_func_p && !signal_func_p && live_seq);
517 fprintf (file, "/* epilogue: frame size=%d */\n", size);
520 fprintf (file, "__stop_progIi__:\n\trjmp __stop_progIi__\n");
523 else if (minimize && (frame_pointer_needed || live_seq > 4))
525 fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
527 if (frame_pointer_needed)
533 fprintf (file, AS2 (subi,r28,lo8(-%d)) CR_TAB, size);
534 fprintf (file, AS2 (sbci,r29,hi8(-%d)) CR_TAB, size);
539 fprintf (file, AS2 (adiw,r28,%d) CR_TAB, size);
546 fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
547 AS2 (in , r29, __SP_H__) CR_TAB));
553 fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
554 (18 - live_seq) * 2);
559 fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
560 (18 - live_seq) * 2);
566 if (frame_pointer_needed)
572 fprintf (file, "\t" AS2 (subi,r28,lo8(-%d)) CR_TAB, size);
573 fprintf (file, AS2 (sbci,r29,hi8(-%d)) CR_TAB, size);
578 fprintf (file, "\t" AS2 (adiw,r28,%d) CR_TAB, size);
581 if (interrupt_func_p | signal_func_p)
585 AS2 (out,__SP_L__,r28) CR_TAB
586 AS2 (out,__SP_H__,r29) "\n");
589 else if (TARGET_NO_INTERRUPTS)
592 AS2 (out,__SP_L__,r28) CR_TAB
593 AS2 (out,__SP_H__,r29) "\n");
599 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
601 AS2 (out,__SP_L__,r28) CR_TAB
602 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
603 AS2 (out,__SP_H__,r29) "\n");
613 for (reg = 31; reg >= 0; --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 (pop,%s) "\n", avr_regnames[reg]);
630 if (interrupt_func_p | signal_func_p)
633 AS1 (pop,__tmp_reg__) CR_TAB
634 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
635 AS1 (pop,__tmp_reg__) CR_TAB
636 AS1 (pop,__zero_reg__) "\n");
638 fprintf (file, "\treti\n");
641 fprintf (file, "\tret\n");
645 fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
646 fprintf (file, "/* function %s size %d (%d) */\n", current_function_name,
647 prologue_size + function_size + epilogue_size, function_size);
648 commands_in_file += prologue_size + function_size + epilogue_size;
649 commands_in_prologues += prologue_size;
650 commands_in_epilogues += epilogue_size;
654 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
655 machine for a memory operand of mode MODE. */
658 legitimate_address_p (mode, x, strict)
659 enum machine_mode mode;
664 if (TARGET_ALL_DEBUG)
666 fprintf (stderr, "mode: (%s) %s %s %s %s:",
668 strict ? "(strict)": "",
669 reload_completed ? "(reload_completed)": "",
670 reload_in_progress ? "(reload_in_progress)": "",
671 reg_renumber ? "(reg_renumber)" : "");
672 if (GET_CODE (x) == PLUS
673 && REG_P (XEXP (x, 0))
674 && GET_CODE (XEXP (x, 1)) == CONST_INT
675 && INTVAL (XEXP (x, 1)) >= 0
676 && INTVAL (XEXP (x, 1)) <= (64 - GET_MODE_SIZE (mode))
679 fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
680 true_regnum (XEXP (x, 0)));
683 if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
684 : REG_OK_FOR_BASE_NOSTRICT_P (x)))
686 else if (CONSTANT_ADDRESS_P (x))
688 else if (GET_CODE (x) == PLUS
689 && REG_P (XEXP (x, 0))
690 && GET_CODE (XEXP (x, 1)) == CONST_INT
691 && INTVAL (XEXP (x, 1)) >= 0)
693 int fit = INTVAL (XEXP (x, 1)) <= (64 - GET_MODE_SIZE (mode));
697 || REGNO (XEXP (x,0)) == REG_Y || REGNO (XEXP (x,0)) == REG_Z)
699 if (XEXP (x,0) == frame_pointer_rtx
700 || XEXP (x,0) == arg_pointer_rtx)
703 else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
706 else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
707 && REG_P (XEXP (x, 0))
708 && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
709 : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
713 if (TARGET_ALL_DEBUG)
715 fprintf (stderr, " ret = %c\n", r);
720 /* Attempts to replace X with a valid
721 memory address for an operand of mode MODE */
724 legitimize_address (x, oldx, mode)
727 enum machine_mode mode;
730 if (TARGET_ALL_DEBUG)
732 fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
736 if (GET_CODE (oldx) == PLUS
737 && REG_P (XEXP (oldx,0)))
739 if (REG_P (XEXP (oldx,1)))
740 x = force_reg (GET_MODE (oldx), oldx);
741 else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
743 int offs = INTVAL (XEXP (oldx,1));
744 if (frame_pointer_rtx != XEXP (oldx,0))
745 if (offs > 64 - GET_MODE_SIZE (mode))
747 if (TARGET_ALL_DEBUG)
748 fprintf (stderr, "force_reg (big offset)\n");
749 x = force_reg (GET_MODE (oldx), oldx);
757 /* Return a pointer register name as a string */
760 ptrreg_to_str (regno)
765 case REG_X: return "X";
766 case REG_Y: return "Y";
767 case REG_Z: return "Z";
769 fatal ("register r%d isn't a pointer\n", regno);
774 /* Return the condition name as a string.
775 Used in conditional jump constructing */
788 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
793 fatal ("Internal compiler bug: command `bgt'");
795 fatal ("Internal compiler bug: command `ble'");
797 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
804 fatal ("Internal compiler bug: command `bgtu'");
806 fatal ("Internal compiler bug: command `bleu'");
814 /* Output ADDR to FILE as address */
817 print_operand_address (file, addr)
821 switch (GET_CODE (addr))
824 fprintf (file, ptrreg_to_str (REGNO (addr)));
828 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
832 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
836 if (CONSTANT_ADDRESS_P (addr)
837 && (SYMBOL_REF_FLAG (addr) || GET_CODE (addr) == LABEL_REF))
839 fprintf (file, "pm(");
840 output_addr_const (file,addr);
844 output_addr_const (file, addr);
849 /* Output X as assembler operand to file FILE */
852 print_operand (file, x, code)
859 if (code >= 'A' && code <= 'D')
864 if (x == zero_reg_rtx)
865 fprintf (file,"__zero_reg__");
867 fprintf (file, reg_names[true_regnum (x) + abcd]);
869 else if (GET_CODE (x) == CONST_INT)
870 fprintf (file, "%d", INTVAL (x) + abcd);
871 else if (GET_CODE (x) == MEM)
873 rtx addr = XEXP (x,0);
876 if (CONSTANT_P (addr))
878 else if (GET_CODE (addr) == PLUS)
881 else if (CONSTANT_P (addr) && abcd)
884 output_address (addr);
885 fprintf (file, ")+%d", abcd);
887 else if (GET_CODE (addr) == PLUS)
889 print_operand_address (file, XEXP (addr,0));
890 if (REGNO (XEXP (addr, 0)) == REG_X)
891 fatal_insn ("Internal compiler bug.\nBad address:"
894 print_operand (file, XEXP (addr,1), code);
897 print_operand_address (file, addr);
899 else if (GET_CODE (x) == CONST_DOUBLE)
903 if (GET_MODE (x) != SFmode)
904 fatal_insn ("Internal compiler bug. Unknown mode:", x);
905 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
906 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
907 asm_fprintf (file, "0x%x", val);
909 else if (code == 'j')
910 asm_fprintf (file, cond_string (GET_CODE (x)));
911 else if (code == 'k')
912 asm_fprintf (file, cond_string (reverse_condition (GET_CODE (x))));
914 output_addr_const (file, x);
917 /* Recognise operand OP of mode MODE used in call instructions */
920 call_insn_operand (op, mode)
922 enum machine_mode mode ATTRIBUTE_UNUSED;
924 if (GET_CODE (op) == MEM)
926 rtx inside = XEXP (op, 0);
927 if (register_operand (inside, Pmode))
929 if (CONSTANT_ADDRESS_P (inside))
935 /* Update the condition code in the INSN. */
938 notice_update_cc (body, insn)
939 rtx body ATTRIBUTE_UNUSED;
942 switch (get_attr_cc (insn))
945 /* Insn does not affect CC at all. */
954 rtx set = single_set (insn);
958 cc_status.flags |= CC_NO_OVERFLOW;
959 cc_status.value1 = SET_DEST (set);
965 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
966 The V flag may or may not be known but that's ok because
967 alter_cond will change tests to use EQ/NE. */
969 rtx set = single_set (insn);
973 cc_status.value1 = SET_DEST (set);
974 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
981 rtx set = single_set (insn);
984 cc_status.value1 = SET_SRC (set);
989 /* Insn doesn't leave CC in a usable state. */
995 /* Return maximum number of consecutive registers of
996 class CLASS needed to hold a value of mode MODE. */
999 class_max_nregs (class, mode)
1000 enum reg_class class ATTRIBUTE_UNUSED;
1001 enum machine_mode mode;
1003 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1006 /* Choose mode for jump insn:
1007 1 - relative jump in range -63 <= x <= 62 ;
1008 2 - relative jump in range -2046 <= x <= 2045 ;
1009 3 - absolute jump (only for ATmega[16]03). */
1012 avr_jump_mode (x,insn)
1013 rtx x; /* jump operand */
1014 rtx insn; /* jump insn */
1016 int dest_addr = insn_addresses[INSN_UID (GET_MODE (x) == LABEL_REF
1017 ? XEXP (x, 0) : x)];
1018 int cur_addr = insn_addresses[INSN_UID (insn)];
1019 int jump_distance = cur_addr - dest_addr;
1021 if (-63 <= jump_distance && jump_distance <= 62)
1023 else if (-2046 <= jump_distance && jump_distance <= 2045)
1031 /* return a AVR condition jump commands.
1032 LEN is a number returned by avr_jump_mode function. */
1035 ret_cond_branch (cond,len)
1042 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1043 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1045 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1046 AS1 (brmi,_PC_+2) CR_TAB
1048 (AS1 (breq,_PC_+6) CR_TAB
1049 AS1 (brmi,_PC_+4) CR_TAB
1053 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1055 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1056 AS1 (brlt,_PC_+2) CR_TAB
1058 (AS1 (breq,_PC_+6) CR_TAB
1059 AS1 (brlt,_PC_+4) CR_TAB
1062 return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1064 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1065 AS1 (brlo,_PC_+2) CR_TAB
1067 (AS1 (breq,_PC_+6) CR_TAB
1068 AS1 (brlo,_PC_+4) CR_TAB
1071 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1072 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1074 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1075 AS1 (brpl,_PC_+2) CR_TAB
1077 (AS1 (breq,_PC_+2) CR_TAB
1078 AS1 (brpl,_PC_+4) CR_TAB
1081 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1083 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1084 AS1 (brge,_PC_+2) CR_TAB
1086 (AS1 (breq,_PC_+2) CR_TAB
1087 AS1 (brge,_PC_+4) CR_TAB
1090 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1092 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1093 AS1 (brsh,_PC_+2) CR_TAB
1095 (AS1 (breq,_PC_+2) CR_TAB
1096 AS1 (brsh,_PC_+4) CR_TAB
1102 return AS1 (br%j1,%0);
1104 return (AS1 (br%k1,_PC_+2) CR_TAB
1107 return (AS1 (br%k1,_PC_+4) CR_TAB
1114 /* Predicate function for immediate operand which fits to byte (8bit) */
1117 byte_immediate_operand (op, mode)
1119 enum machine_mode mode ATTRIBUTE_UNUSED;
1121 return (GET_CODE (op) == CONST_INT
1122 && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1125 /* Output all insn addresses and their sizes into the assembly language
1126 output file. This is helpful for debugging whether the length attributes
1127 in the md file are correct.
1128 Output insn cost for next insn. */
1131 final_prescan_insn (insn, operand, num_operands)
1132 rtx insn, *operand ATTRIBUTE_UNUSED;
1133 int num_operands ATTRIBUTE_UNUSED;
1135 int uid = INSN_UID (insn);
1137 if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1139 fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n", insn_addresses[uid],
1140 insn_addresses[uid] - last_insn_address,
1141 rtx_cost (PATTERN (insn),INSN));
1143 last_insn_address = insn_addresses[uid];
1145 if (TARGET_RTL_DUMP)
1147 fprintf (asm_out_file, "/*****************\n");
1148 print_rtl_single (asm_out_file, insn);
1149 fprintf (asm_out_file, "*****************/\n");
1153 /* return 1 if undefined,
1154 1 if always true or always false */
1157 avr_simplify_comparision_p (mode, operator, x)
1158 enum machine_mode mode;
1162 unsigned int max = (mode == QImode ? 0xff :
1163 mode == HImode ? 0xffff :
1164 mode == SImode ? 0xffffffffU : 0);
1165 if (max && operator && GET_CODE (x) == CONST_INT)
1167 if (unsigned_condition (operator) != operator)
1170 if (max != (INTVAL (x) & max)
1171 && INTVAL (x) != 0xff)
1178 /* Returns nonzero if REGNO is the number of a hard
1179 register in which function arguments are sometimes passed. */
1182 function_arg_regno_p(r)
1185 return (r >= 8 && r <= 25);
1188 /* Initializing the variable cum for the state at the beginning
1189 of the argument list. */
1192 init_cumulative_args (cum, fntype, libname, indirect)
1193 CUMULATIVE_ARGS *cum;
1196 int indirect ATTRIBUTE_UNUSED;
1199 cum->regno = FIRST_CUM_REG;
1202 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1203 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1204 != void_type_node));
1210 /* Controls whether a function argument is passed
1211 in a register, and which register. */
1214 function_arg (cum, mode, type, named)
1215 CUMULATIVE_ARGS *cum;
1216 enum machine_mode mode;
1218 int named ATTRIBUTE_UNUSED;
1222 bytes = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
1224 if (cum->nregs && bytes <= cum->nregs)
1225 return gen_rtx (REG, mode, cum->regno - bytes);
1229 /* Update the summarizer variable CUM to advance past an argument
1230 in the argument list. */
1233 function_arg_advance (cum, mode, type, named)
1234 CUMULATIVE_ARGS *cum; /* current arg information */
1235 enum machine_mode mode; /* current arg mode */
1236 tree type; /* type of the argument or 0 if lib support */
1237 int named ATTRIBUTE_UNUSED; /* whether or not the argument was named */
1241 bytes = (mode == BLKmode ? int_size_in_bytes (type) : GET_MODE_SIZE (mode));
1242 cum->nregs -= bytes;
1243 cum->regno -= bytes;
1245 if (cum->nregs <= 0)
1248 cum->regno = FIRST_CUM_REG;
1254 /***********************************************************************
1255 Functions for outputting various mov's for a various modes
1256 ************************************************************************/
1258 out_movqi_r_mr (insn, op, l)
1261 int *l; /* instruction length */
1263 /* We handle CONSTANT_ADDRESS_P case in adjust_insn_length */
1265 if (GET_CODE (op[1]) == MEM)
1267 rtx x = XEXP (op[1],0);
1268 if (GET_CODE (x) == PLUS
1269 && REG_P (XEXP (x,0))
1270 && GET_CODE (XEXP (x,1)) == CONST_INT)
1272 if((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (op[1]))) >= 63)
1274 int disp = INTVAL (XEXP (x,1));
1275 if (REGNO (XEXP (x,0)) != REG_Y)
1276 fatal_insn ("Incorrect insn:",insn);
1277 if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[1])))
1283 op[4] = GEN_INT (disp - 63);
1284 return (AS2 (adiw, r28, %4) CR_TAB
1285 AS2 (ldd, %0,Y+63) CR_TAB
1286 AS2 (sbiw, r28, %4));
1295 return (AS2 (subi, r28, lo8(-%4)) CR_TAB
1296 AS2 (sbci, r29, hi8(-%4)) CR_TAB
1297 AS2 (ld, %0,Y) CR_TAB
1298 AS2 (subi, r28, lo8(%4)) CR_TAB
1299 AS2 (sbci, r29, hi8(%4)));
1302 else if (REGNO (XEXP (x,0)) == REG_X)
1304 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1305 it but I have this situation with extremal optimizing options
1311 output_asm_insn (AS2 (adiw, r26, %0),&XEXP (x,1));
1312 output_asm_insn (AS2 (ld ,%0,X),op);
1313 if (!reg_overlap_mentioned_p (op[0],XEXP (x,0)))
1314 output_asm_insn (AS2 (sbiw, r26, %0),&XEXP (x,1));
1320 return AS2 (ld%K1,%0,%1);
1324 out_movhi_r_mr (insn, op, l)
1327 int *l; /* instruction length */
1329 int reg_dest = true_regnum (op[0]);
1330 int reg_base = true_regnum (XEXP (op[1],0));
1335 l = &tmp, len_p = 0;
1339 if (reg_dest == reg_base) /* R = (R) */
1340 return *l=3, (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1341 AS2 (ld,%B0,%1) CR_TAB
1342 AS2 (mov,%A0,__tmp_reg__));
1343 else if (reg_base == REG_X) /* (R26) */
1345 if (reg_unused_after (insn, XEXP (op[1],0)))
1346 return *l=2, (AS2 (ld,%A0,X+) CR_TAB
1349 return *l=3, (AS2 (ld,%A0,X+) CR_TAB
1350 AS2 (ld,%B0,X) CR_TAB
1354 return *l=2, (AS2 (ld,%A0,%1) CR_TAB
1355 AS2 (ldd,%B0,%1+1));
1357 else if (GET_CODE (XEXP (op[1],0)) == PLUS) /* (R + i) */
1359 int disp = INTVAL(XEXP (XEXP (op[1],0), 1));
1360 int reg_base = true_regnum (XEXP (XEXP (op[1],0), 0));
1362 if (disp > 64 - GET_MODE_SIZE (GET_MODE (op[1])))
1364 rtx x = XEXP (op[1],0);
1365 if (REGNO (XEXP (x,0)) != REG_Y)
1366 fatal_insn ("Incorrect insn:",insn);
1367 if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[1])))
1369 op[4] = GEN_INT (disp - 62);
1370 return *l=4, (AS2 (adiw, r28, %4) CR_TAB
1371 AS2 (ldd, %A0,Y+62) CR_TAB
1372 AS2 (ldd, %B0,Y+63) CR_TAB
1373 AS2 (sbiw, r28, %4));
1378 return *l=6, (AS2 (subi, r28, lo8(-%4)) CR_TAB
1379 AS2 (sbci, r29, hi8(-%4)) CR_TAB
1380 AS2 (ld, %A0,Y) CR_TAB
1381 AS2 (ldd, %B0,Y+1) CR_TAB
1382 AS2 (subi, r28, lo8(%4)) CR_TAB
1383 AS2 (sbci, r29, hi8(%4)));
1386 if (reg_base == REG_X)
1388 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1389 it but I have this situation with extremal optimization options
1392 ops[0] = XEXP (XEXP (op[1],0), 1);
1395 else if (reg_base == reg_dest)
1397 output_asm_insn (AS2 (adiw, r26, %0), ops);
1398 output_asm_insn (AS2 (ld , __tmp_reg__, X+), op);
1399 output_asm_insn (AS2 (ld , %B0, X), op);
1400 output_asm_insn (AS2 (mov, %A0, __tmp_reg__),op);
1404 output_asm_insn (AS2 (adiw, r26, %0), ops);
1405 output_asm_insn (AS2 (ld , %A0, X+), op);
1406 output_asm_insn (AS2 (ld , %B0, X), op);
1407 if (INTVAL (ops[0]) == 63)
1409 output_asm_insn (AS2 (subi, r26, %0+1), ops);
1410 output_asm_insn (AS2 (sbci, r26, 0), ops);
1413 output_asm_insn (AS2 (sbiw, r26, %0+1), ops);
1418 if (reg_base == reg_dest)
1419 return *l=3, (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
1420 AS2 (ldd,%B0,%B1) CR_TAB
1421 AS2 (mov,%A0,__tmp_reg__));
1423 return *l=2, (AS2 (ldd,%A0,%A1) CR_TAB
1426 else if (GET_CODE (XEXP (op[1],0)) == PRE_DEC) /* (--R) */
1428 if (reg_overlap_mentioned_p (op[0], XEXP (XEXP (op[1],0),0)))
1431 fatal ("Internal error. Incorrect insn.");
1433 return *l=2, (AS2 (ld,%B0,%1) CR_TAB
1436 else if (GET_CODE (XEXP (op[1],0)) == POST_INC) /* (R++) */
1438 if (reg_overlap_mentioned_p (op[0], XEXP (XEXP (op[1],0),0)))
1441 fatal ("Internal error. Incorrect insn.");
1443 return *l=2, (AS2 (ld,%A0,%1) CR_TAB
1446 else if (CONSTANT_ADDRESS_P (XEXP (op[1],0)))
1447 return *l=4, (AS2 (lds,%A0,%A1) CR_TAB
1449 fatal_insn ("Unknown move insn:",insn);
1454 out_movsi_r_mr (insn,op,l)
1457 int *l; /* instruction length */
1459 int reg_dest=true_regnum (op[0]);
1460 int reg_base=true_regnum (XEXP (op[1],0));
1466 if (reg_base == REG_X) /* (R26) */
1468 if (reg_dest == REG_X)
1469 return *l=6, (AS2 (adiw,r26,3) CR_TAB
1470 AS2 (ld,%D0,X) CR_TAB
1471 AS2 (ld,%C0,-X) CR_TAB
1472 AS2 (ld,__tmp_reg__,-X) CR_TAB
1473 AS2 (ld,%A0,-X) CR_TAB
1474 AS2 (mov,%B0,__tmp_reg__));
1475 else if (reg_dest == REG_X - 2)
1476 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
1477 AS2 (ld,%B0,X+) CR_TAB
1478 AS2 (ld,__tmp_reg__,X+) CR_TAB
1479 AS2 (ld,%D0,X) CR_TAB
1480 AS2 (mov,%C0,__tmp_reg__));
1481 else if (reg_unused_after (insn,XEXP (op[1],0)))
1482 return *l=4, (AS2 (ld,%A0,X+) CR_TAB
1483 AS2 (ld,%B0,X+) CR_TAB
1484 AS2 (ld,%C0,X+) CR_TAB
1487 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
1488 AS2 (ld,%B0,X+) CR_TAB
1489 AS2 (ld,%C0,X+) CR_TAB
1490 AS2 (ld,%D0,X) CR_TAB
1495 if (reg_dest == reg_base)
1496 return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
1497 AS2 (ldd,%C0,%1+2) CR_TAB
1498 AS2 (ldd,__tmp_reg__,%1+1) CR_TAB
1499 AS2 (ld,%A0,%1) CR_TAB
1500 AS2 (mov,%B0,__tmp_reg__));
1501 else if (reg_base == reg_dest + 2)
1502 return *l=5, (AS2 (ld ,%A0,%1) CR_TAB
1503 AS2 (ldd,%B0,%1+1) CR_TAB
1504 AS2 (ldd,__tmp_reg__,%1+2) CR_TAB
1505 AS2 (ldd,%D0,%1+3) CR_TAB
1506 AS2 (mov,%C0,__tmp_reg__));
1508 return *l=4, (AS2 (ld ,%A0,%1) CR_TAB
1509 AS2 (ldd,%B0,%1+1) CR_TAB
1510 AS2 (ldd,%C0,%1+2) CR_TAB
1511 AS2 (ldd,%D0,%1+3));
1514 else if (GET_CODE (XEXP (op[1],0)) == PLUS) /* (R + i) */
1516 int disp = INTVAL(XEXP (XEXP (op[1],0), 1));
1518 if (disp > 64 - GET_MODE_SIZE (GET_MODE (op[1])))
1520 rtx x = XEXP (op[1],0);
1521 if (REGNO (XEXP (x,0)) != REG_Y)
1522 fatal_insn ("Incorrect insn:",insn);
1523 if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[1])))
1525 op[4] = GEN_INT (disp - 60);
1526 return *l=6,(AS2 (adiw, r28, %4) CR_TAB
1527 AS2 (ldd, %A0,Y+60) CR_TAB
1528 AS2 (ldd, %B0,Y+61) CR_TAB
1529 AS2 (ldd, %C0,Y+62) CR_TAB
1530 AS2 (ldd, %D0,Y+63) CR_TAB
1531 AS2 (sbiw, r28, %4));
1536 return *l=8,(AS2 (subi, r28, lo8(-%4)) CR_TAB
1537 AS2 (sbci, r29, hi8(-%4)) CR_TAB
1538 AS2 (ld, %A0,Y) CR_TAB
1539 AS2 (ldd, %B0,Y+1) CR_TAB
1540 AS2 (ldd, %C0,Y+2) CR_TAB
1541 AS2 (ldd, %D0,Y+3) CR_TAB
1542 AS2 (subi, r28, lo8(%4)) CR_TAB
1543 AS2 (sbci, r29, hi8(%4)));
1547 reg_base = true_regnum (XEXP (XEXP (op[1],0), 0));
1548 if (reg_dest == reg_base)
1549 return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
1550 AS2 (ldd,%C0,%C1) CR_TAB
1551 AS2 (ldd,__tmp_reg__,%B1) CR_TAB
1552 AS2 (ldd,%A0,%A1) CR_TAB
1553 AS2 (mov,%B0,__tmp_reg__));
1554 else if (reg_dest == reg_base - 2)
1555 return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
1556 AS2 (ldd,%B0,%B1) CR_TAB
1557 AS2 (ldd,__tmp_reg__,%C1) CR_TAB
1558 AS2 (ldd,%D0,%D1) CR_TAB
1559 AS2 (mov,%C0,__tmp_reg__));
1560 return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
1561 AS2 (ldd,%B0,%B1) CR_TAB
1562 AS2 (ldd,%C0,%C1) CR_TAB
1565 else if (GET_CODE (XEXP (op[1],0)) == PRE_DEC) /* (--R) */
1566 return *l=4, (AS2 (ld,%D0,%1) CR_TAB
1567 AS2 (ld,%C0,%1) CR_TAB
1568 AS2 (ld,%B0,%1) CR_TAB
1570 else if (GET_CODE (XEXP (op[1],0)) == POST_INC) /* (R++) */
1571 return *l=4, (AS2 (ld,%A0,%1) CR_TAB
1572 AS2 (ld,%B0,%1) CR_TAB
1573 AS2 (ld,%C0,%1) CR_TAB
1575 else if (CONSTANT_ADDRESS_P (XEXP (op[1],0)))
1576 return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
1577 AS2 (lds,%B0,%B1) CR_TAB
1578 AS2 (lds,%C0,%C1) CR_TAB
1581 fatal_insn ("Unknown move insn:",insn);
1586 out_movsi_mr_r (insn,op,l)
1591 int reg_base = true_regnum (XEXP (op[0],0));
1592 int reg_dest = true_regnum (op[1]);
1596 if (CONSTANT_ADDRESS_P (XEXP (op[0],0)))
1597 return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
1598 AS2 (sts,%B0,%B1) CR_TAB
1599 AS2 (sts,%C0,%C1) CR_TAB
1601 if (reg_base > 0) /* (r) */
1603 if (reg_base == REG_X) /* (R26) */
1605 if (reg_dest == REG_X)
1607 if (reg_unused_after (insn,XEXP (op[0],0)))
1608 return *l=5, (AS2 (mov,__tmp_reg__,%B1) CR_TAB
1609 AS2 (st,%0+,%A1) CR_TAB
1610 AS2 (st,%0+,__tmp_reg__) CR_TAB
1611 AS2 (st,%0+,%C1) CR_TAB
1614 return *l=6, (AS2 (mov,__tmp_reg__,%B1) CR_TAB
1615 AS2 (st,%0+,%A1) CR_TAB
1616 AS2 (st,%0+,__tmp_reg__) CR_TAB
1617 AS2 (st,%0+,%C1) CR_TAB
1618 AS2 (st,%0,%D1) CR_TAB
1621 else if (reg_base == reg_dest+2)
1623 if (reg_unused_after (insn,XEXP (op[0],0)))
1624 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
1625 AS2 (mov,__tmp_reg__,%D1) CR_TAB
1626 AS2 (st,%0+,%A1) CR_TAB
1627 AS2 (st,%0+,%B1) CR_TAB
1628 AS2 (st,%0+,__zero_reg__) CR_TAB
1629 AS2 (st,%0,__tmp_reg__) CR_TAB
1630 AS1 (clr,__zero_reg__));
1632 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
1633 AS2 (mov,__tmp_reg__,%D1) CR_TAB
1634 AS2 (st,%0+,%A1) CR_TAB
1635 AS2 (st,%0+,%B1) CR_TAB
1636 AS2 (st,%0+,__zero_reg__) CR_TAB
1637 AS2 (st,%0,__tmp_reg__) CR_TAB
1638 AS1 (clr,__zero_reg__) CR_TAB
1641 return *l=5, (AS2 (st,%0+,%A1) CR_TAB
1642 AS2 (st,%0+,%B1) CR_TAB
1643 AS2 (st,%0+,%C1) CR_TAB
1644 AS2 (st,%0,%D1) CR_TAB
1648 return *l=4, (AS2 (st,%0,%A1) CR_TAB
1649 AS2 (std,%0+1,%B1) CR_TAB
1650 AS2 (std,%0+2,%C1) CR_TAB
1651 AS2 (std,%0+3,%D1));
1653 else if (GET_CODE (XEXP (op[0],0)) == PLUS) /* (R + i) */
1655 int disp = INTVAL(XEXP (XEXP (op[0],0), 1));
1656 if (disp > 64 - GET_MODE_SIZE (GET_MODE (op[0])))
1658 rtx x = XEXP (op[0],0);
1659 if (REGNO (XEXP (x,0)) != REG_Y)
1660 fatal_insn ("Incorrect insn:",insn);
1661 if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[0])))
1663 op[4] = GEN_INT (disp - 60);
1664 return *l=6,(AS2 (adiw, r28, %4) CR_TAB
1665 AS2 (std, Y+60,%A1) CR_TAB
1666 AS2 (std, Y+61,%B1) CR_TAB
1667 AS2 (std, Y+62,%C1) CR_TAB
1668 AS2 (std, Y+63,%D1) CR_TAB
1669 AS2 (sbiw, r28, %4));
1674 return *l=8,(AS2 (subi, r28, lo8(-%4)) CR_TAB
1675 AS2 (sbci, r29, hi8(-%4)) CR_TAB
1676 AS2 (st, Y,%A1) CR_TAB
1677 AS2 (std, Y+1,%B1) CR_TAB
1678 AS2 (std, Y+2,%C1) CR_TAB
1679 AS2 (std, Y+3,%D1) CR_TAB
1680 AS2 (subi, r28, lo8(%4)) CR_TAB
1681 AS2 (sbci, r29, hi8(%4)));
1684 return *l=4, (AS2 (std,%A0,%A1) CR_TAB
1685 AS2 (std,%B0,%B1) CR_TAB
1686 AS2 (std,%C0,%C1) CR_TAB
1689 else if (GET_CODE (XEXP (op[0],0)) == PRE_DEC) /* (--R) */
1690 return *l=4, (AS2 (st,%0,%D1) CR_TAB
1691 AS2 (st,%0,%C1) CR_TAB
1692 AS2 (st,%0,%B1) CR_TAB
1694 else if (GET_CODE (XEXP (op[0],0)) == POST_INC) /* (R++) */
1695 return *l=4, (AS2 (st,%0,%A1) CR_TAB
1696 AS2 (st,%0,%B1) CR_TAB
1697 AS2 (st,%0,%C1) CR_TAB
1699 fatal_insn ("Unknown move insn:",insn);
1704 output_movsisf(insn, operands, which_alternative)
1707 int which_alternative;
1710 switch (which_alternative)
1712 case 0: /* mov r,r */
1713 if (true_regnum (operands[0]) > true_regnum (operands[1]))
1714 return (AS2 (mov,%D0,%D1) CR_TAB
1715 AS2 (mov,%C0,%C1) CR_TAB
1716 AS2 (mov,%B0,%B1) CR_TAB
1719 return (AS2 (mov,%A0,%A1) CR_TAB
1720 AS2 (mov,%B0,%B1) CR_TAB
1721 AS2 (mov,%C0,%C1) CR_TAB
1723 case 1: /* mov r,L */
1724 return (AS1 (clr,%A0) CR_TAB
1725 AS1 (clr,%B0) CR_TAB
1726 AS1 (clr,%C0) CR_TAB
1728 case 2: /* mov r,d */
1729 if (GET_MODE (operands[0]) == SImode
1730 && operands[1] == const1_rtx
1731 && (link = find_reg_note (insn, REG_WAS_0, 0))
1732 /* Make sure the insn that stored the 0 is still present. */
1733 && ! INSN_DELETED_P (XEXP (link, 0))
1734 && GET_CODE (XEXP (link, 0)) != NOTE
1735 /* Make sure cross jumping didn't happen here. */
1736 && no_labels_between_p (XEXP (link, 0), insn)
1737 /* Make sure the reg hasn't been clobbered. */
1738 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1739 /* Fastest way to change a 0 to a 1. */
1740 return AS1 (inc,%A0 ; reg_was_0);
1741 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1742 AS2 (ldi,%B0,hi8(%1)) CR_TAB
1743 AS2 (ldi,%C0,hlo8(%1)) CR_TAB
1744 AS2 (ldi,%D0,hhi8(%1)));
1745 case 3: /* mov r,m*/
1747 return out_movsi_r_mr (insn, operands, NULL);
1748 case 4: /* mov m,r*/
1752 if (operands[1] == const0_rtx)
1754 save1 = operands[1];
1755 operands[1] = zero_reg_rtx;
1757 output_asm_insn (out_movsi_mr_r (insn,operands,NULL), operands);
1759 operands[1] = save1;
1766 out_movqi_mr_r (insn, op, l)
1769 int *l; /* instruction length */
1773 if (GET_CODE (op[0]) == MEM)
1775 rtx x = XEXP (op[0],0);
1776 if (GET_CODE (x) == PLUS
1777 && REG_P (XEXP (x,0))
1778 && GET_CODE (XEXP (x,1)) == CONST_INT)
1780 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (op[0]))) >= 63)
1782 int disp = INTVAL (XEXP (x,1));
1783 if (REGNO (XEXP (x,0)) != REG_Y)
1784 fatal_insn ("Incorrect insn:",insn);
1785 if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[0])))
1791 op[4] = GEN_INT (disp - 63);
1792 return (AS2 (adiw, r28, %4) CR_TAB
1793 AS2 (std, Y+63,%1) CR_TAB
1794 AS2 (sbiw, r28, %4));
1803 return (AS2 (subi, r28, lo8(-%4)) CR_TAB
1804 AS2 (sbci, r29, hi8(-%4)) CR_TAB
1805 AS2 (st, Y,%1) CR_TAB
1806 AS2 (subi, r28, lo8(%4)) CR_TAB
1807 AS2 (sbci, r29, hi8(%4)));
1810 else if (REGNO (XEXP (x,0)) == REG_X)
1816 int overlap_p = reg_overlap_mentioned_p (op[1],XEXP (x,0));
1818 output_asm_insn (AS2 (mov, __tmp_reg__, %1),op);
1819 output_asm_insn (AS2 (adiw, r26,%0),&XEXP (x,1));
1821 output_asm_insn (AS2 (st ,X,__tmp_reg__),op);
1823 output_asm_insn (AS2 (st ,X,%1),op);
1824 output_asm_insn (AS2 (sbiw ,r26,%0),&XEXP (x,1));
1830 return AS2 (st%K0, %0,%1);
1834 out_movhi_mr_r (insn,op,l)
1839 int reg_base = true_regnum (XEXP (op[0],0));
1840 int reg_dest = true_regnum (op[1]);
1844 if (CONSTANT_ADDRESS_P (XEXP (op[0],0)))
1845 return *l=4,(AS2 (sts,%A0,%A1) CR_TAB
1849 if (reg_base == REG_X)
1851 if (reg_dest == REG_X)
1853 if (reg_unused_after (insn, op[1]))
1854 return *l=3, (AS2 (mov,__tmp_reg__,r27) CR_TAB
1855 AS2 (st ,X+,r26) CR_TAB
1856 AS2 (st ,X,__tmp_reg__));
1858 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
1859 AS2 (st ,X+,r26) CR_TAB
1860 AS2 (st ,X,__tmp_reg__) CR_TAB
1865 if (reg_unused_after (insn, XEXP (op[0],0)))
1866 return *l=2, (AS2 (st,X+,%A1) CR_TAB
1869 return *l=3, (AS2 (st ,X+,%A1) CR_TAB
1870 AS2 (st ,X,%B1) CR_TAB
1875 return *l=2, (AS2 (st ,%0,%A1) CR_TAB
1876 AS2 (std,%0+1,%B1));
1878 else if (GET_CODE (XEXP (op[0],0)) == PLUS)
1880 int disp = INTVAL(XEXP (XEXP (op[0],0), 1));
1881 if (disp > 64 - GET_MODE_SIZE (GET_MODE (op[0])))
1883 rtx x = XEXP (op[0],0);
1884 if (REGNO (XEXP (x,0)) != REG_Y)
1885 fatal_insn ("Incorrect insn:",insn);
1886 if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[0])))
1888 op[4] = GEN_INT (disp - 62);
1889 return *l=4,(AS2 (adiw, r28, %4) CR_TAB
1890 AS2 (std, Y+62,%A1) CR_TAB
1891 AS2 (std, Y+63,%B1) CR_TAB
1892 AS2 (sbiw, r28, %4));
1897 return *l=6,(AS2 (subi, r28, lo8(-%4)) CR_TAB
1898 AS2 (sbci, r29, hi8(-%4)) CR_TAB
1899 AS2 (st, Y,%A1) CR_TAB
1900 AS2 (std, Y+1,%B1) CR_TAB
1901 AS2 (subi, r28, lo8(%4)) CR_TAB
1902 AS2 (sbci, r29, hi8(%4)));
1905 return *l=2, (AS2 (std,%A0,%A1) CR_TAB
1908 else if (GET_CODE (XEXP (op[0],0)) == PRE_DEC) /* (--R) */
1909 return *l=2, (AS2 (st,%0,%B1) CR_TAB
1911 else if (GET_CODE (XEXP (op[0],0)) == POST_INC) /* (R++) */
1912 return *l=2, (AS2 (st,%0,%A1) CR_TAB
1914 fatal_insn ("Unknown move insn:",insn);
1918 /* Return 1 if frame pointer for current function required */
1921 frame_pointer_required_p(void)
1923 return (current_function_calls_alloca
1924 || current_function_args_info.nregs == 0
1925 || current_function_varargs
1926 || get_frame_size () > 0);
1929 /* Return 1 if the next insn is a JUMP_INSN with condition (GT,LE,GTU,LTU) */
1932 compare_diff_p (insn)
1935 rtx next = next_real_insn (insn);
1936 RTX_CODE cond = UNKNOWN;
1937 if (GET_CODE (next) == JUMP_INSN)
1939 rtx pat = PATTERN (next);
1940 rtx src = SET_SRC (pat);
1941 rtx t = XEXP (src,0);
1942 cond = GET_CODE (t);
1944 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
1947 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition */
1953 rtx next = next_real_insn (insn);
1954 RTX_CODE cond = UNKNOWN;
1955 if (GET_CODE (next) == JUMP_INSN)
1957 rtx pat = PATTERN (next);
1958 rtx src = SET_SRC (pat);
1959 rtx t = XEXP (src,0);
1960 cond = GET_CODE (t);
1962 return (cond == EQ || cond == NE);
1966 /* Output test instruction for HImode */
1973 if (!compare_eq_p (insn))
1976 return AS1 (tst,%B0);
1978 if (TEST_HARD_REG_CLASS (ADDW_REGS, true_regnum (SET_SRC (PATTERN (insn)))))
1981 return AS2 (sbiw,%0,0);
1983 if (compare_eq_p (insn) && reg_unused_after (insn, SET_SRC (PATTERN (insn))))
1986 return AS2 (or,%A0,%B0);
1989 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
1990 AS2 (cpc,%B0,__zero_reg__));
1994 /* Output test instruction for SImode */
2001 if (!compare_eq_p (insn))
2004 return AS1 (tst,%D0);
2006 if (TEST_HARD_REG_CLASS (ADDW_REGS, true_regnum (SET_SRC (PATTERN (insn)))))
2009 return (AS2 (sbiw,%A0,0) CR_TAB
2010 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2011 AS2 (cpc,%D0,__zero_reg__));
2014 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2015 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2016 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2017 AS2 (cpc,%D0,__zero_reg__));
2021 /* Generate asm equivalent for various shift's.
2022 Shift count are CONST_INT or REG. */
2025 out_shift_with_cnt (template,insn,operands,len)
2034 op[0] = operands[0];
2035 op[1] = operands[1];
2036 op[2] = operands[2];
2037 op[3] = operands[3];
2040 if (CONSTANT_P (operands[2]))
2045 strcat (str, "ldi %3,lo8(%2)");
2047 else if (GET_CODE (operands[2]) == MEM)
2054 op[3] = op_mov[0] = tmp_reg_rtx;
2059 output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2060 strcat (str,(AS2 (or,%3,%3) CR_TAB
2061 AS1 (breq,L_hi%=)));
2065 out_movqi_r_mr (insn, op_mov, &mov_len);
2069 else if (register_operand (operands[2],QImode))
2075 strcat (str, (AS2 (or,%2,%2) CR_TAB
2076 AS1 (breq,L_hi%=)));
2078 if (reg_unused_after (insn, operands[2]))
2084 op[3] = tmp_reg_rtx;
2088 strcat (str, CR_TAB "mov %3,%2");
2093 strcat (str,"\n\t");
2094 strcat (str, template);
2096 strcat (str, "\nL_hi%=:");
2097 output_asm_insn (str, op);
2102 /* 8bit shift left ((char)x << i) */
2105 ashlqi3_out (insn,operands,len)
2108 int *len; /* insn length (may be NULL) */
2110 if (GET_CODE (operands[2]) == CONST_INT)
2116 switch (INTVAL (operands[2]))
2118 default: len = t; break;
2121 return AS1 (lsl,%0);
2124 return (AS1 (lsl,%0) CR_TAB
2128 return (AS1 (lsl,%0) CR_TAB
2132 if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
2135 return (AS1 (swap,%0) CR_TAB
2136 AS2 (andi,%0,0xf0));
2139 return (AS1 (lsl,%0) CR_TAB
2144 if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
2147 return (AS1 (swap,%0) CR_TAB
2149 AS2 (andi,%0,0xe0));
2152 return (AS1 (lsl,%0) CR_TAB
2158 if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
2161 return (AS1 (swap,%0) CR_TAB
2164 AS2 (andi,%0,0xc0));
2167 return (AS1 (lsl,%0) CR_TAB
2175 return (AS1 (ror,%0) CR_TAB
2182 out_shift_with_cnt (AS1 (lsl,%0) CR_TAB
2185 insn, operands, len);
2190 /* 16bit shift left ((short)x << i) */
2193 ashlhi3_out (insn,operands,len)
2198 if (GET_CODE (operands[2]) == CONST_INT)
2204 switch (INTVAL (operands[2]))
2206 default: len = t; break;
2209 return (AS1 (lsl,%A0) CR_TAB
2213 return (AS1 (lsl,%A0) CR_TAB
2214 AS1 (rol,%B0) CR_TAB
2218 if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
2219 return *len = 1, AS1 (clr,%A0);
2221 return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
2227 out_shift_with_cnt (AS1 (lsl,%0) CR_TAB
2228 AS1 (rol,%B0) CR_TAB
2231 insn, operands, len);
2236 /* 32bit shift left ((long)x << i) */
2239 ashlsi3_out (insn,operands,len)
2244 if (GET_CODE (operands[2]) == CONST_INT)
2250 switch (INTVAL (operands[2]))
2252 default: len = t; break;
2255 return (AS1 (lsl,%A0) CR_TAB
2256 AS1 (rol,%B0) CR_TAB
2257 AS1 (rol,%C0) CR_TAB
2261 int reg0 = true_regnum (operands[0]);
2262 int reg1 = true_regnum (operands[1]);
2265 return (AS2 (mov,%D0,%C1) CR_TAB
2266 AS2 (mov,%C0,%B1) CR_TAB
2267 AS2 (mov,%B0,%A1) CR_TAB
2269 else if (reg0 + 1 == reg1)
2270 return *len = 1, AS1 (clr,%A0);
2272 return (AS1 (clr,%A0) CR_TAB
2273 AS2 (mov,%B0,%A1) CR_TAB
2274 AS2 (mov,%C0,%B1) CR_TAB
2279 int reg0 = true_regnum (operands[0]);
2280 int reg1 = true_regnum (operands[1]);
2282 if (reg0 + 1 >= reg1)
2283 return (AS2 (mov,%D0,%B1) CR_TAB
2284 AS2 (mov,%C0,%A1) CR_TAB
2285 AS1 (clr,%B0) CR_TAB
2287 if (reg0 + 2 == reg1)
2288 return *len = 2, (AS1 (clr,%B0) CR_TAB
2291 return (AS2 (mov,%C0,%A1) CR_TAB
2292 AS2 (mov,%D0,%B1) CR_TAB
2293 AS1 (clr,%B0) CR_TAB
2298 if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
2299 return (AS2 (mov,%D0,%A1) CR_TAB
2300 AS1 (clr,%C0) CR_TAB
2301 AS1 (clr,%B0) CR_TAB
2304 return *len = 3, (AS1 (clr,%C0) CR_TAB
2305 AS1 (clr,%B0) CR_TAB
2311 out_shift_with_cnt (AS1 (lsl,%0) CR_TAB
2312 AS1 (rol,%B0) CR_TAB
2313 AS1 (rol,%C0) CR_TAB
2314 AS1 (rol,%D0) CR_TAB
2317 insn, operands, len);
2321 /* 8bit arithmetic shift right ((signed char)x >> i) */
2324 ashrqi3_out (insn,operands,len)
2327 int *len; /* insn length */
2329 if (GET_CODE (operands[2]) == CONST_INT)
2335 switch (INTVAL (operands[2]))
2337 default: len = t; break;
2340 return AS1 (asr,%0);
2343 return (AS1 (asr,%0) CR_TAB
2347 return (AS1 (asr,%0) CR_TAB
2352 return (AS1 (asr,%0) CR_TAB
2360 out_shift_with_cnt (AS1 (asr,%0) CR_TAB
2363 insn, operands, len);
2368 /* 16bit arithmetic shift right ((signed short)x >> i) */
2371 ashrhi3_out (insn,operands,len)
2376 if (GET_CODE (operands[2]) == CONST_INT)
2382 switch (INTVAL (operands[2]))
2384 default: len = t; break;
2387 return (AS1 (asr,%B0) CR_TAB
2391 return (AS1 (asr,%B0) CR_TAB
2392 AS1 (ror,%A0) CR_TAB
2393 AS1 (asr,%B0) CR_TAB
2396 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
2397 return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
2398 AS1 (clr,%B0) CR_TAB
2399 AS2 (sbrc,%A0,7) CR_TAB
2402 return *len = 3, (AS1 (clr,%B0) CR_TAB
2403 AS2 (sbrc,%A0,7) CR_TAB
2409 out_shift_with_cnt (AS1 (asr,%B0) CR_TAB
2410 AS1 (ror,%A0) CR_TAB
2413 insn, operands, len);
2418 /* 32bit arithmetic shift right ((signed long)x >> i) */
2421 ashrsi3_out (insn,operands,len)
2426 if (GET_CODE (operands[2]) == CONST_INT)
2432 switch (INTVAL (operands[2]))
2434 default: len = t; break;
2437 return (AS1 (asr,%D0) CR_TAB
2438 AS1 (ror,%C0) CR_TAB
2439 AS1 (ror,%B0) CR_TAB
2443 int reg0 = true_regnum (operands[0]);
2444 int reg1 = true_regnum (operands[1]);
2447 return (AS2 (mov,%A0,%B1) CR_TAB
2448 AS2 (mov,%B0,%C1) CR_TAB
2449 AS2 (mov,%C0,%D1) CR_TAB
2450 AS1 (clr,%D0) CR_TAB
2451 AS2 (sbrc,%C0,7) CR_TAB
2453 else if (reg0 == reg1 + 1)
2454 return *len = 3, (AS1 (clr,%D0) CR_TAB
2455 AS2 (sbrc,%C0,7) CR_TAB
2458 return (AS1 (clr,%D0) CR_TAB
2459 AS2 (sbrc,%C0,7) CR_TAB
2460 AS1 (dec,%D0) CR_TAB
2461 AS2 (mov,%C0,%D1) CR_TAB
2462 AS2 (mov,%B0,%C1) CR_TAB
2467 int reg0 = true_regnum (operands[0]);
2468 int reg1 = true_regnum (operands[1]);
2470 if (reg0 <= reg1 + 1)
2471 return (AS2 (mov,%A0,%C1) CR_TAB
2472 AS2 (mov,%B0,%D1) CR_TAB
2473 AS1 (clr,%D0) CR_TAB
2474 AS2 (sbrc,%B0,7) CR_TAB
2475 AS1 (com,%D0) CR_TAB
2477 else if (reg0 == reg1 + 2)
2478 return *len = 4, (AS1 (clr,%D0) CR_TAB
2479 AS2 (sbrc,%B0,7) CR_TAB
2480 AS1 (com,%D0) CR_TAB
2483 return (AS2 (mov,%B0,%D1) CR_TAB
2484 AS2 (mov,%A0,%C1) CR_TAB
2485 AS1 (clr,%D0) CR_TAB
2486 AS2 (sbrc,%B0,7) CR_TAB
2487 AS1 (com,%D0) CR_TAB
2491 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
2492 return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
2493 AS1 (clr,%D0) CR_TAB
2494 AS2 (sbrc,%A0,7) CR_TAB
2495 AS1 (com,%D0) CR_TAB
2496 AS2 (mov,%B0,%D0) CR_TAB
2499 return *len = 5, (AS1 (clr,%D0) CR_TAB
2500 AS2 (sbrc,%A0,7) CR_TAB
2501 AS1 (com,%D0) CR_TAB
2502 AS2 (mov,%B0,%D0) CR_TAB
2508 out_shift_with_cnt (AS1 (asr,%D0) CR_TAB
2509 AS1 (ror,%C0) CR_TAB
2510 AS1 (ror,%B0) CR_TAB
2511 AS1 (ror,%A0) CR_TAB
2514 insn, operands, len);
2518 /* 8bit logic shift right ((unsigned char)x >> i) */
2521 lshrqi3_out (insn,operands,len)
2526 if (GET_CODE (operands[2]) == CONST_INT)
2532 switch (INTVAL (operands[2]))
2534 default: len = t; break;
2537 return AS1 (lsr,%0);
2540 return (AS1 (lsr,%0) CR_TAB
2544 return (AS1 (lsr,%0) CR_TAB
2548 if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
2551 return (AS1 (swap,%0) CR_TAB
2552 AS2 (andi,%0,0x0f));
2555 return (AS1 (lsr,%0) CR_TAB
2560 if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
2563 return (AS1 (swap,%0) CR_TAB
2568 return (AS1 (lsr,%0) CR_TAB
2574 if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
2577 return (AS1 (swap,%0) CR_TAB
2583 return (AS1 (lsr,%0) CR_TAB
2591 return (AS1 (rol,%0) CR_TAB
2598 out_shift_with_cnt (AS1 (lsr,%0) CR_TAB
2601 insn, operands, len);
2605 /* 16bit logic shift right ((unsigned short)x >> i) */
2608 lshrhi3_out (insn,operands,len)
2613 if (GET_CODE (operands[2]) == CONST_INT)
2619 switch (INTVAL (operands[2]))
2621 default: len = t; break;
2624 return (AS1 (lsr,%B0) CR_TAB
2628 return (AS1 (lsr,%B0) CR_TAB
2629 AS1 (ror,%A0) CR_TAB
2630 AS1 (lsr,%B0) CR_TAB
2633 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
2634 return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
2637 return *len = 1, AS1 (clr,%B0);
2643 out_shift_with_cnt (AS1 (lsr,%B0) CR_TAB
2644 AS1 (ror,%A0) CR_TAB
2647 insn, operands, len);
2651 /* 32bit logic shift right ((unsigned int)x >> i) */
2654 lshrsi3_out (insn,operands,len)
2659 if (GET_CODE (operands[2]) == CONST_INT)
2665 switch (INTVAL (operands[2]))
2667 default: len = t; break;
2670 return (AS1 (lsr,%D0) CR_TAB
2671 AS1 (ror,%C0) CR_TAB
2672 AS1 (ror,%B0) CR_TAB
2676 int reg0 = true_regnum (operands[0]);
2677 int reg1 = true_regnum (operands[1]);
2680 return (AS2 (mov,%A0,%B1) CR_TAB
2681 AS2 (mov,%B0,%C1) CR_TAB
2682 AS2 (mov,%C0,%D1) CR_TAB
2684 else if (reg0 == reg1 + 1)
2685 return *len = 1, AS1 (clr,%D0);
2687 return (AS1 (clr,%D0) CR_TAB
2688 AS2 (mov,%C0,%D1) CR_TAB
2689 AS2 (mov,%B0,%C1) CR_TAB
2694 int reg0 = true_regnum (operands[0]);
2695 int reg1 = true_regnum (operands[1]);
2697 if (reg0 <= reg1 + 1)
2698 return (AS2 (mov,%A0,%C1) CR_TAB
2699 AS2 (mov,%B0,%D1) CR_TAB
2700 AS1 (clr,%C0) CR_TAB
2702 else if (reg0 == reg1 + 2)
2703 return *len = 2, (AS1 (clr,%C0) CR_TAB
2706 return (AS2 (mov,%B0,%D1) CR_TAB
2707 AS2 (mov,%A0,%C1) CR_TAB
2708 AS1 (clr,%C0) CR_TAB
2712 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
2713 return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
2714 AS1 (clr,%B0) CR_TAB
2715 AS1 (clr,%C0) CR_TAB
2718 return *len = 3, (AS1 (clr,%B0) CR_TAB
2719 AS1 (clr,%C0) CR_TAB
2725 out_shift_with_cnt (AS1 (lsr,%D0) CR_TAB
2726 AS1 (ror,%C0) CR_TAB
2727 AS1 (ror,%B0) CR_TAB
2728 AS1 (ror,%A0) CR_TAB
2731 insn, operands, len);
2735 /* Modifies the length assigned to instruction INSN
2736 LEN is the initially computed length of the insn. */
2739 adjust_insn_length (insn,len)
2743 rtx patt = PATTERN (insn);
2745 if (GET_CODE (patt) == SET)
2748 op[1] = SET_SRC (patt);
2749 op[0] = SET_DEST (patt);
2750 if (REG_P (op[0]) && GET_CODE (op[1]) == MEM)
2752 if (CONSTANT_ADDRESS_P (XEXP (op[1],0)))
2753 switch (GET_MODE (op[0]))
2755 case QImode: len = 2; break;
2756 case HImode: len = 4; break;
2758 case SFmode: len = 8; break;
2762 switch (GET_MODE (op[0]))
2764 case QImode: out_movqi_r_mr (insn,op,&len); break;
2765 case HImode: out_movhi_r_mr (insn,op,&len); break;
2767 case SFmode: out_movsi_r_mr (insn,op,&len); break;
2771 else if ((REG_P (op[1]) || const0_rtx == op[1])
2772 && GET_CODE (op[0]) == MEM)
2774 if (CONSTANT_ADDRESS_P (XEXP (op[0],0)))
2775 switch (GET_MODE (op[0]))
2777 case QImode: len = 2; break;
2778 case HImode: len = 4; break;
2780 case SFmode: len = 8; break;
2783 else if (GET_CODE (XEXP (op[0],0)) != POST_DEC)
2784 switch (GET_MODE (op[0]))
2786 case QImode: out_movqi_mr_r (insn,op,&len); break;
2787 case HImode: out_movhi_mr_r (insn,op,&len); break;
2789 case SFmode: out_movsi_mr_r (insn,op,&len); break;
2793 else if (op[0] == cc0_rtx && REG_P (op[1]))
2795 switch (GET_MODE (op[1]))
2797 case HImode: out_tsthi (insn,&len); break;
2798 case SImode: out_tstsi (insn,&len); break;
2802 else if (GET_CODE (op[1]) == AND)
2804 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
2806 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
2807 if (GET_MODE (op[1]) == SImode)
2808 len = (((mask & 0xff) != 0xff)
2809 + ((mask & 0xff00) != 0xff00)
2810 + ((mask & 0xff0000UL) != 0xff0000UL)
2811 + ((mask & 0xff000000UL) != 0xff000000UL));
2812 else if (GET_MODE (op[1]) == HImode)
2813 len = (((mask & 0xff) != 0xff)
2814 + ((mask & 0xff00) != 0xff00));
2817 else if (GET_CODE (op[1]) == IOR)
2819 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
2821 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
2822 if (GET_MODE (op[1]) == SImode)
2823 len = (((mask & 0xff) == 0)
2824 + ((mask & 0xff00) == 0)
2825 + ((mask & 0xff0000UL) == 0)
2826 + ((mask & 0xff000000UL) ==0));
2827 else if (GET_MODE (op[1]) == HImode)
2828 len = (((mask & 0xff) == 0)
2829 + ((mask & 0xff00) == 0));
2833 set = single_set (insn);
2837 op[1] = SET_SRC (set);
2838 op[0] = SET_DEST (set);
2839 if (GET_CODE (op[1]) == ASHIFT
2840 || GET_CODE (op[1]) == ASHIFTRT
2841 || GET_CODE (op[1]) == LSHIFTRT)
2845 ops[1] = XEXP (op[1],0);
2846 ops[2] = XEXP (op[1],1);
2847 switch (GET_CODE (op[1]))
2850 switch (GET_MODE (op[0]))
2852 case QImode: ashlqi3_out (insn,ops,&len); break;
2853 case HImode: ashlhi3_out (insn,ops,&len); break;
2854 case SImode: ashlsi3_out (insn,ops,&len); break;
2859 switch (GET_MODE (op[0]))
2861 case QImode: ashrqi3_out (insn,ops,&len); break;
2862 case HImode: ashrhi3_out (insn,ops,&len); break;
2863 case SImode: ashrsi3_out (insn,ops,&len); break;
2868 switch (GET_MODE (op[0]))
2870 case QImode: lshrqi3_out (insn,ops,&len); break;
2871 case HImode: lshrhi3_out (insn,ops,&len); break;
2872 case SImode: lshrsi3_out (insn,ops,&len); break;
2884 /* Return non-zero if register REG dead after INSN */
2887 reg_unused_after (insn, reg)
2892 /* In egcs 1.1.x dead_or_set_p give buggy result after reload
2893 #ifdef PRESERVE_DEATH_INFO_REGNO_P
2894 || dead_or_set_p (insn,reg)
2898 || (REG_P(reg) && _reg_unused_after (insn, reg)));
2901 /* Return non-zero if REG is not used after INSN.
2902 We assume REG is a reload reg, and therefore does
2903 not live past labels. It may live past calls or jumps though. */
2906 _reg_unused_after (insn, reg)
2913 /* If the reg is set by this instruction, then it is safe for our
2914 case. Disregard the case where this is a store to memory, since
2915 we are checking a register used in the store address. */
2916 set = single_set (insn);
2917 if (set && GET_CODE (SET_DEST (set)) != MEM
2918 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
2921 while ((insn = NEXT_INSN (insn)))
2923 code = GET_CODE (insn);
2926 /* If this is a label that existed before reload, then the register
2927 if dead here. However, if this is a label added by reorg, then
2928 the register may still be live here. We can't tell the difference,
2929 so we just ignore labels completely. */
2930 if (code == CODE_LABEL)
2935 if (code == JUMP_INSN)
2938 /* If this is a sequence, we must handle them all at once.
2939 We could have for instance a call that sets the target register,
2940 and a insn in a delay slot that uses the register. In this case,
2941 we must return 0. */
2942 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
2947 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2949 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
2950 rtx set = single_set (this_insn);
2952 if (GET_CODE (this_insn) == CALL_INSN)
2954 else if (GET_CODE (this_insn) == JUMP_INSN)
2956 if (INSN_ANNULLED_BRANCH_P (this_insn))
2961 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
2963 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
2965 if (GET_CODE (SET_DEST (set)) != MEM)
2971 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
2976 else if (code == JUMP_INSN)
2980 if (code == CALL_INSN)
2983 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
2984 if (GET_CODE (XEXP (tem, 0)) == USE
2985 && REG_P (XEXP (XEXP (tem, 0), 0))
2986 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
2988 if (call_used_regs[REGNO (reg)])
2992 if (GET_RTX_CLASS (code) == 'i')
2994 rtx set = single_set (insn);
2996 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
2998 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
2999 return GET_CODE (SET_DEST (set)) != MEM;
3000 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
3007 /* Output rtx VALUE as .byte to file FILE */
3010 asm_output_char(file,value)
3014 fprintf (file, "\t.byte ");
3015 output_addr_const (file, value);
3016 fprintf (file, "\n");
3020 /* Output VALUE as .byte to file FILE */
3023 asm_output_byte (file,value)
3027 fprintf (file, "\t.byte 0x%x\n",value & 0xff);
3031 /* Output rtx VALUE as .word to file FILE */
3034 asm_output_short (file, value)
3038 if (SYMBOL_REF_FLAG (value) || GET_CODE (value) == LABEL_REF)
3040 fprintf (file, "\t.word pm(");
3041 output_addr_const (file, (value));
3042 fprintf (file, ")\n");
3046 fprintf (file, "\t.word ");
3047 output_addr_const (file, (value));
3048 fprintf (file, "\n");
3053 /* Output real N to file FILE */
3056 asm_output_float (file, n)
3063 REAL_VALUE_TO_TARGET_SINGLE (n, val);
3064 REAL_VALUE_TO_DECIMAL (n, "%g", dstr);
3065 fprintf (file, "\t.long 0x%08lx\t/* %s */\n",val, dstr);
3068 /* Sets section name for declaration DECL */
3071 unique_section (decl, reloc)
3073 int reloc ATTRIBUTE_UNUSED;
3078 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
3079 /* Strip off any encoding in name. */
3080 STRIP_NAME_ENCODING (name, name);
3082 if (TREE_CODE (decl) == FUNCTION_DECL)
3084 if (flag_function_sections)
3090 fatal ("Strange situation: unique section is not a FUNCTION_DECL");
3092 if (flag_function_sections)
3094 len = strlen (name) + strlen (prefix);
3095 string = alloca (len + 1);
3096 sprintf (string, "%s%s", prefix, name);
3097 DECL_SECTION_NAME (decl) = build_string (len, string);
3102 /* Output section name to file FILE */
3105 asm_output_section_name(file, decl, name, reloc)
3107 tree decl ATTRIBUTE_UNUSED;
3109 int reloc ATTRIBUTE_UNUSED;
3111 fprintf (file, ".section %s\n", name);
3115 /* The routine used to output NUL terminated strings. We use a special
3116 version of this for most svr4 targets because doing so makes the
3117 generated assembly code more compact (and thus faster to assemble)
3118 as well as more readable, especially for targets like the i386
3119 (where the only alternative is to output character sequences as
3120 comma separated lists of numbers). */
3123 gas_output_limited_string(file, str)
3124 FILE * file ATTRIBUTE_UNUSED;
3127 unsigned char *_limited_str = (unsigned char *) str;
3129 fprintf (file, "\t%s\t\"", STRING_ASM_OP);
3130 for (; (ch = *_limited_str); _limited_str++)
3133 switch (escape = ESCAPES[ch])
3139 fprintf (file, "\\%03o", ch);
3143 putc (escape, file);
3147 fprintf (file, "\"\n");
3150 /* The routine used to output sequences of byte values. We use a special
3151 version of this for most svr4 targets because doing so makes the
3152 generated assembly code more compact (and thus faster to assemble)
3153 as well as more readable. Note that if we find subparts of the
3154 character sequence which end with NUL (and which are shorter than
3155 STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
3158 gas_output_ascii(file, str, length)
3163 unsigned char *_ascii_bytes = (unsigned char *) str;
3164 unsigned char *limit = _ascii_bytes + length;
3165 unsigned bytes_in_chunk = 0;
3166 for (; _ascii_bytes < limit; _ascii_bytes++)
3168 register unsigned char *p;
3169 if (bytes_in_chunk >= 60)
3171 fprintf (file, "\"\n");
3174 for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
3176 if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
3178 if (bytes_in_chunk > 0)
3180 fprintf (file, "\"\n");
3183 gas_output_limited_string (file, _ascii_bytes);
3190 if (bytes_in_chunk == 0)
3191 fprintf (file, "\t.ascii\t\"");
3192 switch (escape = ESCAPES[ch = *_ascii_bytes])
3199 fprintf (file, "\\%03o", ch);
3200 bytes_in_chunk += 4;
3204 putc (escape, file);
3205 bytes_in_chunk += 2;
3210 if (bytes_in_chunk > 0)
3211 fprintf (file, "\"\n");
3214 /* Return value is nonzero if pseudos that have been
3215 assigned to registers of class CLASS would likely be spilled
3216 because registers of CLASS are needed for spill registers. */
3219 class_likely_spilled_p(int c)
3221 return (c != ALL_REGS && c != ADDW_REGS);
3224 /* Only `progmem' attribute valid for type. */
3227 valid_machine_type_attribute(type, attributes, identifier, args)
3228 tree type ATTRIBUTE_UNUSED;
3229 tree attributes ATTRIBUTE_UNUSED;
3231 tree args ATTRIBUTE_UNUSED;
3233 return is_attribute_p ("progmem", identifier);
3236 /* If IDENTIFIER with arguments ARGS is a valid machine specific
3237 attribute for DECL return 1.
3239 progmem - put data to program memory;
3240 signal - make a function to be hardware interrupt. After function
3241 epilogue interrupts are disabled;
3242 interrupt - make a function to be hardware interrupt. After function
3243 epilogue interrupts are enabled;
3244 naked - don't generate function prologue/epilogue and `ret' command. */
3247 valid_machine_decl_attribute (decl, attributes, attr, args)
3249 tree attributes ATTRIBUTE_UNUSED;
3251 tree args ATTRIBUTE_UNUSED;
3253 if (is_attribute_p ("interrupt", attr)
3254 || is_attribute_p ("signal", attr)
3255 || is_attribute_p ("naked", attr))
3256 return TREE_CODE (decl) == FUNCTION_DECL;
3258 if (is_attribute_p ("progmem", attr)
3259 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
3261 if (DECL_INITIAL (decl) == NULL_TREE)
3263 warning ("Only initialized variables can be placed into "
3264 "program memory area.");
3273 /* Look for attribute `progmem' in DECL
3274 founded - 1 otherwise 0 */
3277 avr_progmem_p (decl)
3282 if (TREE_CODE (decl) != VAR_DECL)
3286 != lookup_attribute ("progmem", DECL_MACHINE_ATTRIBUTES (decl)))
3292 while (TREE_CODE (a) == ARRAY_TYPE);
3294 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
3300 /* Encode section information about tree DECL */
3303 encode_section_info (decl)
3306 if ((TREE_STATIC (decl) || DECL_EXTERNAL (decl))
3307 && TREE_CODE (decl) == VAR_DECL
3308 && avr_progmem_p (decl))
3310 char * dsec = ".progmem.data";
3311 DECL_SECTION_NAME (decl) = build_string (strlen (dsec), dsec);
3315 /* Outputs to the stdio stream FILE some
3316 appropriate text to go at the start of an assembler file. */
3319 asm_file_start (file)
3322 output_file_directive (file, main_input_filename);
3323 fprintf (file, "\t.arch %s\n", avr_mcu_type->name);
3324 fputs ("__SREG__ = 0x3f\n"
3326 "__SP_L__ = 0x3d\n", file);
3329 initial_stack = avr_ram_end;
3332 static char buf[30];
3333 initial_stack = buf;
3334 sprintf (buf, "0x%x", avr_mcu_type->stack);
3337 fputs ("__tmp_reg__ = r0\n"
3338 "__zero_reg__ = r1\n"
3339 "_PC_ = 2\n", file);
3341 commands_in_file = 0;
3342 commands_in_prologues = 0;
3343 commands_in_epilogues = 0;
3346 /* Outputs to the stdio stream FILE some
3347 appropriate text to go at the end of an assembler file. */
3354 "/* File %s: code %4d (%4d), prologues %3d, epilogues %3d */\n",
3355 main_input_filename,
3357 commands_in_file - commands_in_prologues - commands_in_epilogues,
3358 commands_in_prologues, commands_in_epilogues);
3361 /* Choose the order in which to allocate hard registers for
3362 pseudo-registers local to a basic block.
3364 Store the desired register order in the array `reg_alloc_order'.
3365 Element 0 should be the register to allocate first; element 1, the
3366 next register; and so on. */
3369 order_regs_for_local_alloc (void)
3380 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
3392 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
3405 15,14,13,12,11,10,9,8,7,6,5,4,3,2,
3410 int *order = (TARGET_ORDER_1 ? order_1 :
3411 TARGET_ORDER_2 ? order_2 :
3413 for (i=0; i < sizeof (order_0) / sizeof (order_0[0]); ++i)
3414 reg_alloc_order[i] = order[i];
3417 /* Calculate the cost of X code of the expression in which it is contained,
3418 found in OUTER_CODE */
3421 default_rtx_costs (X, code, outer_code)
3424 enum rtx_code outer_code;
3431 cost = 2 * GET_MODE_SIZE (GET_MODE (X));
3434 if (outer_code != SET)
3436 if (GET_CODE (XEXP (X,0)) == SYMBOL_REF)
3437 cost += 2 * GET_MODE_SIZE (GET_MODE (X));
3439 cost += GET_MODE_SIZE (GET_MODE (X));
3445 if (outer_code == SET)
3446 cost = GET_MODE_SIZE (GET_MODE (X));
3448 cost = -GET_MODE_SIZE (GET_MODE (X));
3451 if (outer_code == SET)
3452 cost = GET_MODE_SIZE (GET_MODE (X));
3458 if (outer_code == SET)
3460 if (X == stack_pointer_rtx)
3462 else if (GET_CODE (XEXP (X,1)) == CONST_INT)
3463 cost = (INTVAL (XEXP (X,1)) <= 63 ? 1 :
3464 GET_MODE_SIZE (GET_MODE (X)));
3466 cost = GET_MODE_SIZE (GET_MODE (X));
3470 if (GET_CODE (XEXP (X,1)) == CONST_INT)
3471 cost = GET_MODE_SIZE (GET_MODE (XEXP (X,0)));
3479 /* Calculate the cost of a memory address */
3482 address_cost (rtx x)
3484 if (GET_CODE (x) == PLUS
3485 && GET_CODE (XEXP (x,1)) == CONST_INT
3486 && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
3487 && INTVAL (XEXP (x,1)) >= 61)
3489 if (CONSTANT_ADDRESS_P (x))
3494 /* EXTRA_CONSTRAINT helper */
3497 extra_constraint (x,c)
3502 && GET_CODE (x) == MEM
3503 && GET_CODE (XEXP (x,0)) == PLUS)
3505 if (TARGET_ALL_DEBUG)
3507 fprintf (stderr, ("extra_constraint:\n"
3508 "reload_completed: %d\n"
3509 "reload_in_progress: %d\n"),
3510 reload_completed, reload_in_progress);
3513 if (GET_CODE (x) == MEM
3514 && GET_CODE (XEXP (x,0)) == PLUS
3515 && REG_P (XEXP (XEXP (x,0), 0))
3516 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
3517 && (INTVAL (XEXP (XEXP (x,0), 1))
3518 <= (64 - GET_MODE_SIZE (GET_MODE (x)))))
3520 rtx xx = XEXP (XEXP (x,0), 0);
3521 int regno = REGNO (xx);
3522 if (TARGET_ALL_DEBUG)
3524 fprintf (stderr, ("extra_constraint:\n"
3525 "reload_completed: %d\n"
3526 "reload_in_progress: %d\n"),
3527 reload_completed, reload_in_progress);
3530 if (regno >= FIRST_PSEUDO_REGISTER)
3531 return 1; /* allocate pseudos */
3532 else if (regno == REG_Z || regno == REG_Y)
3533 return 1; /* strictly check */
3534 else if (xx == frame_pointer_rtx
3535 || xx == arg_pointer_rtx)
3536 return 1; /* XXX frame & arg pointer checks */
3542 /* Convert condition code CONDITION to the valid AVR condition code */
3545 avr_normalize_condition (condition)
3559 fatal ("Wrong condition: %s", GET_RTX_NAME (condition));
3563 /* This fnction optimizes conditional jumps */
3566 machine_dependent_reorg (first_insn)
3572 for (insn = first_insn; insn; insn = NEXT_INSN (insn))
3574 if (! (insn == 0 || GET_CODE (insn) == INSN
3575 || GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN)
3576 || !single_set (insn))
3579 pattern = PATTERN (insn);
3581 cc_prev_status = cc_status;
3582 NOTICE_UPDATE_CC (pattern, insn);
3584 if (GET_CODE (pattern) == PARALLEL)
3585 pattern = XVECEXP (pattern, 0, 0);
3586 if (GET_CODE (pattern) == SET
3587 && SET_DEST (pattern) == cc0_rtx
3588 && compare_diff_p (insn))
3590 if (GET_CODE (SET_SRC (pattern)) == COMPARE)
3592 /* Now we work under compare insn */
3594 pattern = SET_SRC (pattern);
3595 if (true_regnum (XEXP (pattern,0)) >= 0
3596 && true_regnum (XEXP (pattern,1)) >= 0 )
3598 rtx x = XEXP (pattern,0);
3599 rtx next = next_real_insn (insn);
3600 rtx pat = PATTERN (next);
3601 rtx src = SET_SRC (pat);
3602 rtx t = XEXP (src,0);
3603 PUT_CODE (t, swap_condition (GET_CODE (t)));
3604 XEXP (pattern,0) = XEXP (pattern,1);
3605 XEXP (pattern,1) = x;
3606 INSN_CODE (next) = -1;
3608 else if (true_regnum (XEXP (pattern,0)) >= 0
3609 && GET_CODE (XEXP (pattern,1)) == CONST_INT)
3611 rtx x = XEXP (pattern,1);
3612 rtx next = next_real_insn (insn);
3613 rtx pat = PATTERN (next);
3614 rtx src = SET_SRC (pat);
3615 rtx t = XEXP (src,0);
3617 if (avr_simplify_comparision_p (GET_MODE (XEXP (pattern,0)),
3620 XEXP (pattern,1) = GEN_INT (INTVAL (x)+1);
3621 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
3622 INSN_CODE (next) = -1;
3623 INSN_CODE (insn) = -1;
3627 else if (true_regnum (SET_SRC (pattern)) >= 0)
3629 /* This is a tst insn */
3630 rtx next = next_real_insn (insn);
3631 rtx pat = PATTERN (next);
3632 rtx src = SET_SRC (pat);
3633 rtx t = XEXP (src,0);
3635 if (!(cc_prev_status.value1 != 0 && cc_status.value1 != 0
3636 && rtx_equal_p (cc_status.value1, cc_prev_status.value1)))
3638 PUT_CODE (t, swap_condition (GET_CODE (t)));
3639 SET_SRC (pattern) = gen_rtx (NEG,
3640 GET_MODE (SET_SRC (pattern)),
3642 INSN_CODE (next) = -1;
3643 INSN_CODE (insn) = -1;
3650 /* Returns register number for function return value.*/
3653 avr_ret_register (void)
3658 /* Ceate an RTX representing the place where a
3659 library function returns a value of mode MODE. */
3662 avr_libcall_value (mode)
3663 enum machine_mode mode;
3665 int offs = GET_MODE_SIZE (mode);
3668 return gen_rtx (REG, mode, RET_REGISTER + 2 - offs);
3671 /* Create an RTX representing the place where a
3672 function returns a value of data type VALTYPE. */
3675 avr_function_value (type,func)
3677 tree func ATTRIBUTE_UNUSED;
3680 if (TYPE_MODE (type) != BLKmode)
3681 return avr_libcall_value (TYPE_MODE (type));
3683 offs = int_size_in_bytes (type);
3686 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
3687 offs = GET_MODE_SIZE (SImode);
3688 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
3689 offs = GET_MODE_SIZE (DImode);
3691 return gen_rtx (REG, BLKmode, RET_REGISTER + 2 - offs);
3694 /* Returns non-zero if number MASK have only one setted bit */
3697 mask_one_bit_p (mask)
3701 unsigned HOST_WIDE_INT n=mask;
3702 for (i = 0; i < 32; ++i)
3704 if (n & 0x80000000UL)
3706 if (n & 0x7fffffffUL)
3717 /* Places additional restrictions on the register class to
3718 use when it is necessary to copy value X into a register
3722 preferred_reload_class(x,class)
3724 enum reg_class class;
3726 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0)
3728 if (CONSTANT_P (x) && (class == NO_LD_REGS
3729 || class == ALL_REGS
3730 || class == GENERAL_REGS))
3738 debug_hard_reg_set (HARD_REG_SET set)
3741 for (i=0; i < FIRST_PSEUDO_REGISTER; ++i)
3743 if (TEST_HARD_REG_BIT (set, i))
3745 fprintf (stderr, "r%-2d ", i);
3748 fprintf (stderr, "\n");