Dead
[official-gcc.git] / gomp-20050608-branch / gcc / config / avr / avr.c
blobf6e9f9fbd03ec82237827238cc8b4a41718d4f3b
1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005
3 Free Software Foundation, Inc.
4 Contributed by Denis Chertykov (denisc@overta.ru)
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "real.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "insn-attr.h"
34 #include "flags.h"
35 #include "reload.h"
36 #include "tree.h"
37 #include "output.h"
38 #include "expr.h"
39 #include "toplev.h"
40 #include "obstack.h"
41 #include "function.h"
42 #include "recog.h"
43 #include "ggc.h"
44 #include "tm_p.h"
45 #include "target.h"
46 #include "target-def.h"
48 /* Maximal allowed offset for an address in the LD command */
49 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
51 static int avr_naked_function_p (tree);
52 static int interrupt_function_p (tree);
53 static int signal_function_p (tree);
54 static int avr_regs_to_save (HARD_REG_SET *);
55 static int sequent_regs_live (void);
56 static const char *ptrreg_to_str (int);
57 static const char *cond_string (enum rtx_code);
58 static int avr_num_arg_regs (enum machine_mode, tree);
59 static int out_adj_frame_ptr (FILE *, int);
60 static int out_set_stack_ptr (FILE *, int, int);
61 static RTX_CODE compare_condition (rtx insn);
62 static int compare_sign_p (rtx insn);
63 static tree avr_handle_progmem_attribute (tree *, tree, tree, int, bool *);
64 static tree avr_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
65 const struct attribute_spec avr_attribute_table[];
66 static bool avr_assemble_integer (rtx, unsigned int, int);
67 static void avr_file_start (void);
68 static void avr_file_end (void);
69 static void avr_output_function_prologue (FILE *, HOST_WIDE_INT);
70 static void avr_output_function_epilogue (FILE *, HOST_WIDE_INT);
71 static void avr_insert_attributes (tree, tree *);
72 static void avr_asm_init_sections (void);
73 static unsigned int avr_section_type_flags (tree, const char *, int);
75 static void avr_reorg (void);
76 static void avr_asm_out_ctor (rtx, int);
77 static void avr_asm_out_dtor (rtx, int);
78 static int avr_operand_rtx_cost (rtx, enum machine_mode, enum rtx_code);
79 static bool avr_rtx_costs (rtx, int, int, int *);
80 static int avr_address_cost (rtx);
81 static bool avr_return_in_memory (tree, tree);
83 /* Allocate registers from r25 to r8 for parameters for function calls. */
84 #define FIRST_CUM_REG 26
86 /* Temporary register RTX (gen_rtx_REG (QImode, TMP_REGNO)) */
87 static GTY(()) rtx tmp_reg_rtx;
89 /* Zeroed register RTX (gen_rtx_REG (QImode, ZERO_REGNO)) */
90 static GTY(()) rtx zero_reg_rtx;
92 /* AVR register names {"r0", "r1", ..., "r31"} */
93 static const char *const avr_regnames[] = REGISTER_NAMES;
95 /* This holds the last insn address. */
96 static int last_insn_address = 0;
98 /* Commands count in the compiled file */
99 static int commands_in_file;
101 /* Commands in the functions prologues in the compiled file */
102 static int commands_in_prologues;
104 /* Commands in the functions epilogues in the compiled file */
105 static int commands_in_epilogues;
107 /* Prologue/Epilogue size in words */
108 static int prologue_size;
109 static int epilogue_size;
111 /* Size of all jump tables in the current function, in words. */
112 static int jump_tables_size;
114 /* Preprocessor macros to define depending on MCU type. */
115 const char *avr_base_arch_macro;
116 const char *avr_extra_arch_macro;
118 section *progmem_section;
120 /* More than 8K of program memory: use "call" and "jmp". */
121 int avr_mega_p = 0;
123 /* Enhanced core: use "movw", "mul", ... */
124 int avr_enhanced_p = 0;
126 /* Assembler only. */
127 int avr_asm_only_p = 0;
129 struct base_arch_s {
130 int asm_only;
131 int enhanced;
132 int mega;
133 const char *const macro;
136 static const struct base_arch_s avr_arch_types[] = {
137 { 1, 0, 0, NULL }, /* unknown device specified */
138 { 1, 0, 0, "__AVR_ARCH__=1" },
139 { 0, 0, 0, "__AVR_ARCH__=2" },
140 { 0, 0, 1, "__AVR_ARCH__=3" },
141 { 0, 1, 0, "__AVR_ARCH__=4" },
142 { 0, 1, 1, "__AVR_ARCH__=5" }
145 struct mcu_type_s {
146 const char *const name;
147 int arch; /* index in avr_arch_types[] */
148 /* Must lie outside user's namespace. NULL == no macro. */
149 const char *const macro;
152 /* List of all known AVR MCU types - if updated, it has to be kept
153 in sync in several places (FIXME: is there a better way?):
154 - here
155 - avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
156 - t-avr (MULTILIB_MATCHES)
157 - gas/config/tc-avr.c
158 - avr-libc */
160 static const struct mcu_type_s avr_mcu_types[] = {
161 /* Classic, <= 8K. */
162 { "avr2", 2, NULL },
163 { "at90s2313", 2, "__AVR_AT90S2313__" },
164 { "at90s2323", 2, "__AVR_AT90S2323__" },
165 { "at90s2333", 2, "__AVR_AT90S2333__" },
166 { "at90s2343", 2, "__AVR_AT90S2343__" },
167 { "attiny22", 2, "__AVR_ATtiny22__" },
168 { "attiny26", 2, "__AVR_ATtiny26__" },
169 { "at90s4414", 2, "__AVR_AT90S4414__" },
170 { "at90s4433", 2, "__AVR_AT90S4433__" },
171 { "at90s4434", 2, "__AVR_AT90S4434__" },
172 { "at90s8515", 2, "__AVR_AT90S8515__" },
173 { "at90c8534", 2, "__AVR_AT90C8534__" },
174 { "at90s8535", 2, "__AVR_AT90S8535__" },
175 { "at86rf401", 2, "__AVR_AT86RF401__" },
176 /* Classic + MOVW, <= 8K. */
177 { "attiny13", 2, "__AVR_ATtiny13__" },
178 { "attiny2313", 2, "__AVR_ATtiny2313__" },
179 /* Classic, > 8K. */
180 { "avr3", 3, NULL },
181 { "atmega103", 3, "__AVR_ATmega103__" },
182 { "atmega603", 3, "__AVR_ATmega603__" },
183 { "at43usb320", 3, "__AVR_AT43USB320__" },
184 { "at43usb355", 3, "__AVR_AT43USB355__" },
185 { "at76c711", 3, "__AVR_AT76C711__" },
186 /* Enhanced, <= 8K. */
187 { "avr4", 4, NULL },
188 { "atmega8", 4, "__AVR_ATmega8__" },
189 { "atmega48", 4, "__AVR_ATmega48__" },
190 { "atmega88", 4, "__AVR_ATmega88__" },
191 { "atmega8515", 4, "__AVR_ATmega8515__" },
192 { "atmega8535", 4, "__AVR_ATmega8535__" },
193 /* Enhanced, > 8K. */
194 { "avr5", 5, NULL },
195 { "atmega16", 5, "__AVR_ATmega16__" },
196 { "atmega161", 5, "__AVR_ATmega161__" },
197 { "atmega162", 5, "__AVR_ATmega162__" },
198 { "atmega163", 5, "__AVR_ATmega163__" },
199 { "atmega165", 5, "__AVR_ATmega165__" },
200 { "atmega168", 5, "__AVR_ATmega168__" },
201 { "atmega169", 5, "__AVR_ATmega169__" },
202 { "atmega32", 5, "__AVR_ATmega32__" },
203 { "atmega323", 5, "__AVR_ATmega323__" },
204 { "atmega325", 5, "__AVR_ATmega325__" },
205 { "atmega3250", 5, "__AVR_ATmega3250__" },
206 { "atmega64", 5, "__AVR_ATmega64__" },
207 { "atmega645", 5, "__AVR_ATmega645__" },
208 { "atmega6450", 5, "__AVR_ATmega6450__" },
209 { "atmega128", 5, "__AVR_ATmega128__" },
210 { "at90can128", 5, "__AVR_AT90CAN128__" },
211 { "at94k", 5, "__AVR_AT94K__" },
212 /* Assembler only. */
213 { "avr1", 1, NULL },
214 { "at90s1200", 1, "__AVR_AT90S1200__" },
215 { "attiny11", 1, "__AVR_ATtiny11__" },
216 { "attiny12", 1, "__AVR_ATtiny12__" },
217 { "attiny15", 1, "__AVR_ATtiny15__" },
218 { "attiny28", 1, "__AVR_ATtiny28__" },
219 { NULL, 0, NULL }
222 int avr_case_values_threshold = 30000;
224 /* Initialize the GCC target structure. */
225 #undef TARGET_ASM_ALIGNED_HI_OP
226 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
227 #undef TARGET_ASM_ALIGNED_SI_OP
228 #define TARGET_ASM_ALIGNED_SI_OP "\t.long\t"
229 #undef TARGET_ASM_UNALIGNED_HI_OP
230 #define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
231 #undef TARGET_ASM_UNALIGNED_SI_OP
232 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
233 #undef TARGET_ASM_INTEGER
234 #define TARGET_ASM_INTEGER avr_assemble_integer
235 #undef TARGET_ASM_FILE_START
236 #define TARGET_ASM_FILE_START avr_file_start
237 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
238 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
239 #undef TARGET_ASM_FILE_END
240 #define TARGET_ASM_FILE_END avr_file_end
242 #undef TARGET_ASM_FUNCTION_PROLOGUE
243 #define TARGET_ASM_FUNCTION_PROLOGUE avr_output_function_prologue
244 #undef TARGET_ASM_FUNCTION_EPILOGUE
245 #define TARGET_ASM_FUNCTION_EPILOGUE avr_output_function_epilogue
246 #undef TARGET_ATTRIBUTE_TABLE
247 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
248 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
249 #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
250 #undef TARGET_INSERT_ATTRIBUTES
251 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
252 #undef TARGET_SECTION_TYPE_FLAGS
253 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
254 #undef TARGET_RTX_COSTS
255 #define TARGET_RTX_COSTS avr_rtx_costs
256 #undef TARGET_ADDRESS_COST
257 #define TARGET_ADDRESS_COST avr_address_cost
258 #undef TARGET_MACHINE_DEPENDENT_REORG
259 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
261 #undef TARGET_RETURN_IN_MEMORY
262 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
264 #undef TARGET_STRICT_ARGUMENT_NAMING
265 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
267 struct gcc_target targetm = TARGET_INITIALIZER;
269 void
270 avr_override_options (void)
272 const struct mcu_type_s *t;
273 const struct base_arch_s *base;
275 for (t = avr_mcu_types; t->name; t++)
276 if (strcmp (t->name, avr_mcu_name) == 0)
277 break;
279 if (!t->name)
281 fprintf (stderr, "unknown MCU '%s' specified\nKnown MCU names:\n",
282 avr_mcu_name);
283 for (t = avr_mcu_types; t->name; t++)
284 fprintf (stderr," %s\n", t->name);
287 base = &avr_arch_types[t->arch];
288 avr_asm_only_p = base->asm_only;
289 avr_enhanced_p = base->enhanced;
290 avr_mega_p = base->mega;
291 avr_base_arch_macro = base->macro;
292 avr_extra_arch_macro = t->macro;
294 if (optimize && !TARGET_NO_TABLEJUMP)
295 avr_case_values_threshold = (!AVR_MEGA || TARGET_CALL_PROLOGUES) ? 8 : 17;
297 tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO);
298 zero_reg_rtx = gen_rtx_REG (QImode, ZERO_REGNO);
301 /* return register class from register number. */
303 static const int reg_class_tab[]={
304 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
305 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
306 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
307 GENERAL_REGS, /* r0 - r15 */
308 LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
309 LD_REGS, /* r16 - 23 */
310 ADDW_REGS,ADDW_REGS, /* r24,r25 */
311 POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
312 POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
313 POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
314 STACK_REG,STACK_REG /* SPL,SPH */
317 /* Return register class for register R. */
319 enum reg_class
320 avr_regno_reg_class (int r)
322 if (r <= 33)
323 return reg_class_tab[r];
324 return ALL_REGS;
328 /* A C expression which defines the machine-dependent operand
329 constraint letters for register classes. If C is such a
330 letter, the value should be the register class corresponding to
331 it. Otherwise, the value should be `NO_REGS'. The register
332 letter `r', corresponding to class `GENERAL_REGS', will not be
333 passed to this macro; you do not need to handle it. */
335 enum reg_class
336 avr_reg_class_from_letter (int c)
338 switch (c)
340 case 't' : return R0_REG;
341 case 'b' : return BASE_POINTER_REGS;
342 case 'e' : return POINTER_REGS;
343 case 'w' : return ADDW_REGS;
344 case 'd' : return LD_REGS;
345 case 'l' : return NO_LD_REGS;
346 case 'a' : return SIMPLE_LD_REGS;
347 case 'x' : return POINTER_X_REGS;
348 case 'y' : return POINTER_Y_REGS;
349 case 'z' : return POINTER_Z_REGS;
350 case 'q' : return STACK_REG;
351 default: break;
353 return NO_REGS;
356 /* Return nonzero if FUNC is a naked function. */
358 static int
359 avr_naked_function_p (tree func)
361 tree a;
363 gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
365 a = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
366 return a != NULL_TREE;
369 /* Return nonzero if FUNC is an interrupt function as specified
370 by the "interrupt" attribute. */
372 static int
373 interrupt_function_p (tree func)
375 tree a;
377 if (TREE_CODE (func) != FUNCTION_DECL)
378 return 0;
380 a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
381 return a != NULL_TREE;
384 /* Return nonzero if FUNC is a signal function as specified
385 by the "signal" attribute. */
387 static int
388 signal_function_p (tree func)
390 tree a;
392 if (TREE_CODE (func) != FUNCTION_DECL)
393 return 0;
395 a = lookup_attribute ("signal", DECL_ATTRIBUTES (func));
396 return a != NULL_TREE;
399 /* Return the number of hard registers to push/pop in the prologue/epilogue
400 of the current function, and optionally store these registers in SET. */
402 static int
403 avr_regs_to_save (HARD_REG_SET *set)
405 int reg, count;
406 int int_or_sig_p = (interrupt_function_p (current_function_decl)
407 || signal_function_p (current_function_decl));
408 int leaf_func_p = leaf_function_p ();
410 if (set)
411 CLEAR_HARD_REG_SET (*set);
412 count = 0;
414 /* No need to save any registers if the function never returns. */
415 if (TREE_THIS_VOLATILE (current_function_decl))
416 return 0;
418 for (reg = 0; reg < 32; reg++)
420 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
421 any global register variables. */
422 if (fixed_regs[reg])
423 continue;
425 if ((int_or_sig_p && !leaf_func_p && call_used_regs[reg])
426 || (regs_ever_live[reg]
427 && (int_or_sig_p || !call_used_regs[reg])
428 && !(frame_pointer_needed
429 && (reg == REG_Y || reg == (REG_Y+1)))))
431 if (set)
432 SET_HARD_REG_BIT (*set, reg);
433 count++;
436 return count;
439 /* Compute offset between arg_pointer and frame_pointer. */
442 initial_elimination_offset (int from, int to)
444 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
445 return 0;
446 else
448 int offset = frame_pointer_needed ? 2 : 0;
450 offset += avr_regs_to_save (NULL);
451 return get_frame_size () + 2 + 1 + offset;
455 /* Return 1 if the function epilogue is just a single "ret". */
458 avr_simple_epilogue (void)
460 return (! frame_pointer_needed
461 && get_frame_size () == 0
462 && avr_regs_to_save (NULL) == 0
463 && ! interrupt_function_p (current_function_decl)
464 && ! signal_function_p (current_function_decl)
465 && ! avr_naked_function_p (current_function_decl)
466 && ! MAIN_NAME_P (DECL_NAME (current_function_decl))
467 && ! TREE_THIS_VOLATILE (current_function_decl));
470 /* This function checks sequence of live registers. */
472 static int
473 sequent_regs_live (void)
475 int reg;
476 int live_seq=0;
477 int cur_seq=0;
479 for (reg = 0; reg < 18; ++reg)
481 if (!call_used_regs[reg])
483 if (regs_ever_live[reg])
485 ++live_seq;
486 ++cur_seq;
488 else
489 cur_seq = 0;
493 if (!frame_pointer_needed)
495 if (regs_ever_live[REG_Y])
497 ++live_seq;
498 ++cur_seq;
500 else
501 cur_seq = 0;
503 if (regs_ever_live[REG_Y+1])
505 ++live_seq;
506 ++cur_seq;
508 else
509 cur_seq = 0;
511 else
513 cur_seq += 2;
514 live_seq += 2;
516 return (cur_seq == live_seq) ? live_seq : 0;
520 /* Output to FILE the asm instructions to adjust the frame pointer by
521 ADJ (r29:r28 -= ADJ;) which can be positive (prologue) or negative
522 (epilogue). Returns the number of instructions generated. */
524 static int
525 out_adj_frame_ptr (FILE *file, int adj)
527 int size = 0;
529 if (adj)
531 if (TARGET_TINY_STACK)
533 if (adj < -63 || adj > 63)
534 warning (0, "large frame pointer change (%d) with -mtiny-stack", adj);
536 /* The high byte (r29) doesn't change - prefer "subi" (1 cycle)
537 over "sbiw" (2 cycles, same size). */
539 fprintf (file, (AS2 (subi, r28, %d) CR_TAB), adj);
540 size++;
542 else if (adj < -63 || adj > 63)
544 fprintf (file, (AS2 (subi, r28, lo8(%d)) CR_TAB
545 AS2 (sbci, r29, hi8(%d)) CR_TAB),
546 adj, adj);
547 size += 2;
549 else if (adj < 0)
551 fprintf (file, (AS2 (adiw, r28, %d) CR_TAB), -adj);
552 size++;
554 else
556 fprintf (file, (AS2 (sbiw, r28, %d) CR_TAB), adj);
557 size++;
560 return size;
564 /* Output to FILE the asm instructions to copy r29:r28 to SPH:SPL,
565 handling various cases of interrupt enable flag state BEFORE and AFTER
566 (0=disabled, 1=enabled, -1=unknown/unchanged) and target_flags.
567 Returns the number of instructions generated. */
569 static int
570 out_set_stack_ptr (FILE *file, int before, int after)
572 int do_sph, do_cli, do_save, do_sei, lock_sph, size;
574 /* The logic here is so that -mno-interrupts actually means
575 "it is safe to write SPH in one instruction, then SPL in the
576 next instruction, without disabling interrupts first".
577 The after != -1 case (interrupt/signal) is not affected. */
579 do_sph = !TARGET_TINY_STACK;
580 lock_sph = do_sph && !TARGET_NO_INTERRUPTS;
581 do_cli = (before != 0 && (after == 0 || lock_sph));
582 do_save = (do_cli && before == -1 && after == -1);
583 do_sei = ((do_cli || before != 1) && after == 1);
584 size = 1;
586 if (do_save)
588 fprintf (file, AS2 (in, __tmp_reg__, __SREG__) CR_TAB);
589 size++;
592 if (do_cli)
594 fprintf (file, "cli" CR_TAB);
595 size++;
598 /* Do SPH first - maybe this will disable interrupts for one instruction
599 someday (a suggestion has been sent to avr@atmel.com for consideration
600 in future devices - that would make -mno-interrupts always safe). */
601 if (do_sph)
603 fprintf (file, AS2 (out, __SP_H__, r29) CR_TAB);
604 size++;
607 /* Set/restore the I flag now - interrupts will be really enabled only
608 after the next instruction. This is not clearly documented, but
609 believed to be true for all AVR devices. */
610 if (do_save)
612 fprintf (file, AS2 (out, __SREG__, __tmp_reg__) CR_TAB);
613 size++;
615 else if (do_sei)
617 fprintf (file, "sei" CR_TAB);
618 size++;
621 fprintf (file, AS2 (out, __SP_L__, r28) "\n");
623 return size;
627 /* Output function prologue. */
629 static void
630 avr_output_function_prologue (FILE *file, HOST_WIDE_INT size)
632 int reg;
633 int interrupt_func_p;
634 int signal_func_p;
635 int main_p;
636 int live_seq;
637 int minimize;
639 last_insn_address = 0;
640 jump_tables_size = 0;
641 prologue_size = 0;
642 fprintf (file, "/* prologue: frame size=" HOST_WIDE_INT_PRINT_DEC " */\n",
643 size);
645 if (avr_naked_function_p (current_function_decl))
647 fputs ("/* prologue: naked */\n", file);
648 goto out;
651 interrupt_func_p = interrupt_function_p (current_function_decl);
652 signal_func_p = signal_function_p (current_function_decl);
653 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
654 live_seq = sequent_regs_live ();
655 minimize = (TARGET_CALL_PROLOGUES
656 && !interrupt_func_p && !signal_func_p && live_seq);
658 if (interrupt_func_p)
660 fprintf (file,"\tsei\n");
661 ++prologue_size;
663 if (interrupt_func_p || signal_func_p)
665 fprintf (file, "\t"
666 AS1 (push,__zero_reg__) CR_TAB
667 AS1 (push,__tmp_reg__) CR_TAB
668 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
669 AS1 (push,__tmp_reg__) CR_TAB
670 AS1 (clr,__zero_reg__) "\n");
671 prologue_size += 5;
673 if (main_p)
675 fprintf (file, ("\t"
676 AS1 (ldi,r28) ",lo8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
677 AS1 (ldi,r29) ",hi8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
678 AS2 (out,__SP_H__,r29) CR_TAB
679 AS2 (out,__SP_L__,r28) "\n"),
680 avr_init_stack, size, avr_init_stack, size);
682 prologue_size += 4;
684 else if (minimize && (frame_pointer_needed || live_seq > 6))
686 fprintf (file, ("\t"
687 AS1 (ldi, r26) ",lo8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
688 AS1 (ldi, r27) ",hi8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB), size, size);
690 fputs ((AS2 (ldi,r30,pm_lo8(1f)) CR_TAB
691 AS2 (ldi,r31,pm_hi8(1f)) CR_TAB), file);
693 prologue_size += 4;
695 if (AVR_MEGA)
697 fprintf (file, AS1 (jmp,__prologue_saves__+%d) "\n",
698 (18 - live_seq) * 2);
699 prologue_size += 2;
701 else
703 fprintf (file, AS1 (rjmp,__prologue_saves__+%d) "\n",
704 (18 - live_seq) * 2);
705 ++prologue_size;
707 fputs ("1:\n", file);
709 else
711 HARD_REG_SET set;
713 prologue_size += avr_regs_to_save (&set);
714 for (reg = 0; reg < 32; ++reg)
716 if (TEST_HARD_REG_BIT (set, reg))
718 fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
721 if (frame_pointer_needed)
723 fprintf (file, "\t"
724 AS1 (push,r28) CR_TAB
725 AS1 (push,r29) CR_TAB
726 AS2 (in,r28,__SP_L__) CR_TAB
727 AS2 (in,r29,__SP_H__) "\n");
728 prologue_size += 4;
729 if (size)
731 fputs ("\t", file);
732 prologue_size += out_adj_frame_ptr (file, size);
734 if (interrupt_func_p)
736 prologue_size += out_set_stack_ptr (file, 1, 1);
738 else if (signal_func_p)
740 prologue_size += out_set_stack_ptr (file, 0, 0);
742 else
744 prologue_size += out_set_stack_ptr (file, -1, -1);
750 out:
751 fprintf (file, "/* prologue end (size=%d) */\n", prologue_size);
754 /* Output function epilogue. */
756 static void
757 avr_output_function_epilogue (FILE *file, HOST_WIDE_INT size)
759 int reg;
760 int interrupt_func_p;
761 int signal_func_p;
762 int main_p;
763 int function_size;
764 int live_seq;
765 int minimize;
766 rtx last = get_last_nonnote_insn ();
768 function_size = jump_tables_size;
769 if (last)
771 rtx first = get_first_nonnote_insn ();
772 function_size += (INSN_ADDRESSES (INSN_UID (last)) -
773 INSN_ADDRESSES (INSN_UID (first)));
774 function_size += get_attr_length (last);
777 fprintf (file, "/* epilogue: frame size=" HOST_WIDE_INT_PRINT_DEC " */\n", size);
778 epilogue_size = 0;
780 if (avr_naked_function_p (current_function_decl))
782 fputs ("/* epilogue: naked */\n", file);
783 goto out;
786 if (last && GET_CODE (last) == BARRIER)
788 fputs ("/* epilogue: noreturn */\n", file);
789 goto out;
792 interrupt_func_p = interrupt_function_p (current_function_decl);
793 signal_func_p = signal_function_p (current_function_decl);
794 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
795 live_seq = sequent_regs_live ();
796 minimize = (TARGET_CALL_PROLOGUES
797 && !interrupt_func_p && !signal_func_p && live_seq);
799 if (main_p)
801 /* Return value from main() is already in the correct registers
802 (r25:r24) as the exit() argument. */
803 if (AVR_MEGA)
805 fputs ("\t" AS1 (jmp,exit) "\n", file);
806 epilogue_size += 2;
808 else
810 fputs ("\t" AS1 (rjmp,exit) "\n", file);
811 ++epilogue_size;
814 else if (minimize && (frame_pointer_needed || live_seq > 4))
816 fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
817 ++epilogue_size;
818 if (frame_pointer_needed)
820 epilogue_size += out_adj_frame_ptr (file, -size);
822 else
824 fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
825 AS2 (in , r29, __SP_H__) CR_TAB));
826 epilogue_size += 2;
829 if (AVR_MEGA)
831 fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
832 (18 - live_seq) * 2);
833 epilogue_size += 2;
835 else
837 fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
838 (18 - live_seq) * 2);
839 ++epilogue_size;
842 else
844 HARD_REG_SET set;
846 if (frame_pointer_needed)
848 if (size)
850 fputs ("\t", file);
851 epilogue_size += out_adj_frame_ptr (file, -size);
853 if (interrupt_func_p || signal_func_p)
855 epilogue_size += out_set_stack_ptr (file, -1, 0);
857 else
859 epilogue_size += out_set_stack_ptr (file, -1, -1);
862 fprintf (file, "\t"
863 AS1 (pop,r29) CR_TAB
864 AS1 (pop,r28) "\n");
865 epilogue_size += 2;
868 epilogue_size += avr_regs_to_save (&set);
869 for (reg = 31; reg >= 0; --reg)
871 if (TEST_HARD_REG_BIT (set, reg))
873 fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
877 if (interrupt_func_p || signal_func_p)
879 fprintf (file, "\t"
880 AS1 (pop,__tmp_reg__) CR_TAB
881 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
882 AS1 (pop,__tmp_reg__) CR_TAB
883 AS1 (pop,__zero_reg__) "\n");
884 epilogue_size += 4;
885 fprintf (file, "\treti\n");
887 else
888 fprintf (file, "\tret\n");
889 ++epilogue_size;
892 out:
893 fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
894 fprintf (file, "/* function %s size %d (%d) */\n", current_function_name (),
895 prologue_size + function_size + epilogue_size, function_size);
896 commands_in_file += prologue_size + function_size + epilogue_size;
897 commands_in_prologues += prologue_size;
898 commands_in_epilogues += epilogue_size;
902 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
903 machine for a memory operand of mode MODE. */
906 legitimate_address_p (enum machine_mode mode, rtx x, int strict)
908 enum reg_class r = NO_REGS;
910 if (TARGET_ALL_DEBUG)
912 fprintf (stderr, "mode: (%s) %s %s %s %s:",
913 GET_MODE_NAME(mode),
914 strict ? "(strict)": "",
915 reload_completed ? "(reload_completed)": "",
916 reload_in_progress ? "(reload_in_progress)": "",
917 reg_renumber ? "(reg_renumber)" : "");
918 if (GET_CODE (x) == PLUS
919 && REG_P (XEXP (x, 0))
920 && GET_CODE (XEXP (x, 1)) == CONST_INT
921 && INTVAL (XEXP (x, 1)) >= 0
922 && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
923 && reg_renumber
925 fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
926 true_regnum (XEXP (x, 0)));
927 debug_rtx (x);
929 if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
930 : REG_OK_FOR_BASE_NOSTRICT_P (x)))
931 r = POINTER_REGS;
932 else if (CONSTANT_ADDRESS_P (x))
933 r = ALL_REGS;
934 else if (GET_CODE (x) == PLUS
935 && REG_P (XEXP (x, 0))
936 && GET_CODE (XEXP (x, 1)) == CONST_INT
937 && INTVAL (XEXP (x, 1)) >= 0)
939 int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
940 if (fit)
942 if (! strict
943 || REGNO (XEXP (x,0)) == REG_Y
944 || REGNO (XEXP (x,0)) == REG_Z)
945 r = BASE_POINTER_REGS;
946 if (XEXP (x,0) == frame_pointer_rtx
947 || XEXP (x,0) == arg_pointer_rtx)
948 r = BASE_POINTER_REGS;
950 else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
951 r = POINTER_Y_REGS;
953 else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
954 && REG_P (XEXP (x, 0))
955 && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
956 : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
958 r = POINTER_REGS;
960 if (TARGET_ALL_DEBUG)
962 fprintf (stderr, " ret = %c\n", r + '0');
964 return r == NO_REGS ? 0 : (int)r;
967 /* Attempts to replace X with a valid
968 memory address for an operand of mode MODE */
971 legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
973 x = oldx;
974 if (TARGET_ALL_DEBUG)
976 fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
977 debug_rtx (oldx);
980 if (GET_CODE (oldx) == PLUS
981 && REG_P (XEXP (oldx,0)))
983 if (REG_P (XEXP (oldx,1)))
984 x = force_reg (GET_MODE (oldx), oldx);
985 else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
987 int offs = INTVAL (XEXP (oldx,1));
988 if (frame_pointer_rtx != XEXP (oldx,0))
989 if (offs > MAX_LD_OFFSET (mode))
991 if (TARGET_ALL_DEBUG)
992 fprintf (stderr, "force_reg (big offset)\n");
993 x = force_reg (GET_MODE (oldx), oldx);
997 return x;
1001 /* Return a pointer register name as a string. */
1003 static const char *
1004 ptrreg_to_str (int regno)
1006 switch (regno)
1008 case REG_X: return "X";
1009 case REG_Y: return "Y";
1010 case REG_Z: return "Z";
1011 default:
1012 gcc_unreachable ();
1014 return NULL;
1017 /* Return the condition name as a string.
1018 Used in conditional jump constructing */
1020 static const char *
1021 cond_string (enum rtx_code code)
1023 switch (code)
1025 case NE:
1026 return "ne";
1027 case EQ:
1028 return "eq";
1029 case GE:
1030 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1031 return "pl";
1032 else
1033 return "ge";
1034 case LT:
1035 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1036 return "mi";
1037 else
1038 return "lt";
1039 case GEU:
1040 return "sh";
1041 case LTU:
1042 return "lo";
1043 default:
1044 gcc_unreachable ();
1048 /* Output ADDR to FILE as address. */
1050 void
1051 print_operand_address (FILE *file, rtx addr)
1053 switch (GET_CODE (addr))
1055 case REG:
1056 fprintf (file, ptrreg_to_str (REGNO (addr)));
1057 break;
1059 case PRE_DEC:
1060 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1061 break;
1063 case POST_INC:
1064 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1065 break;
1067 default:
1068 if (CONSTANT_ADDRESS_P (addr)
1069 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (addr))
1070 || GET_CODE (addr) == LABEL_REF))
1072 fprintf (file, "pm(");
1073 output_addr_const (file,addr);
1074 fprintf (file ,")");
1076 else
1077 output_addr_const (file, addr);
1082 /* Output X as assembler operand to file FILE. */
1084 void
1085 print_operand (FILE *file, rtx x, int code)
1087 int abcd = 0;
1089 if (code >= 'A' && code <= 'D')
1090 abcd = code - 'A';
1092 if (code == '~')
1094 if (!AVR_MEGA)
1095 fputc ('r', file);
1097 else if (REG_P (x))
1099 if (x == zero_reg_rtx)
1100 fprintf (file, "__zero_reg__");
1101 else
1102 fprintf (file, reg_names[true_regnum (x) + abcd]);
1104 else if (GET_CODE (x) == CONST_INT)
1105 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd);
1106 else if (GET_CODE (x) == MEM)
1108 rtx addr = XEXP (x,0);
1110 if (CONSTANT_P (addr) && abcd)
1112 fputc ('(', file);
1113 output_address (addr);
1114 fprintf (file, ")+%d", abcd);
1116 else if (code == 'o')
1118 if (GET_CODE (addr) != PLUS)
1119 fatal_insn ("bad address, not (reg+disp):", addr);
1121 print_operand (file, XEXP (addr, 1), 0);
1123 else if (code == 'p' || code == 'r')
1125 if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
1126 fatal_insn ("bad address, not post_inc or pre_dec:", addr);
1128 if (code == 'p')
1129 print_operand_address (file, XEXP (addr, 0)); /* X, Y, Z */
1130 else
1131 print_operand (file, XEXP (addr, 0), 0); /* r26, r28, r30 */
1133 else if (GET_CODE (addr) == PLUS)
1135 print_operand_address (file, XEXP (addr,0));
1136 if (REGNO (XEXP (addr, 0)) == REG_X)
1137 fatal_insn ("internal compiler error. Bad address:"
1138 ,addr);
1139 fputc ('+', file);
1140 print_operand (file, XEXP (addr,1), code);
1142 else
1143 print_operand_address (file, addr);
1145 else if (GET_CODE (x) == CONST_DOUBLE)
1147 long val;
1148 REAL_VALUE_TYPE rv;
1149 if (GET_MODE (x) != SFmode)
1150 fatal_insn ("internal compiler error. Unknown mode:", x);
1151 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1152 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1153 fprintf (file, "0x%lx", val);
1155 else if (code == 'j')
1156 fputs (cond_string (GET_CODE (x)), file);
1157 else if (code == 'k')
1158 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
1159 else
1160 print_operand_address (file, x);
1163 /* Recognize operand OP of mode MODE used in call instructions. */
1166 call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1168 if (GET_CODE (op) == MEM)
1170 rtx inside = XEXP (op, 0);
1171 if (register_operand (inside, Pmode))
1172 return 1;
1173 if (CONSTANT_ADDRESS_P (inside))
1174 return 1;
1176 return 0;
1179 /* Update the condition code in the INSN. */
1181 void
1182 notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
1184 rtx set;
1186 switch (get_attr_cc (insn))
1188 case CC_NONE:
1189 /* Insn does not affect CC at all. */
1190 break;
1192 case CC_SET_N:
1193 CC_STATUS_INIT;
1194 break;
1196 case CC_SET_ZN:
1197 set = single_set (insn);
1198 CC_STATUS_INIT;
1199 if (set)
1201 cc_status.flags |= CC_NO_OVERFLOW;
1202 cc_status.value1 = SET_DEST (set);
1204 break;
1206 case CC_SET_CZN:
1207 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1208 The V flag may or may not be known but that's ok because
1209 alter_cond will change tests to use EQ/NE. */
1210 set = single_set (insn);
1211 CC_STATUS_INIT;
1212 if (set)
1214 cc_status.value1 = SET_DEST (set);
1215 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1217 break;
1219 case CC_COMPARE:
1220 set = single_set (insn);
1221 CC_STATUS_INIT;
1222 if (set)
1223 cc_status.value1 = SET_SRC (set);
1224 break;
1226 case CC_CLOBBER:
1227 /* Insn doesn't leave CC in a usable state. */
1228 CC_STATUS_INIT;
1230 /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1231 set = single_set (insn);
1232 if (set)
1234 rtx src = SET_SRC (set);
1236 if (GET_CODE (src) == ASHIFTRT
1237 && GET_MODE (src) == QImode)
1239 rtx x = XEXP (src, 1);
1241 if (GET_CODE (x) == CONST_INT
1242 && INTVAL (x) > 0
1243 && INTVAL (x) != 6)
1245 cc_status.value1 = SET_DEST (set);
1246 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1250 break;
1254 /* Return maximum number of consecutive registers of
1255 class CLASS needed to hold a value of mode MODE. */
1258 class_max_nregs (enum reg_class class ATTRIBUTE_UNUSED,enum machine_mode mode)
1260 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1263 /* Choose mode for jump insn:
1264 1 - relative jump in range -63 <= x <= 62 ;
1265 2 - relative jump in range -2046 <= x <= 2045 ;
1266 3 - absolute jump (only for ATmega[16]03). */
1269 avr_jump_mode (rtx x, rtx insn)
1271 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1272 ? XEXP (x, 0) : x));
1273 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1274 int jump_distance = cur_addr - dest_addr;
1276 if (-63 <= jump_distance && jump_distance <= 62)
1277 return 1;
1278 else if (-2046 <= jump_distance && jump_distance <= 2045)
1279 return 2;
1280 else if (AVR_MEGA)
1281 return 3;
1283 return 2;
1286 /* return an AVR condition jump commands.
1287 X is a comparison RTX.
1288 LEN is a number returned by avr_jump_mode function.
1289 if REVERSE nonzero then condition code in X must be reversed. */
1291 const char *
1292 ret_cond_branch (rtx x, int len, int reverse)
1294 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1296 switch (cond)
1298 case GT:
1299 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1300 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1301 AS1 (brpl,%0)) :
1302 len == 2 ? (AS1 (breq,.+4) CR_TAB
1303 AS1 (brmi,.+2) CR_TAB
1304 AS1 (rjmp,%0)) :
1305 (AS1 (breq,.+6) CR_TAB
1306 AS1 (brmi,.+4) CR_TAB
1307 AS1 (jmp,%0)));
1309 else
1310 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1311 AS1 (brge,%0)) :
1312 len == 2 ? (AS1 (breq,.+4) CR_TAB
1313 AS1 (brlt,.+2) CR_TAB
1314 AS1 (rjmp,%0)) :
1315 (AS1 (breq,.+6) CR_TAB
1316 AS1 (brlt,.+4) CR_TAB
1317 AS1 (jmp,%0)));
1318 case GTU:
1319 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1320 AS1 (brsh,%0)) :
1321 len == 2 ? (AS1 (breq,.+4) CR_TAB
1322 AS1 (brlo,.+2) CR_TAB
1323 AS1 (rjmp,%0)) :
1324 (AS1 (breq,.+6) CR_TAB
1325 AS1 (brlo,.+4) CR_TAB
1326 AS1 (jmp,%0)));
1327 case LE:
1328 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1329 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1330 AS1 (brmi,%0)) :
1331 len == 2 ? (AS1 (breq,.+2) CR_TAB
1332 AS1 (brpl,.+2) CR_TAB
1333 AS1 (rjmp,%0)) :
1334 (AS1 (breq,.+2) CR_TAB
1335 AS1 (brpl,.+4) CR_TAB
1336 AS1 (jmp,%0)));
1337 else
1338 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1339 AS1 (brlt,%0)) :
1340 len == 2 ? (AS1 (breq,.+2) CR_TAB
1341 AS1 (brge,.+2) CR_TAB
1342 AS1 (rjmp,%0)) :
1343 (AS1 (breq,.+2) CR_TAB
1344 AS1 (brge,.+4) CR_TAB
1345 AS1 (jmp,%0)));
1346 case LEU:
1347 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1348 AS1 (brlo,%0)) :
1349 len == 2 ? (AS1 (breq,.+2) CR_TAB
1350 AS1 (brsh,.+2) CR_TAB
1351 AS1 (rjmp,%0)) :
1352 (AS1 (breq,.+2) CR_TAB
1353 AS1 (brsh,.+4) CR_TAB
1354 AS1 (jmp,%0)));
1355 default:
1356 if (reverse)
1358 switch (len)
1360 case 1:
1361 return AS1 (br%k1,%0);
1362 case 2:
1363 return (AS1 (br%j1,.+2) CR_TAB
1364 AS1 (rjmp,%0));
1365 default:
1366 return (AS1 (br%j1,.+4) CR_TAB
1367 AS1 (jmp,%0));
1370 else
1372 switch (len)
1374 case 1:
1375 return AS1 (br%j1,%0);
1376 case 2:
1377 return (AS1 (br%k1,.+2) CR_TAB
1378 AS1 (rjmp,%0));
1379 default:
1380 return (AS1 (br%k1,.+4) CR_TAB
1381 AS1 (jmp,%0));
1385 return "";
1388 /* Predicate function for immediate operand which fits to byte (8bit) */
1391 byte_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1393 return (GET_CODE (op) == CONST_INT
1394 && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1397 /* Output all insn addresses and their sizes into the assembly language
1398 output file. This is helpful for debugging whether the length attributes
1399 in the md file are correct.
1400 Output insn cost for next insn. */
1402 void
1403 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
1404 int num_operands ATTRIBUTE_UNUSED)
1406 int uid = INSN_UID (insn);
1408 if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1410 fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1411 INSN_ADDRESSES (uid),
1412 INSN_ADDRESSES (uid) - last_insn_address,
1413 rtx_cost (PATTERN (insn), INSN));
1415 last_insn_address = INSN_ADDRESSES (uid);
1418 /* Return 0 if undefined, 1 if always true or always false. */
1421 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE operator, rtx x)
1423 unsigned int max = (mode == QImode ? 0xff :
1424 mode == HImode ? 0xffff :
1425 mode == SImode ? 0xffffffff : 0);
1426 if (max && operator && GET_CODE (x) == CONST_INT)
1428 if (unsigned_condition (operator) != operator)
1429 max >>= 1;
1431 if (max != (INTVAL (x) & max)
1432 && INTVAL (x) != 0xff)
1433 return 1;
1435 return 0;
1439 /* Returns nonzero if REGNO is the number of a hard
1440 register in which function arguments are sometimes passed. */
1443 function_arg_regno_p(int r)
1445 return (r >= 8 && r <= 25);
1448 /* Initializing the variable cum for the state at the beginning
1449 of the argument list. */
1451 void
1452 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
1453 tree fndecl ATTRIBUTE_UNUSED)
1455 cum->nregs = 18;
1456 cum->regno = FIRST_CUM_REG;
1457 if (!libname && fntype)
1459 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1460 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1461 != void_type_node));
1462 if (stdarg)
1463 cum->nregs = 0;
1467 /* Returns the number of registers to allocate for a function argument. */
1469 static int
1470 avr_num_arg_regs (enum machine_mode mode, tree type)
1472 int size;
1474 if (mode == BLKmode)
1475 size = int_size_in_bytes (type);
1476 else
1477 size = GET_MODE_SIZE (mode);
1479 /* Align all function arguments to start in even-numbered registers.
1480 Odd-sized arguments leave holes above them. */
1482 return (size + 1) & ~1;
1485 /* Controls whether a function argument is passed
1486 in a register, and which register. */
1489 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1490 int named ATTRIBUTE_UNUSED)
1492 int bytes = avr_num_arg_regs (mode, type);
1494 if (cum->nregs && bytes <= cum->nregs)
1495 return gen_rtx_REG (mode, cum->regno - bytes);
1497 return NULL_RTX;
1500 /* Update the summarizer variable CUM to advance past an argument
1501 in the argument list. */
1503 void
1504 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1505 int named ATTRIBUTE_UNUSED)
1507 int bytes = avr_num_arg_regs (mode, type);
1509 cum->nregs -= bytes;
1510 cum->regno -= bytes;
1512 if (cum->nregs <= 0)
1514 cum->nregs = 0;
1515 cum->regno = FIRST_CUM_REG;
1519 /***********************************************************************
1520 Functions for outputting various mov's for a various modes
1521 ************************************************************************/
1522 const char *
1523 output_movqi (rtx insn, rtx operands[], int *l)
1525 int dummy;
1526 rtx dest = operands[0];
1527 rtx src = operands[1];
1528 int *real_l = l;
1530 if (!l)
1531 l = &dummy;
1533 *l = 1;
1535 if (register_operand (dest, QImode))
1537 if (register_operand (src, QImode)) /* mov r,r */
1539 if (test_hard_reg_class (STACK_REG, dest))
1540 return AS2 (out,%0,%1);
1541 else if (test_hard_reg_class (STACK_REG, src))
1542 return AS2 (in,%0,%1);
1544 return AS2 (mov,%0,%1);
1546 else if (CONSTANT_P (src))
1548 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1549 return AS2 (ldi,%0,lo8(%1));
1551 if (GET_CODE (src) == CONST_INT)
1553 if (src == const0_rtx) /* mov r,L */
1554 return AS1 (clr,%0);
1555 else if (src == const1_rtx)
1557 *l = 2;
1558 return (AS1 (clr,%0) CR_TAB
1559 AS1 (inc,%0));
1561 else if (src == constm1_rtx)
1563 /* Immediate constants -1 to any register */
1564 *l = 2;
1565 return (AS1 (clr,%0) CR_TAB
1566 AS1 (dec,%0));
1568 else
1570 int bit_nr = exact_log2 (INTVAL (src));
1572 if (bit_nr >= 0)
1574 *l = 3;
1575 if (!real_l)
1576 output_asm_insn ((AS1 (clr,%0) CR_TAB
1577 "set"), operands);
1578 if (!real_l)
1579 avr_output_bld (operands, bit_nr);
1581 return "";
1586 /* Last resort, larger than loading from memory. */
1587 *l = 4;
1588 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1589 AS2 (ldi,r31,lo8(%1)) CR_TAB
1590 AS2 (mov,%0,r31) CR_TAB
1591 AS2 (mov,r31,__tmp_reg__));
1593 else if (GET_CODE (src) == MEM)
1594 return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1596 else if (GET_CODE (dest) == MEM)
1598 const char *template;
1600 if (src == const0_rtx)
1601 operands[1] = zero_reg_rtx;
1603 template = out_movqi_mr_r (insn, operands, real_l);
1605 if (!real_l)
1606 output_asm_insn (template, operands);
1608 operands[1] = src;
1610 return "";
1614 const char *
1615 output_movhi (rtx insn, rtx operands[], int *l)
1617 int dummy;
1618 rtx dest = operands[0];
1619 rtx src = operands[1];
1620 int *real_l = l;
1622 if (!l)
1623 l = &dummy;
1625 if (register_operand (dest, HImode))
1627 if (register_operand (src, HImode)) /* mov r,r */
1629 if (test_hard_reg_class (STACK_REG, dest))
1631 if (TARGET_TINY_STACK)
1633 *l = 1;
1634 return AS2 (out,__SP_L__,%A1);
1636 else if (TARGET_NO_INTERRUPTS)
1638 *l = 2;
1639 return (AS2 (out,__SP_H__,%B1) CR_TAB
1640 AS2 (out,__SP_L__,%A1));
1643 *l = 5;
1644 return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB
1645 "cli" CR_TAB
1646 AS2 (out,__SP_H__,%B1) CR_TAB
1647 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1648 AS2 (out,__SP_L__,%A1));
1650 else if (test_hard_reg_class (STACK_REG, src))
1652 *l = 2;
1653 return (AS2 (in,%A0,__SP_L__) CR_TAB
1654 AS2 (in,%B0,__SP_H__));
1657 if (AVR_ENHANCED)
1659 *l = 1;
1660 return (AS2 (movw,%0,%1));
1663 if (true_regnum (dest) > true_regnum (src))
1665 *l = 2;
1666 return (AS2 (mov,%B0,%B1) CR_TAB
1667 AS2 (mov,%A0,%A1));
1669 else
1671 *l = 2;
1672 return (AS2 (mov,%A0,%A1) CR_TAB
1673 AS2 (mov,%B0,%B1));
1676 else if (CONSTANT_P (src))
1678 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1680 *l = 2;
1681 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1682 AS2 (ldi,%B0,hi8(%1)));
1685 if (GET_CODE (src) == CONST_INT)
1687 if (src == const0_rtx) /* mov r,L */
1689 *l = 2;
1690 return (AS1 (clr,%A0) CR_TAB
1691 AS1 (clr,%B0));
1693 else if (src == const1_rtx)
1695 *l = 3;
1696 return (AS1 (clr,%A0) CR_TAB
1697 AS1 (clr,%B0) CR_TAB
1698 AS1 (inc,%A0));
1700 else if (src == constm1_rtx)
1702 /* Immediate constants -1 to any register */
1703 *l = 3;
1704 return (AS1 (clr,%0) CR_TAB
1705 AS1 (dec,%A0) CR_TAB
1706 AS2 (mov,%B0,%A0));
1708 else
1710 int bit_nr = exact_log2 (INTVAL (src));
1712 if (bit_nr >= 0)
1714 *l = 4;
1715 if (!real_l)
1716 output_asm_insn ((AS1 (clr,%A0) CR_TAB
1717 AS1 (clr,%B0) CR_TAB
1718 "set"), operands);
1719 if (!real_l)
1720 avr_output_bld (operands, bit_nr);
1722 return "";
1726 if ((INTVAL (src) & 0xff) == 0)
1728 *l = 5;
1729 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1730 AS1 (clr,%A0) CR_TAB
1731 AS2 (ldi,r31,hi8(%1)) CR_TAB
1732 AS2 (mov,%B0,r31) CR_TAB
1733 AS2 (mov,r31,__tmp_reg__));
1735 else if ((INTVAL (src) & 0xff00) == 0)
1737 *l = 5;
1738 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1739 AS2 (ldi,r31,lo8(%1)) CR_TAB
1740 AS2 (mov,%A0,r31) CR_TAB
1741 AS1 (clr,%B0) CR_TAB
1742 AS2 (mov,r31,__tmp_reg__));
1746 /* Last resort, equal to loading from memory. */
1747 *l = 6;
1748 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1749 AS2 (ldi,r31,lo8(%1)) CR_TAB
1750 AS2 (mov,%A0,r31) CR_TAB
1751 AS2 (ldi,r31,hi8(%1)) CR_TAB
1752 AS2 (mov,%B0,r31) CR_TAB
1753 AS2 (mov,r31,__tmp_reg__));
1755 else if (GET_CODE (src) == MEM)
1756 return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1758 else if (GET_CODE (dest) == MEM)
1760 const char *template;
1762 if (src == const0_rtx)
1763 operands[1] = zero_reg_rtx;
1765 template = out_movhi_mr_r (insn, operands, real_l);
1767 if (!real_l)
1768 output_asm_insn (template, operands);
1770 operands[1] = src;
1771 return "";
1773 fatal_insn ("invalid insn:", insn);
1774 return "";
1777 const char *
1778 out_movqi_r_mr (rtx insn, rtx op[], int *l)
1780 rtx dest = op[0];
1781 rtx src = op[1];
1782 rtx x = XEXP (src, 0);
1783 int dummy;
1785 if (!l)
1786 l = &dummy;
1788 if (CONSTANT_ADDRESS_P (x))
1790 if (avr_io_address_p (x, 1))
1792 *l = 1;
1793 return AS2 (in,%0,%1-0x20);
1795 *l = 2;
1796 return AS2 (lds,%0,%1);
1798 /* memory access by reg+disp */
1799 else if (GET_CODE (x) == PLUS
1800 && REG_P (XEXP (x,0))
1801 && GET_CODE (XEXP (x,1)) == CONST_INT)
1803 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1805 int disp = INTVAL (XEXP (x,1));
1806 if (REGNO (XEXP (x,0)) != REG_Y)
1807 fatal_insn ("incorrect insn:",insn);
1809 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1810 return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
1811 AS2 (ldd,%0,Y+63) CR_TAB
1812 AS2 (sbiw,r28,%o1-63));
1814 return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1815 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1816 AS2 (ld,%0,Y) CR_TAB
1817 AS2 (subi,r28,lo8(%o1)) CR_TAB
1818 AS2 (sbci,r29,hi8(%o1)));
1820 else if (REGNO (XEXP (x,0)) == REG_X)
1822 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1823 it but I have this situation with extremal optimizing options. */
1824 if (reg_overlap_mentioned_p (dest, XEXP (x,0))
1825 || reg_unused_after (insn, XEXP (x,0)))
1826 return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
1827 AS2 (ld,%0,X));
1829 return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
1830 AS2 (ld,%0,X) CR_TAB
1831 AS2 (sbiw,r26,%o1));
1833 *l = 1;
1834 return AS2 (ldd,%0,%1);
1836 *l = 1;
1837 return AS2 (ld,%0,%1);
1840 const char *
1841 out_movhi_r_mr (rtx insn, rtx op[], int *l)
1843 rtx dest = op[0];
1844 rtx src = op[1];
1845 rtx base = XEXP (src, 0);
1846 int reg_dest = true_regnum (dest);
1847 int reg_base = true_regnum (base);
1848 /* "volatile" forces reading low byte first, even if less efficient,
1849 for correct operation with 16-bit I/O registers. */
1850 int mem_volatile_p = MEM_VOLATILE_P (src);
1851 int tmp;
1853 if (!l)
1854 l = &tmp;
1856 if (reg_base > 0)
1858 if (reg_dest == reg_base) /* R = (R) */
1860 *l = 3;
1861 return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1862 AS2 (ld,%B0,%1) CR_TAB
1863 AS2 (mov,%A0,__tmp_reg__));
1865 else if (reg_base == REG_X) /* (R26) */
1867 if (reg_unused_after (insn, base))
1869 *l = 2;
1870 return (AS2 (ld,%A0,X+) CR_TAB
1871 AS2 (ld,%B0,X));
1873 *l = 3;
1874 return (AS2 (ld,%A0,X+) CR_TAB
1875 AS2 (ld,%B0,X) CR_TAB
1876 AS2 (sbiw,r26,1));
1878 else /* (R) */
1880 *l = 2;
1881 return (AS2 (ld,%A0,%1) CR_TAB
1882 AS2 (ldd,%B0,%1+1));
1885 else if (GET_CODE (base) == PLUS) /* (R + i) */
1887 int disp = INTVAL (XEXP (base, 1));
1888 int reg_base = true_regnum (XEXP (base, 0));
1890 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
1892 if (REGNO (XEXP (base, 0)) != REG_Y)
1893 fatal_insn ("incorrect insn:",insn);
1895 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1896 return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
1897 AS2 (ldd,%A0,Y+62) CR_TAB
1898 AS2 (ldd,%B0,Y+63) CR_TAB
1899 AS2 (sbiw,r28,%o1-62));
1901 return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1902 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1903 AS2 (ld,%A0,Y) CR_TAB
1904 AS2 (ldd,%B0,Y+1) CR_TAB
1905 AS2 (subi,r28,lo8(%o1)) CR_TAB
1906 AS2 (sbci,r29,hi8(%o1)));
1908 if (reg_base == REG_X)
1910 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1911 it but I have this situation with extremal
1912 optimization options. */
1914 *l = 4;
1915 if (reg_base == reg_dest)
1916 return (AS2 (adiw,r26,%o1) CR_TAB
1917 AS2 (ld,__tmp_reg__,X+) CR_TAB
1918 AS2 (ld,%B0,X) CR_TAB
1919 AS2 (mov,%A0,__tmp_reg__));
1921 return (AS2 (adiw,r26,%o1) CR_TAB
1922 AS2 (ld,%A0,X+) CR_TAB
1923 AS2 (ld,%B0,X) CR_TAB
1924 AS2 (sbiw,r26,%o1+1));
1927 if (reg_base == reg_dest)
1929 *l = 3;
1930 return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
1931 AS2 (ldd,%B0,%B1) CR_TAB
1932 AS2 (mov,%A0,__tmp_reg__));
1935 *l = 2;
1936 return (AS2 (ldd,%A0,%A1) CR_TAB
1937 AS2 (ldd,%B0,%B1));
1939 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
1941 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1942 fatal_insn ("incorrect insn:", insn);
1944 if (mem_volatile_p)
1946 if (REGNO (XEXP (base, 0)) == REG_X)
1948 *l = 4;
1949 return (AS2 (sbiw,r26,2) CR_TAB
1950 AS2 (ld,%A0,X+) CR_TAB
1951 AS2 (ld,%B0,X) CR_TAB
1952 AS2 (sbiw,r26,1));
1954 else
1956 *l = 3;
1957 return (AS2 (sbiw,%r1,2) CR_TAB
1958 AS2 (ld,%A0,%p1) CR_TAB
1959 AS2 (ldd,%B0,%p1+1));
1963 *l = 2;
1964 return (AS2 (ld,%B0,%1) CR_TAB
1965 AS2 (ld,%A0,%1));
1967 else if (GET_CODE (base) == POST_INC) /* (R++) */
1969 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1970 fatal_insn ("incorrect insn:", insn);
1972 *l = 2;
1973 return (AS2 (ld,%A0,%1) CR_TAB
1974 AS2 (ld,%B0,%1));
1976 else if (CONSTANT_ADDRESS_P (base))
1978 if (avr_io_address_p (base, 2))
1980 *l = 2;
1981 return (AS2 (in,%A0,%A1-0x20) CR_TAB
1982 AS2 (in,%B0,%B1-0x20));
1984 *l = 4;
1985 return (AS2 (lds,%A0,%A1) CR_TAB
1986 AS2 (lds,%B0,%B1));
1989 fatal_insn ("unknown move insn:",insn);
1990 return "";
1993 const char *
1994 out_movsi_r_mr (rtx insn, rtx op[], int *l)
1996 rtx dest = op[0];
1997 rtx src = op[1];
1998 rtx base = XEXP (src, 0);
1999 int reg_dest = true_regnum (dest);
2000 int reg_base = true_regnum (base);
2001 int tmp;
2003 if (!l)
2004 l = &tmp;
2006 if (reg_base > 0)
2008 if (reg_base == REG_X) /* (R26) */
2010 if (reg_dest == REG_X)
2011 /* "ld r26,-X" is undefined */
2012 return *l=7, (AS2 (adiw,r26,3) CR_TAB
2013 AS2 (ld,r29,X) CR_TAB
2014 AS2 (ld,r28,-X) CR_TAB
2015 AS2 (ld,__tmp_reg__,-X) CR_TAB
2016 AS2 (sbiw,r26,1) CR_TAB
2017 AS2 (ld,r26,X) CR_TAB
2018 AS2 (mov,r27,__tmp_reg__));
2019 else if (reg_dest == REG_X - 2)
2020 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2021 AS2 (ld,%B0,X+) CR_TAB
2022 AS2 (ld,__tmp_reg__,X+) CR_TAB
2023 AS2 (ld,%D0,X) CR_TAB
2024 AS2 (mov,%C0,__tmp_reg__));
2025 else if (reg_unused_after (insn, base))
2026 return *l=4, (AS2 (ld,%A0,X+) CR_TAB
2027 AS2 (ld,%B0,X+) CR_TAB
2028 AS2 (ld,%C0,X+) CR_TAB
2029 AS2 (ld,%D0,X));
2030 else
2031 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2032 AS2 (ld,%B0,X+) CR_TAB
2033 AS2 (ld,%C0,X+) CR_TAB
2034 AS2 (ld,%D0,X) CR_TAB
2035 AS2 (sbiw,r26,3));
2037 else
2039 if (reg_dest == reg_base)
2040 return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
2041 AS2 (ldd,%C0,%1+2) CR_TAB
2042 AS2 (ldd,__tmp_reg__,%1+1) CR_TAB
2043 AS2 (ld,%A0,%1) CR_TAB
2044 AS2 (mov,%B0,__tmp_reg__));
2045 else if (reg_base == reg_dest + 2)
2046 return *l=5, (AS2 (ld ,%A0,%1) CR_TAB
2047 AS2 (ldd,%B0,%1+1) CR_TAB
2048 AS2 (ldd,__tmp_reg__,%1+2) CR_TAB
2049 AS2 (ldd,%D0,%1+3) CR_TAB
2050 AS2 (mov,%C0,__tmp_reg__));
2051 else
2052 return *l=4, (AS2 (ld ,%A0,%1) CR_TAB
2053 AS2 (ldd,%B0,%1+1) CR_TAB
2054 AS2 (ldd,%C0,%1+2) CR_TAB
2055 AS2 (ldd,%D0,%1+3));
2058 else if (GET_CODE (base) == PLUS) /* (R + i) */
2060 int disp = INTVAL (XEXP (base, 1));
2062 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2064 if (REGNO (XEXP (base, 0)) != REG_Y)
2065 fatal_insn ("incorrect insn:",insn);
2067 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2068 return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2069 AS2 (ldd,%A0,Y+60) CR_TAB
2070 AS2 (ldd,%B0,Y+61) CR_TAB
2071 AS2 (ldd,%C0,Y+62) CR_TAB
2072 AS2 (ldd,%D0,Y+63) CR_TAB
2073 AS2 (sbiw,r28,%o1-60));
2075 return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2076 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2077 AS2 (ld,%A0,Y) CR_TAB
2078 AS2 (ldd,%B0,Y+1) CR_TAB
2079 AS2 (ldd,%C0,Y+2) CR_TAB
2080 AS2 (ldd,%D0,Y+3) CR_TAB
2081 AS2 (subi,r28,lo8(%o1)) CR_TAB
2082 AS2 (sbci,r29,hi8(%o1)));
2085 reg_base = true_regnum (XEXP (base, 0));
2086 if (reg_base == REG_X)
2088 /* R = (X + d) */
2089 if (reg_dest == REG_X)
2091 *l = 7;
2092 /* "ld r26,-X" is undefined */
2093 return (AS2 (adiw,r26,%o1+3) CR_TAB
2094 AS2 (ld,r29,X) CR_TAB
2095 AS2 (ld,r28,-X) CR_TAB
2096 AS2 (ld,__tmp_reg__,-X) CR_TAB
2097 AS2 (sbiw,r26,1) CR_TAB
2098 AS2 (ld,r26,X) CR_TAB
2099 AS2 (mov,r27,__tmp_reg__));
2101 *l = 6;
2102 if (reg_dest == REG_X - 2)
2103 return (AS2 (adiw,r26,%o1) CR_TAB
2104 AS2 (ld,r24,X+) CR_TAB
2105 AS2 (ld,r25,X+) CR_TAB
2106 AS2 (ld,__tmp_reg__,X+) CR_TAB
2107 AS2 (ld,r27,X) CR_TAB
2108 AS2 (mov,r26,__tmp_reg__));
2110 return (AS2 (adiw,r26,%o1) CR_TAB
2111 AS2 (ld,%A0,X+) CR_TAB
2112 AS2 (ld,%B0,X+) CR_TAB
2113 AS2 (ld,%C0,X+) CR_TAB
2114 AS2 (ld,%D0,X) CR_TAB
2115 AS2 (sbiw,r26,%o1+3));
2117 if (reg_dest == reg_base)
2118 return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2119 AS2 (ldd,%C0,%C1) CR_TAB
2120 AS2 (ldd,__tmp_reg__,%B1) CR_TAB
2121 AS2 (ldd,%A0,%A1) CR_TAB
2122 AS2 (mov,%B0,__tmp_reg__));
2123 else if (reg_dest == reg_base - 2)
2124 return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2125 AS2 (ldd,%B0,%B1) CR_TAB
2126 AS2 (ldd,__tmp_reg__,%C1) CR_TAB
2127 AS2 (ldd,%D0,%D1) CR_TAB
2128 AS2 (mov,%C0,__tmp_reg__));
2129 return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2130 AS2 (ldd,%B0,%B1) CR_TAB
2131 AS2 (ldd,%C0,%C1) CR_TAB
2132 AS2 (ldd,%D0,%D1));
2134 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2135 return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2136 AS2 (ld,%C0,%1) CR_TAB
2137 AS2 (ld,%B0,%1) CR_TAB
2138 AS2 (ld,%A0,%1));
2139 else if (GET_CODE (base) == POST_INC) /* (R++) */
2140 return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2141 AS2 (ld,%B0,%1) CR_TAB
2142 AS2 (ld,%C0,%1) CR_TAB
2143 AS2 (ld,%D0,%1));
2144 else if (CONSTANT_ADDRESS_P (base))
2145 return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2146 AS2 (lds,%B0,%B1) CR_TAB
2147 AS2 (lds,%C0,%C1) CR_TAB
2148 AS2 (lds,%D0,%D1));
2150 fatal_insn ("unknown move insn:",insn);
2151 return "";
2154 const char *
2155 out_movsi_mr_r (rtx insn, rtx op[], int *l)
2157 rtx dest = op[0];
2158 rtx src = op[1];
2159 rtx base = XEXP (dest, 0);
2160 int reg_base = true_regnum (base);
2161 int reg_src = true_regnum (src);
2162 int tmp;
2164 if (!l)
2165 l = &tmp;
2167 if (CONSTANT_ADDRESS_P (base))
2168 return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2169 AS2 (sts,%B0,%B1) CR_TAB
2170 AS2 (sts,%C0,%C1) CR_TAB
2171 AS2 (sts,%D0,%D1));
2172 if (reg_base > 0) /* (r) */
2174 if (reg_base == REG_X) /* (R26) */
2176 if (reg_src == REG_X)
2178 /* "st X+,r26" is undefined */
2179 if (reg_unused_after (insn, base))
2180 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2181 AS2 (st,X,r26) CR_TAB
2182 AS2 (adiw,r26,1) CR_TAB
2183 AS2 (st,X+,__tmp_reg__) CR_TAB
2184 AS2 (st,X+,r28) CR_TAB
2185 AS2 (st,X,r29));
2186 else
2187 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2188 AS2 (st,X,r26) CR_TAB
2189 AS2 (adiw,r26,1) CR_TAB
2190 AS2 (st,X+,__tmp_reg__) CR_TAB
2191 AS2 (st,X+,r28) CR_TAB
2192 AS2 (st,X,r29) CR_TAB
2193 AS2 (sbiw,r26,3));
2195 else if (reg_base == reg_src + 2)
2197 if (reg_unused_after (insn, base))
2198 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2199 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2200 AS2 (st,%0+,%A1) CR_TAB
2201 AS2 (st,%0+,%B1) CR_TAB
2202 AS2 (st,%0+,__zero_reg__) CR_TAB
2203 AS2 (st,%0,__tmp_reg__) CR_TAB
2204 AS1 (clr,__zero_reg__));
2205 else
2206 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2207 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2208 AS2 (st,%0+,%A1) CR_TAB
2209 AS2 (st,%0+,%B1) CR_TAB
2210 AS2 (st,%0+,__zero_reg__) CR_TAB
2211 AS2 (st,%0,__tmp_reg__) CR_TAB
2212 AS1 (clr,__zero_reg__) CR_TAB
2213 AS2 (sbiw,r26,3));
2215 return *l=5, (AS2 (st,%0+,%A1) CR_TAB
2216 AS2 (st,%0+,%B1) CR_TAB
2217 AS2 (st,%0+,%C1) CR_TAB
2218 AS2 (st,%0,%D1) CR_TAB
2219 AS2 (sbiw,r26,3));
2221 else
2222 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2223 AS2 (std,%0+1,%B1) CR_TAB
2224 AS2 (std,%0+2,%C1) CR_TAB
2225 AS2 (std,%0+3,%D1));
2227 else if (GET_CODE (base) == PLUS) /* (R + i) */
2229 int disp = INTVAL (XEXP (base, 1));
2230 reg_base = REGNO (XEXP (base, 0));
2231 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2233 if (reg_base != REG_Y)
2234 fatal_insn ("incorrect insn:",insn);
2236 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2237 return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2238 AS2 (std,Y+60,%A1) CR_TAB
2239 AS2 (std,Y+61,%B1) CR_TAB
2240 AS2 (std,Y+62,%C1) CR_TAB
2241 AS2 (std,Y+63,%D1) CR_TAB
2242 AS2 (sbiw,r28,%o0-60));
2244 return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2245 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2246 AS2 (st,Y,%A1) CR_TAB
2247 AS2 (std,Y+1,%B1) CR_TAB
2248 AS2 (std,Y+2,%C1) CR_TAB
2249 AS2 (std,Y+3,%D1) CR_TAB
2250 AS2 (subi,r28,lo8(%o0)) CR_TAB
2251 AS2 (sbci,r29,hi8(%o0)));
2253 if (reg_base == REG_X)
2255 /* (X + d) = R */
2256 if (reg_src == REG_X)
2258 *l = 9;
2259 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2260 AS2 (mov,__zero_reg__,r27) CR_TAB
2261 AS2 (adiw,r26,%o0) CR_TAB
2262 AS2 (st,X+,__tmp_reg__) CR_TAB
2263 AS2 (st,X+,__zero_reg__) CR_TAB
2264 AS2 (st,X+,r28) CR_TAB
2265 AS2 (st,X,r29) CR_TAB
2266 AS1 (clr,__zero_reg__) CR_TAB
2267 AS2 (sbiw,r26,%o0+3));
2269 else if (reg_src == REG_X - 2)
2271 *l = 9;
2272 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2273 AS2 (mov,__zero_reg__,r27) CR_TAB
2274 AS2 (adiw,r26,%o0) CR_TAB
2275 AS2 (st,X+,r24) CR_TAB
2276 AS2 (st,X+,r25) CR_TAB
2277 AS2 (st,X+,__tmp_reg__) CR_TAB
2278 AS2 (st,X,__zero_reg__) CR_TAB
2279 AS1 (clr,__zero_reg__) CR_TAB
2280 AS2 (sbiw,r26,%o0+3));
2282 *l = 6;
2283 return (AS2 (adiw,r26,%o0) CR_TAB
2284 AS2 (st,X+,%A1) CR_TAB
2285 AS2 (st,X+,%B1) CR_TAB
2286 AS2 (st,X+,%C1) CR_TAB
2287 AS2 (st,X,%D1) CR_TAB
2288 AS2 (sbiw,r26,%o0+3));
2290 return *l=4, (AS2 (std,%A0,%A1) CR_TAB
2291 AS2 (std,%B0,%B1) CR_TAB
2292 AS2 (std,%C0,%C1) CR_TAB
2293 AS2 (std,%D0,%D1));
2295 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2296 return *l=4, (AS2 (st,%0,%D1) CR_TAB
2297 AS2 (st,%0,%C1) CR_TAB
2298 AS2 (st,%0,%B1) CR_TAB
2299 AS2 (st,%0,%A1));
2300 else if (GET_CODE (base) == POST_INC) /* (R++) */
2301 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2302 AS2 (st,%0,%B1) CR_TAB
2303 AS2 (st,%0,%C1) CR_TAB
2304 AS2 (st,%0,%D1));
2305 fatal_insn ("unknown move insn:",insn);
2306 return "";
2309 const char *
2310 output_movsisf(rtx insn, rtx operands[], int *l)
2312 int dummy;
2313 rtx dest = operands[0];
2314 rtx src = operands[1];
2315 int *real_l = l;
2317 if (!l)
2318 l = &dummy;
2320 if (register_operand (dest, VOIDmode))
2322 if (register_operand (src, VOIDmode)) /* mov r,r */
2324 if (true_regnum (dest) > true_regnum (src))
2326 if (AVR_ENHANCED)
2328 *l = 2;
2329 return (AS2 (movw,%C0,%C1) CR_TAB
2330 AS2 (movw,%A0,%A1));
2332 *l = 4;
2333 return (AS2 (mov,%D0,%D1) CR_TAB
2334 AS2 (mov,%C0,%C1) CR_TAB
2335 AS2 (mov,%B0,%B1) CR_TAB
2336 AS2 (mov,%A0,%A1));
2338 else
2340 if (AVR_ENHANCED)
2342 *l = 2;
2343 return (AS2 (movw,%A0,%A1) CR_TAB
2344 AS2 (movw,%C0,%C1));
2346 *l = 4;
2347 return (AS2 (mov,%A0,%A1) CR_TAB
2348 AS2 (mov,%B0,%B1) CR_TAB
2349 AS2 (mov,%C0,%C1) CR_TAB
2350 AS2 (mov,%D0,%D1));
2353 else if (CONSTANT_P (src))
2355 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2357 *l = 4;
2358 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
2359 AS2 (ldi,%B0,hi8(%1)) CR_TAB
2360 AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2361 AS2 (ldi,%D0,hhi8(%1)));
2364 if (GET_CODE (src) == CONST_INT)
2366 const char *const clr_op0 =
2367 AVR_ENHANCED ? (AS1 (clr,%A0) CR_TAB
2368 AS1 (clr,%B0) CR_TAB
2369 AS2 (movw,%C0,%A0))
2370 : (AS1 (clr,%A0) CR_TAB
2371 AS1 (clr,%B0) CR_TAB
2372 AS1 (clr,%C0) CR_TAB
2373 AS1 (clr,%D0));
2375 if (src == const0_rtx) /* mov r,L */
2377 *l = AVR_ENHANCED ? 3 : 4;
2378 return clr_op0;
2380 else if (src == const1_rtx)
2382 if (!real_l)
2383 output_asm_insn (clr_op0, operands);
2384 *l = AVR_ENHANCED ? 4 : 5;
2385 return AS1 (inc,%A0);
2387 else if (src == constm1_rtx)
2389 /* Immediate constants -1 to any register */
2390 if (AVR_ENHANCED)
2392 *l = 4;
2393 return (AS1 (clr,%A0) CR_TAB
2394 AS1 (dec,%A0) CR_TAB
2395 AS2 (mov,%B0,%A0) CR_TAB
2396 AS2 (movw,%C0,%A0));
2398 *l = 5;
2399 return (AS1 (clr,%A0) CR_TAB
2400 AS1 (dec,%A0) CR_TAB
2401 AS2 (mov,%B0,%A0) CR_TAB
2402 AS2 (mov,%C0,%A0) CR_TAB
2403 AS2 (mov,%D0,%A0));
2405 else
2407 int bit_nr = exact_log2 (INTVAL (src));
2409 if (bit_nr >= 0)
2411 *l = AVR_ENHANCED ? 5 : 6;
2412 if (!real_l)
2414 output_asm_insn (clr_op0, operands);
2415 output_asm_insn ("set", operands);
2417 if (!real_l)
2418 avr_output_bld (operands, bit_nr);
2420 return "";
2425 /* Last resort, better than loading from memory. */
2426 *l = 10;
2427 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2428 AS2 (ldi,r31,lo8(%1)) CR_TAB
2429 AS2 (mov,%A0,r31) CR_TAB
2430 AS2 (ldi,r31,hi8(%1)) CR_TAB
2431 AS2 (mov,%B0,r31) CR_TAB
2432 AS2 (ldi,r31,hlo8(%1)) CR_TAB
2433 AS2 (mov,%C0,r31) CR_TAB
2434 AS2 (ldi,r31,hhi8(%1)) CR_TAB
2435 AS2 (mov,%D0,r31) CR_TAB
2436 AS2 (mov,r31,__tmp_reg__));
2438 else if (GET_CODE (src) == MEM)
2439 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2441 else if (GET_CODE (dest) == MEM)
2443 const char *template;
2445 if (src == const0_rtx)
2446 operands[1] = zero_reg_rtx;
2448 template = out_movsi_mr_r (insn, operands, real_l);
2450 if (!real_l)
2451 output_asm_insn (template, operands);
2453 operands[1] = src;
2454 return "";
2456 fatal_insn ("invalid insn:", insn);
2457 return "";
2460 const char *
2461 out_movqi_mr_r (rtx insn, rtx op[], int *l)
2463 rtx dest = op[0];
2464 rtx src = op[1];
2465 rtx x = XEXP (dest, 0);
2466 int dummy;
2468 if (!l)
2469 l = &dummy;
2471 if (CONSTANT_ADDRESS_P (x))
2473 if (avr_io_address_p (x, 1))
2475 *l = 1;
2476 return AS2 (out,%0-0x20,%1);
2478 *l = 2;
2479 return AS2 (sts,%0,%1);
2481 /* memory access by reg+disp */
2482 else if (GET_CODE (x) == PLUS
2483 && REG_P (XEXP (x,0))
2484 && GET_CODE (XEXP (x,1)) == CONST_INT)
2486 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2488 int disp = INTVAL (XEXP (x,1));
2489 if (REGNO (XEXP (x,0)) != REG_Y)
2490 fatal_insn ("incorrect insn:",insn);
2492 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2493 return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2494 AS2 (std,Y+63,%1) CR_TAB
2495 AS2 (sbiw,r28,%o0-63));
2497 return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2498 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2499 AS2 (st,Y,%1) CR_TAB
2500 AS2 (subi,r28,lo8(%o0)) CR_TAB
2501 AS2 (sbci,r29,hi8(%o0)));
2503 else if (REGNO (XEXP (x,0)) == REG_X)
2505 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2507 if (reg_unused_after (insn, XEXP (x,0)))
2508 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2509 AS2 (adiw,r26,%o0) CR_TAB
2510 AS2 (st,X,__tmp_reg__));
2512 return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2513 AS2 (adiw,r26,%o0) CR_TAB
2514 AS2 (st,X,__tmp_reg__) CR_TAB
2515 AS2 (sbiw,r26,%o0));
2517 else
2519 if (reg_unused_after (insn, XEXP (x,0)))
2520 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2521 AS2 (st,X,%1));
2523 return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2524 AS2 (st,X,%1) CR_TAB
2525 AS2 (sbiw,r26,%o0));
2528 *l = 1;
2529 return AS2 (std,%0,%1);
2531 *l = 1;
2532 return AS2 (st,%0,%1);
2535 const char *
2536 out_movhi_mr_r (rtx insn, rtx op[], int *l)
2538 rtx dest = op[0];
2539 rtx src = op[1];
2540 rtx base = XEXP (dest, 0);
2541 int reg_base = true_regnum (base);
2542 int reg_src = true_regnum (src);
2543 /* "volatile" forces writing high byte first, even if less efficient,
2544 for correct operation with 16-bit I/O registers. */
2545 int mem_volatile_p = MEM_VOLATILE_P (dest);
2546 int tmp;
2548 if (!l)
2549 l = &tmp;
2550 if (CONSTANT_ADDRESS_P (base))
2552 if (avr_io_address_p (base, 2))
2554 *l = 2;
2555 return (AS2 (out,%B0-0x20,%B1) CR_TAB
2556 AS2 (out,%A0-0x20,%A1));
2558 return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2559 AS2 (sts,%A0,%A1));
2561 if (reg_base > 0)
2563 if (reg_base == REG_X)
2565 if (reg_src == REG_X)
2567 /* "st X+,r26" and "st -X,r26" are undefined. */
2568 if (!mem_volatile_p && reg_unused_after (insn, src))
2569 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2570 AS2 (st,X,r26) CR_TAB
2571 AS2 (adiw,r26,1) CR_TAB
2572 AS2 (st,X,__tmp_reg__));
2573 else
2574 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2575 AS2 (adiw,r26,1) CR_TAB
2576 AS2 (st,X,__tmp_reg__) CR_TAB
2577 AS2 (sbiw,r26,1) CR_TAB
2578 AS2 (st,X,r26));
2580 else
2582 if (!mem_volatile_p && reg_unused_after (insn, base))
2583 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2584 AS2 (st,X,%B1));
2585 else
2586 return *l=3, (AS2 (adiw,r26,1) CR_TAB
2587 AS2 (st,X,%B1) CR_TAB
2588 AS2 (st,-X,%A1));
2591 else
2592 return *l=2, (AS2 (std,%0+1,%B1) CR_TAB
2593 AS2 (st,%0,%A1));
2595 else if (GET_CODE (base) == PLUS)
2597 int disp = INTVAL (XEXP (base, 1));
2598 reg_base = REGNO (XEXP (base, 0));
2599 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2601 if (reg_base != REG_Y)
2602 fatal_insn ("incorrect insn:",insn);
2604 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2605 return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2606 AS2 (std,Y+63,%B1) CR_TAB
2607 AS2 (std,Y+62,%A1) CR_TAB
2608 AS2 (sbiw,r28,%o0-62));
2610 return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2611 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2612 AS2 (std,Y+1,%B1) CR_TAB
2613 AS2 (st,Y,%A1) CR_TAB
2614 AS2 (subi,r28,lo8(%o0)) CR_TAB
2615 AS2 (sbci,r29,hi8(%o0)));
2617 if (reg_base == REG_X)
2619 /* (X + d) = R */
2620 if (reg_src == REG_X)
2622 *l = 7;
2623 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2624 AS2 (mov,__zero_reg__,r27) CR_TAB
2625 AS2 (adiw,r26,%o0+1) CR_TAB
2626 AS2 (st,X,__zero_reg__) CR_TAB
2627 AS2 (st,-X,__tmp_reg__) CR_TAB
2628 AS1 (clr,__zero_reg__) CR_TAB
2629 AS2 (sbiw,r26,%o0));
2631 *l = 4;
2632 return (AS2 (adiw,r26,%o0+1) CR_TAB
2633 AS2 (st,X,%B1) CR_TAB
2634 AS2 (st,-X,%A1) CR_TAB
2635 AS2 (sbiw,r26,%o0));
2637 return *l=2, (AS2 (std,%B0,%B1) CR_TAB
2638 AS2 (std,%A0,%A1));
2640 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2641 return *l=2, (AS2 (st,%0,%B1) CR_TAB
2642 AS2 (st,%0,%A1));
2643 else if (GET_CODE (base) == POST_INC) /* (R++) */
2645 if (mem_volatile_p)
2647 if (REGNO (XEXP (base, 0)) == REG_X)
2649 *l = 4;
2650 return (AS2 (adiw,r26,1) CR_TAB
2651 AS2 (st,X,%B1) CR_TAB
2652 AS2 (st,-X,%A1) CR_TAB
2653 AS2 (adiw,r26,2));
2655 else
2657 *l = 3;
2658 return (AS2 (std,%p0+1,%B1) CR_TAB
2659 AS2 (st,%p0,%A1) CR_TAB
2660 AS2 (adiw,%r0,2));
2664 *l = 2;
2665 return (AS2 (st,%0,%A1) CR_TAB
2666 AS2 (st,%0,%B1));
2668 fatal_insn ("unknown move insn:",insn);
2669 return "";
2672 /* Return 1 if frame pointer for current function required. */
2675 frame_pointer_required_p (void)
2677 return (current_function_calls_alloca
2678 || current_function_args_info.nregs == 0
2679 || get_frame_size () > 0);
2682 /* Returns the condition of compare insn INSN, or UNKNOWN. */
2684 static RTX_CODE
2685 compare_condition (rtx insn)
2687 rtx next = next_real_insn (insn);
2688 RTX_CODE cond = UNKNOWN;
2689 if (next && GET_CODE (next) == JUMP_INSN)
2691 rtx pat = PATTERN (next);
2692 rtx src = SET_SRC (pat);
2693 rtx t = XEXP (src, 0);
2694 cond = GET_CODE (t);
2696 return cond;
2699 /* Returns nonzero if INSN is a tst insn that only tests the sign. */
2701 static int
2702 compare_sign_p (rtx insn)
2704 RTX_CODE cond = compare_condition (insn);
2705 return (cond == GE || cond == LT);
2708 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
2709 that needs to be swapped (GT, GTU, LE, LEU). */
2712 compare_diff_p (rtx insn)
2714 RTX_CODE cond = compare_condition (insn);
2715 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2718 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition. */
2721 compare_eq_p (rtx insn)
2723 RTX_CODE cond = compare_condition (insn);
2724 return (cond == EQ || cond == NE);
2728 /* Output test instruction for HImode. */
2730 const char *
2731 out_tsthi (rtx insn, int *l)
2733 if (compare_sign_p (insn))
2735 if (l) *l = 1;
2736 return AS1 (tst,%B0);
2738 if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
2739 && compare_eq_p (insn))
2741 /* Faster than sbiw if we can clobber the operand. */
2742 if (l) *l = 1;
2743 return AS2 (or,%A0,%B0);
2745 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2747 if (l) *l = 1;
2748 return AS2 (sbiw,%0,0);
2750 if (l) *l = 2;
2751 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2752 AS2 (cpc,%B0,__zero_reg__));
2756 /* Output test instruction for SImode. */
2758 const char *
2759 out_tstsi (rtx insn, int *l)
2761 if (compare_sign_p (insn))
2763 if (l) *l = 1;
2764 return AS1 (tst,%D0);
2766 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2768 if (l) *l = 3;
2769 return (AS2 (sbiw,%A0,0) CR_TAB
2770 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2771 AS2 (cpc,%D0,__zero_reg__));
2773 if (l) *l = 4;
2774 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2775 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2776 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2777 AS2 (cpc,%D0,__zero_reg__));
2781 /* Generate asm equivalent for various shifts.
2782 Shift count is a CONST_INT, MEM or REG.
2783 This only handles cases that are not already
2784 carefully hand-optimized in ?sh??i3_out. */
2786 void
2787 out_shift_with_cnt (const char *template, rtx insn, rtx operands[],
2788 int *len, int t_len)
2790 rtx op[10];
2791 char str[500];
2792 int second_label = 1;
2793 int saved_in_tmp = 0;
2794 int use_zero_reg = 0;
2796 op[0] = operands[0];
2797 op[1] = operands[1];
2798 op[2] = operands[2];
2799 op[3] = operands[3];
2800 str[0] = 0;
2802 if (len)
2803 *len = 1;
2805 if (GET_CODE (operands[2]) == CONST_INT)
2807 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2808 int count = INTVAL (operands[2]);
2809 int max_len = 10; /* If larger than this, always use a loop. */
2811 if (count <= 0)
2813 if (len)
2814 *len = 0;
2815 return;
2818 if (count < 8 && !scratch)
2819 use_zero_reg = 1;
2821 if (optimize_size)
2822 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
2824 if (t_len * count <= max_len)
2826 /* Output shifts inline with no loop - faster. */
2827 if (len)
2828 *len = t_len * count;
2829 else
2831 while (count-- > 0)
2832 output_asm_insn (template, op);
2835 return;
2838 if (scratch)
2840 if (!len)
2841 strcat (str, AS2 (ldi,%3,%2));
2843 else if (use_zero_reg)
2845 /* Hack to save one word: use __zero_reg__ as loop counter.
2846 Set one bit, then shift in a loop until it is 0 again. */
2848 op[3] = zero_reg_rtx;
2849 if (len)
2850 *len = 2;
2851 else
2852 strcat (str, ("set" CR_TAB
2853 AS2 (bld,%3,%2-1)));
2855 else
2857 /* No scratch register available, use one from LD_REGS (saved in
2858 __tmp_reg__) that doesn't overlap with registers to shift. */
2860 op[3] = gen_rtx_REG (QImode,
2861 ((true_regnum (operands[0]) - 1) & 15) + 16);
2862 op[4] = tmp_reg_rtx;
2863 saved_in_tmp = 1;
2865 if (len)
2866 *len = 3; /* Includes "mov %3,%4" after the loop. */
2867 else
2868 strcat (str, (AS2 (mov,%4,%3) CR_TAB
2869 AS2 (ldi,%3,%2)));
2872 second_label = 0;
2874 else if (GET_CODE (operands[2]) == MEM)
2876 rtx op_mov[10];
2878 op[3] = op_mov[0] = tmp_reg_rtx;
2879 op_mov[1] = op[2];
2881 if (len)
2882 out_movqi_r_mr (insn, op_mov, len);
2883 else
2884 output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2886 else if (register_operand (operands[2], QImode))
2888 if (reg_unused_after (insn, operands[2]))
2889 op[3] = op[2];
2890 else
2892 op[3] = tmp_reg_rtx;
2893 if (!len)
2894 strcat (str, (AS2 (mov,%3,%2) CR_TAB));
2897 else
2898 fatal_insn ("bad shift insn:", insn);
2900 if (second_label)
2902 if (len)
2903 ++*len;
2904 else
2905 strcat (str, AS1 (rjmp,2f));
2908 if (len)
2909 *len += t_len + 2; /* template + dec + brXX */
2910 else
2912 strcat (str, "\n1:\t");
2913 strcat (str, template);
2914 strcat (str, second_label ? "\n2:\t" : "\n\t");
2915 strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
2916 strcat (str, CR_TAB);
2917 strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
2918 if (saved_in_tmp)
2919 strcat (str, (CR_TAB AS2 (mov,%3,%4)));
2920 output_asm_insn (str, op);
2925 /* 8bit shift left ((char)x << i) */
2927 const char *
2928 ashlqi3_out (rtx insn, rtx operands[], int *len)
2930 if (GET_CODE (operands[2]) == CONST_INT)
2932 int k;
2934 if (!len)
2935 len = &k;
2937 switch (INTVAL (operands[2]))
2939 default:
2940 if (INTVAL (operands[2]) < 8)
2941 break;
2943 *len = 1;
2944 return AS1 (clr,%0);
2946 case 1:
2947 *len = 1;
2948 return AS1 (lsl,%0);
2950 case 2:
2951 *len = 2;
2952 return (AS1 (lsl,%0) CR_TAB
2953 AS1 (lsl,%0));
2955 case 3:
2956 *len = 3;
2957 return (AS1 (lsl,%0) CR_TAB
2958 AS1 (lsl,%0) CR_TAB
2959 AS1 (lsl,%0));
2961 case 4:
2962 if (test_hard_reg_class (LD_REGS, operands[0]))
2964 *len = 2;
2965 return (AS1 (swap,%0) CR_TAB
2966 AS2 (andi,%0,0xf0));
2968 *len = 4;
2969 return (AS1 (lsl,%0) CR_TAB
2970 AS1 (lsl,%0) CR_TAB
2971 AS1 (lsl,%0) CR_TAB
2972 AS1 (lsl,%0));
2974 case 5:
2975 if (test_hard_reg_class (LD_REGS, operands[0]))
2977 *len = 3;
2978 return (AS1 (swap,%0) CR_TAB
2979 AS1 (lsl,%0) CR_TAB
2980 AS2 (andi,%0,0xe0));
2982 *len = 5;
2983 return (AS1 (lsl,%0) CR_TAB
2984 AS1 (lsl,%0) CR_TAB
2985 AS1 (lsl,%0) CR_TAB
2986 AS1 (lsl,%0) CR_TAB
2987 AS1 (lsl,%0));
2989 case 6:
2990 if (test_hard_reg_class (LD_REGS, operands[0]))
2992 *len = 4;
2993 return (AS1 (swap,%0) CR_TAB
2994 AS1 (lsl,%0) CR_TAB
2995 AS1 (lsl,%0) CR_TAB
2996 AS2 (andi,%0,0xc0));
2998 *len = 6;
2999 return (AS1 (lsl,%0) CR_TAB
3000 AS1 (lsl,%0) CR_TAB
3001 AS1 (lsl,%0) CR_TAB
3002 AS1 (lsl,%0) CR_TAB
3003 AS1 (lsl,%0) CR_TAB
3004 AS1 (lsl,%0));
3006 case 7:
3007 *len = 3;
3008 return (AS1 (ror,%0) CR_TAB
3009 AS1 (clr,%0) CR_TAB
3010 AS1 (ror,%0));
3013 else if (CONSTANT_P (operands[2]))
3014 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3016 out_shift_with_cnt (AS1 (lsl,%0),
3017 insn, operands, len, 1);
3018 return "";
3022 /* 16bit shift left ((short)x << i) */
3024 const char *
3025 ashlhi3_out (rtx insn, rtx operands[], int *len)
3027 if (GET_CODE (operands[2]) == CONST_INT)
3029 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3030 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3031 int k;
3032 int *t = len;
3034 if (!len)
3035 len = &k;
3037 switch (INTVAL (operands[2]))
3039 default:
3040 if (INTVAL (operands[2]) < 16)
3041 break;
3043 *len = 2;
3044 return (AS1 (clr,%B0) CR_TAB
3045 AS1 (clr,%A0));
3047 case 4:
3048 if (optimize_size && scratch)
3049 break; /* 5 */
3050 if (ldi_ok)
3052 *len = 6;
3053 return (AS1 (swap,%A0) CR_TAB
3054 AS1 (swap,%B0) CR_TAB
3055 AS2 (andi,%B0,0xf0) CR_TAB
3056 AS2 (eor,%B0,%A0) CR_TAB
3057 AS2 (andi,%A0,0xf0) CR_TAB
3058 AS2 (eor,%B0,%A0));
3060 if (scratch)
3062 *len = 7;
3063 return (AS1 (swap,%A0) CR_TAB
3064 AS1 (swap,%B0) CR_TAB
3065 AS2 (ldi,%3,0xf0) CR_TAB
3066 AS2 (and,%B0,%3) CR_TAB
3067 AS2 (eor,%B0,%A0) CR_TAB
3068 AS2 (and,%A0,%3) CR_TAB
3069 AS2 (eor,%B0,%A0));
3071 break; /* optimize_size ? 6 : 8 */
3073 case 5:
3074 if (optimize_size)
3075 break; /* scratch ? 5 : 6 */
3076 if (ldi_ok)
3078 *len = 8;
3079 return (AS1 (lsl,%A0) CR_TAB
3080 AS1 (rol,%B0) CR_TAB
3081 AS1 (swap,%A0) CR_TAB
3082 AS1 (swap,%B0) CR_TAB
3083 AS2 (andi,%B0,0xf0) CR_TAB
3084 AS2 (eor,%B0,%A0) CR_TAB
3085 AS2 (andi,%A0,0xf0) CR_TAB
3086 AS2 (eor,%B0,%A0));
3088 if (scratch)
3090 *len = 9;
3091 return (AS1 (lsl,%A0) CR_TAB
3092 AS1 (rol,%B0) CR_TAB
3093 AS1 (swap,%A0) CR_TAB
3094 AS1 (swap,%B0) CR_TAB
3095 AS2 (ldi,%3,0xf0) CR_TAB
3096 AS2 (and,%B0,%3) CR_TAB
3097 AS2 (eor,%B0,%A0) CR_TAB
3098 AS2 (and,%A0,%3) CR_TAB
3099 AS2 (eor,%B0,%A0));
3101 break; /* 10 */
3103 case 6:
3104 if (optimize_size)
3105 break; /* scratch ? 5 : 6 */
3106 *len = 9;
3107 return (AS1 (clr,__tmp_reg__) CR_TAB
3108 AS1 (lsr,%B0) CR_TAB
3109 AS1 (ror,%A0) CR_TAB
3110 AS1 (ror,__tmp_reg__) CR_TAB
3111 AS1 (lsr,%B0) CR_TAB
3112 AS1 (ror,%A0) CR_TAB
3113 AS1 (ror,__tmp_reg__) CR_TAB
3114 AS2 (mov,%B0,%A0) CR_TAB
3115 AS2 (mov,%A0,__tmp_reg__));
3117 case 7:
3118 *len = 5;
3119 return (AS1 (lsr,%B0) CR_TAB
3120 AS2 (mov,%B0,%A0) CR_TAB
3121 AS1 (clr,%A0) CR_TAB
3122 AS1 (ror,%B0) CR_TAB
3123 AS1 (ror,%A0));
3125 case 8:
3126 if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
3127 return *len = 1, AS1 (clr,%A0);
3128 else
3129 return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3130 AS1 (clr,%A0));
3132 case 9:
3133 *len = 3;
3134 return (AS2 (mov,%B0,%A0) CR_TAB
3135 AS1 (clr,%A0) CR_TAB
3136 AS1 (lsl,%B0));
3138 case 10:
3139 *len = 4;
3140 return (AS2 (mov,%B0,%A0) CR_TAB
3141 AS1 (clr,%A0) CR_TAB
3142 AS1 (lsl,%B0) CR_TAB
3143 AS1 (lsl,%B0));
3145 case 11:
3146 *len = 5;
3147 return (AS2 (mov,%B0,%A0) CR_TAB
3148 AS1 (clr,%A0) CR_TAB
3149 AS1 (lsl,%B0) CR_TAB
3150 AS1 (lsl,%B0) CR_TAB
3151 AS1 (lsl,%B0));
3153 case 12:
3154 if (ldi_ok)
3156 *len = 4;
3157 return (AS2 (mov,%B0,%A0) CR_TAB
3158 AS1 (clr,%A0) CR_TAB
3159 AS1 (swap,%B0) CR_TAB
3160 AS2 (andi,%B0,0xf0));
3162 if (scratch)
3164 *len = 5;
3165 return (AS2 (mov,%B0,%A0) CR_TAB
3166 AS1 (clr,%A0) CR_TAB
3167 AS1 (swap,%B0) CR_TAB
3168 AS2 (ldi,%3,0xf0) CR_TAB
3169 AS2 (and,%B0,%3));
3171 *len = 6;
3172 return (AS2 (mov,%B0,%A0) CR_TAB
3173 AS1 (clr,%A0) CR_TAB
3174 AS1 (lsl,%B0) CR_TAB
3175 AS1 (lsl,%B0) CR_TAB
3176 AS1 (lsl,%B0) CR_TAB
3177 AS1 (lsl,%B0));
3179 case 13:
3180 if (ldi_ok)
3182 *len = 5;
3183 return (AS2 (mov,%B0,%A0) CR_TAB
3184 AS1 (clr,%A0) CR_TAB
3185 AS1 (swap,%B0) CR_TAB
3186 AS1 (lsl,%B0) CR_TAB
3187 AS2 (andi,%B0,0xe0));
3189 if (AVR_ENHANCED && scratch)
3191 *len = 5;
3192 return (AS2 (ldi,%3,0x20) CR_TAB
3193 AS2 (mul,%A0,%3) CR_TAB
3194 AS2 (mov,%B0,r0) CR_TAB
3195 AS1 (clr,%A0) CR_TAB
3196 AS1 (clr,__zero_reg__));
3198 if (optimize_size && scratch)
3199 break; /* 5 */
3200 if (scratch)
3202 *len = 6;
3203 return (AS2 (mov,%B0,%A0) CR_TAB
3204 AS1 (clr,%A0) CR_TAB
3205 AS1 (swap,%B0) CR_TAB
3206 AS1 (lsl,%B0) CR_TAB
3207 AS2 (ldi,%3,0xe0) CR_TAB
3208 AS2 (and,%B0,%3));
3210 if (AVR_ENHANCED)
3212 *len = 6;
3213 return ("set" CR_TAB
3214 AS2 (bld,r1,5) CR_TAB
3215 AS2 (mul,%A0,r1) CR_TAB
3216 AS2 (mov,%B0,r0) CR_TAB
3217 AS1 (clr,%A0) CR_TAB
3218 AS1 (clr,__zero_reg__));
3220 *len = 7;
3221 return (AS2 (mov,%B0,%A0) CR_TAB
3222 AS1 (clr,%A0) CR_TAB
3223 AS1 (lsl,%B0) CR_TAB
3224 AS1 (lsl,%B0) CR_TAB
3225 AS1 (lsl,%B0) CR_TAB
3226 AS1 (lsl,%B0) CR_TAB
3227 AS1 (lsl,%B0));
3229 case 14:
3230 if (AVR_ENHANCED && ldi_ok)
3232 *len = 5;
3233 return (AS2 (ldi,%B0,0x40) CR_TAB
3234 AS2 (mul,%A0,%B0) CR_TAB
3235 AS2 (mov,%B0,r0) CR_TAB
3236 AS1 (clr,%A0) CR_TAB
3237 AS1 (clr,__zero_reg__));
3239 if (AVR_ENHANCED && scratch)
3241 *len = 5;
3242 return (AS2 (ldi,%3,0x40) CR_TAB
3243 AS2 (mul,%A0,%3) CR_TAB
3244 AS2 (mov,%B0,r0) CR_TAB
3245 AS1 (clr,%A0) CR_TAB
3246 AS1 (clr,__zero_reg__));
3248 if (optimize_size && ldi_ok)
3250 *len = 5;
3251 return (AS2 (mov,%B0,%A0) CR_TAB
3252 AS2 (ldi,%A0,6) "\n1:\t"
3253 AS1 (lsl,%B0) CR_TAB
3254 AS1 (dec,%A0) CR_TAB
3255 AS1 (brne,1b));
3257 if (optimize_size && scratch)
3258 break; /* 5 */
3259 *len = 6;
3260 return (AS1 (clr,%B0) CR_TAB
3261 AS1 (lsr,%A0) CR_TAB
3262 AS1 (ror,%B0) CR_TAB
3263 AS1 (lsr,%A0) CR_TAB
3264 AS1 (ror,%B0) CR_TAB
3265 AS1 (clr,%A0));
3267 case 15:
3268 *len = 4;
3269 return (AS1 (clr,%B0) CR_TAB
3270 AS1 (lsr,%A0) CR_TAB
3271 AS1 (ror,%B0) CR_TAB
3272 AS1 (clr,%A0));
3274 len = t;
3276 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3277 AS1 (rol,%B0)),
3278 insn, operands, len, 2);
3279 return "";
3283 /* 32bit shift left ((long)x << i) */
3285 const char *
3286 ashlsi3_out (rtx insn, rtx operands[], int *len)
3288 if (GET_CODE (operands[2]) == CONST_INT)
3290 int k;
3291 int *t = len;
3293 if (!len)
3294 len = &k;
3296 switch (INTVAL (operands[2]))
3298 default:
3299 if (INTVAL (operands[2]) < 32)
3300 break;
3302 if (AVR_ENHANCED)
3303 return *len = 3, (AS1 (clr,%D0) CR_TAB
3304 AS1 (clr,%C0) CR_TAB
3305 AS2 (movw,%A0,%C0));
3306 *len = 4;
3307 return (AS1 (clr,%D0) CR_TAB
3308 AS1 (clr,%C0) CR_TAB
3309 AS1 (clr,%B0) CR_TAB
3310 AS1 (clr,%A0));
3312 case 8:
3314 int reg0 = true_regnum (operands[0]);
3315 int reg1 = true_regnum (operands[1]);
3316 *len = 4;
3317 if (reg0 >= reg1)
3318 return (AS2 (mov,%D0,%C1) CR_TAB
3319 AS2 (mov,%C0,%B1) CR_TAB
3320 AS2 (mov,%B0,%A1) CR_TAB
3321 AS1 (clr,%A0));
3322 else if (reg0 + 1 == reg1)
3324 *len = 1;
3325 return AS1 (clr,%A0);
3327 else
3328 return (AS1 (clr,%A0) CR_TAB
3329 AS2 (mov,%B0,%A1) CR_TAB
3330 AS2 (mov,%C0,%B1) CR_TAB
3331 AS2 (mov,%D0,%C1));
3334 case 16:
3336 int reg0 = true_regnum (operands[0]);
3337 int reg1 = true_regnum (operands[1]);
3338 *len = 4;
3339 if (AVR_ENHANCED && (reg0 + 2 != reg1))
3341 *len = 3;
3342 return (AS2 (movw,%C0,%A1) CR_TAB
3343 AS1 (clr,%B0) CR_TAB
3344 AS1 (clr,%A0));
3346 if (reg0 + 1 >= reg1)
3347 return (AS2 (mov,%D0,%B1) CR_TAB
3348 AS2 (mov,%C0,%A1) CR_TAB
3349 AS1 (clr,%B0) CR_TAB
3350 AS1 (clr,%A0));
3351 if (reg0 + 2 == reg1)
3353 *len = 2;
3354 return (AS1 (clr,%B0) CR_TAB
3355 AS1 (clr,%A0));
3357 else
3358 return (AS2 (mov,%C0,%A1) CR_TAB
3359 AS2 (mov,%D0,%B1) CR_TAB
3360 AS1 (clr,%B0) CR_TAB
3361 AS1 (clr,%A0));
3364 case 24:
3365 *len = 4;
3366 if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
3367 return (AS2 (mov,%D0,%A1) CR_TAB
3368 AS1 (clr,%C0) CR_TAB
3369 AS1 (clr,%B0) CR_TAB
3370 AS1 (clr,%A0));
3371 else
3373 *len = 3;
3374 return (AS1 (clr,%C0) CR_TAB
3375 AS1 (clr,%B0) CR_TAB
3376 AS1 (clr,%A0));
3379 case 31:
3380 *len = 6;
3381 return (AS1 (clr,%D0) CR_TAB
3382 AS1 (lsr,%A0) CR_TAB
3383 AS1 (ror,%D0) CR_TAB
3384 AS1 (clr,%C0) CR_TAB
3385 AS1 (clr,%B0) CR_TAB
3386 AS1 (clr,%A0));
3388 len = t;
3390 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3391 AS1 (rol,%B0) CR_TAB
3392 AS1 (rol,%C0) CR_TAB
3393 AS1 (rol,%D0)),
3394 insn, operands, len, 4);
3395 return "";
3398 /* 8bit arithmetic shift right ((signed char)x >> i) */
3400 const char *
3401 ashrqi3_out (rtx insn, rtx operands[], int *len)
3403 if (GET_CODE (operands[2]) == CONST_INT)
3405 int k;
3407 if (!len)
3408 len = &k;
3410 switch (INTVAL (operands[2]))
3412 case 1:
3413 *len = 1;
3414 return AS1 (asr,%0);
3416 case 2:
3417 *len = 2;
3418 return (AS1 (asr,%0) CR_TAB
3419 AS1 (asr,%0));
3421 case 3:
3422 *len = 3;
3423 return (AS1 (asr,%0) CR_TAB
3424 AS1 (asr,%0) CR_TAB
3425 AS1 (asr,%0));
3427 case 4:
3428 *len = 4;
3429 return (AS1 (asr,%0) CR_TAB
3430 AS1 (asr,%0) CR_TAB
3431 AS1 (asr,%0) CR_TAB
3432 AS1 (asr,%0));
3434 case 5:
3435 *len = 5;
3436 return (AS1 (asr,%0) CR_TAB
3437 AS1 (asr,%0) CR_TAB
3438 AS1 (asr,%0) CR_TAB
3439 AS1 (asr,%0) CR_TAB
3440 AS1 (asr,%0));
3442 case 6:
3443 *len = 4;
3444 return (AS2 (bst,%0,6) CR_TAB
3445 AS1 (lsl,%0) CR_TAB
3446 AS2 (sbc,%0,%0) CR_TAB
3447 AS2 (bld,%0,0));
3449 default:
3450 if (INTVAL (operands[2]) < 8)
3451 break;
3453 /* fall through */
3455 case 7:
3456 *len = 2;
3457 return (AS1 (lsl,%0) CR_TAB
3458 AS2 (sbc,%0,%0));
3461 else if (CONSTANT_P (operands[2]))
3462 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3464 out_shift_with_cnt (AS1 (asr,%0),
3465 insn, operands, len, 1);
3466 return "";
3470 /* 16bit arithmetic shift right ((signed short)x >> i) */
3472 const char *
3473 ashrhi3_out (rtx insn, rtx operands[], int *len)
3475 if (GET_CODE (operands[2]) == CONST_INT)
3477 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3478 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3479 int k;
3480 int *t = len;
3482 if (!len)
3483 len = &k;
3485 switch (INTVAL (operands[2]))
3487 case 4:
3488 case 5:
3489 /* XXX try to optimize this too? */
3490 break;
3492 case 6:
3493 if (optimize_size)
3494 break; /* scratch ? 5 : 6 */
3495 *len = 8;
3496 return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3497 AS2 (mov,%A0,%B0) CR_TAB
3498 AS1 (lsl,__tmp_reg__) CR_TAB
3499 AS1 (rol,%A0) CR_TAB
3500 AS2 (sbc,%B0,%B0) CR_TAB
3501 AS1 (lsl,__tmp_reg__) CR_TAB
3502 AS1 (rol,%A0) CR_TAB
3503 AS1 (rol,%B0));
3505 case 7:
3506 *len = 4;
3507 return (AS1 (lsl,%A0) CR_TAB
3508 AS2 (mov,%A0,%B0) CR_TAB
3509 AS1 (rol,%A0) CR_TAB
3510 AS2 (sbc,%B0,%B0));
3512 case 8:
3514 int reg0 = true_regnum (operands[0]);
3515 int reg1 = true_regnum (operands[1]);
3517 if (reg0 == reg1)
3518 return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3519 AS1 (lsl,%B0) CR_TAB
3520 AS2 (sbc,%B0,%B0));
3521 else if (reg0 == reg1 + 1)
3522 return *len = 3, (AS1 (clr,%B0) CR_TAB
3523 AS2 (sbrc,%A0,7) CR_TAB
3524 AS1 (dec,%B0));
3526 return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3527 AS1 (clr,%B0) CR_TAB
3528 AS2 (sbrc,%A0,7) CR_TAB
3529 AS1 (dec,%B0));
3532 case 9:
3533 *len = 4;
3534 return (AS2 (mov,%A0,%B0) CR_TAB
3535 AS1 (lsl,%B0) CR_TAB
3536 AS2 (sbc,%B0,%B0) CR_TAB
3537 AS1 (asr,%A0));
3539 case 10:
3540 *len = 5;
3541 return (AS2 (mov,%A0,%B0) CR_TAB
3542 AS1 (lsl,%B0) CR_TAB
3543 AS2 (sbc,%B0,%B0) CR_TAB
3544 AS1 (asr,%A0) CR_TAB
3545 AS1 (asr,%A0));
3547 case 11:
3548 if (AVR_ENHANCED && ldi_ok)
3550 *len = 5;
3551 return (AS2 (ldi,%A0,0x20) CR_TAB
3552 AS2 (muls,%B0,%A0) CR_TAB
3553 AS2 (mov,%A0,r1) CR_TAB
3554 AS2 (sbc,%B0,%B0) CR_TAB
3555 AS1 (clr,__zero_reg__));
3557 if (optimize_size && scratch)
3558 break; /* 5 */
3559 *len = 6;
3560 return (AS2 (mov,%A0,%B0) CR_TAB
3561 AS1 (lsl,%B0) CR_TAB
3562 AS2 (sbc,%B0,%B0) CR_TAB
3563 AS1 (asr,%A0) CR_TAB
3564 AS1 (asr,%A0) CR_TAB
3565 AS1 (asr,%A0));
3567 case 12:
3568 if (AVR_ENHANCED && ldi_ok)
3570 *len = 5;
3571 return (AS2 (ldi,%A0,0x10) CR_TAB
3572 AS2 (muls,%B0,%A0) CR_TAB
3573 AS2 (mov,%A0,r1) CR_TAB
3574 AS2 (sbc,%B0,%B0) CR_TAB
3575 AS1 (clr,__zero_reg__));
3577 if (optimize_size && scratch)
3578 break; /* 5 */
3579 *len = 7;
3580 return (AS2 (mov,%A0,%B0) CR_TAB
3581 AS1 (lsl,%B0) CR_TAB
3582 AS2 (sbc,%B0,%B0) CR_TAB
3583 AS1 (asr,%A0) CR_TAB
3584 AS1 (asr,%A0) CR_TAB
3585 AS1 (asr,%A0) CR_TAB
3586 AS1 (asr,%A0));
3588 case 13:
3589 if (AVR_ENHANCED && ldi_ok)
3591 *len = 5;
3592 return (AS2 (ldi,%A0,0x08) CR_TAB
3593 AS2 (muls,%B0,%A0) CR_TAB
3594 AS2 (mov,%A0,r1) CR_TAB
3595 AS2 (sbc,%B0,%B0) CR_TAB
3596 AS1 (clr,__zero_reg__));
3598 if (optimize_size)
3599 break; /* scratch ? 5 : 7 */
3600 *len = 8;
3601 return (AS2 (mov,%A0,%B0) CR_TAB
3602 AS1 (lsl,%B0) CR_TAB
3603 AS2 (sbc,%B0,%B0) CR_TAB
3604 AS1 (asr,%A0) CR_TAB
3605 AS1 (asr,%A0) CR_TAB
3606 AS1 (asr,%A0) CR_TAB
3607 AS1 (asr,%A0) CR_TAB
3608 AS1 (asr,%A0));
3610 case 14:
3611 *len = 5;
3612 return (AS1 (lsl,%B0) CR_TAB
3613 AS2 (sbc,%A0,%A0) CR_TAB
3614 AS1 (lsl,%B0) CR_TAB
3615 AS2 (mov,%B0,%A0) CR_TAB
3616 AS1 (rol,%A0));
3618 default:
3619 if (INTVAL (operands[2]) < 16)
3620 break;
3622 /* fall through */
3624 case 15:
3625 return *len = 3, (AS1 (lsl,%B0) CR_TAB
3626 AS2 (sbc,%A0,%A0) CR_TAB
3627 AS2 (mov,%B0,%A0));
3629 len = t;
3631 out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3632 AS1 (ror,%A0)),
3633 insn, operands, len, 2);
3634 return "";
3638 /* 32bit arithmetic shift right ((signed long)x >> i) */
3640 const char *
3641 ashrsi3_out (rtx insn, rtx operands[], int *len)
3643 if (GET_CODE (operands[2]) == CONST_INT)
3645 int k;
3646 int *t = len;
3648 if (!len)
3649 len = &k;
3651 switch (INTVAL (operands[2]))
3653 case 8:
3655 int reg0 = true_regnum (operands[0]);
3656 int reg1 = true_regnum (operands[1]);
3657 *len=6;
3658 if (reg0 <= reg1)
3659 return (AS2 (mov,%A0,%B1) CR_TAB
3660 AS2 (mov,%B0,%C1) CR_TAB
3661 AS2 (mov,%C0,%D1) CR_TAB
3662 AS1 (clr,%D0) CR_TAB
3663 AS2 (sbrc,%C0,7) CR_TAB
3664 AS1 (dec,%D0));
3665 else if (reg0 == reg1 + 1)
3667 *len = 3;
3668 return (AS1 (clr,%D0) CR_TAB
3669 AS2 (sbrc,%C0,7) CR_TAB
3670 AS1 (dec,%D0));
3672 else
3673 return (AS1 (clr,%D0) CR_TAB
3674 AS2 (sbrc,%D1,7) CR_TAB
3675 AS1 (dec,%D0) CR_TAB
3676 AS2 (mov,%C0,%D1) CR_TAB
3677 AS2 (mov,%B0,%C1) CR_TAB
3678 AS2 (mov,%A0,%B1));
3681 case 16:
3683 int reg0 = true_regnum (operands[0]);
3684 int reg1 = true_regnum (operands[1]);
3685 *len=6;
3686 if (AVR_ENHANCED && (reg0 != reg1 + 2))
3688 *len = 5;
3689 return (AS2 (movw,%A0,%C1) CR_TAB
3690 AS1 (clr,%D0) CR_TAB
3691 AS2 (sbrc,%B0,7) CR_TAB
3692 AS1 (com,%D0) CR_TAB
3693 AS2 (mov,%C0,%D0));
3695 if (reg0 <= reg1 + 1)
3696 return (AS2 (mov,%A0,%C1) CR_TAB
3697 AS2 (mov,%B0,%D1) CR_TAB
3698 AS1 (clr,%D0) CR_TAB
3699 AS2 (sbrc,%B0,7) CR_TAB
3700 AS1 (com,%D0) CR_TAB
3701 AS2 (mov,%C0,%D0));
3702 else if (reg0 == reg1 + 2)
3703 return *len = 4, (AS1 (clr,%D0) CR_TAB
3704 AS2 (sbrc,%B0,7) CR_TAB
3705 AS1 (com,%D0) CR_TAB
3706 AS2 (mov,%C0,%D0));
3707 else
3708 return (AS2 (mov,%B0,%D1) CR_TAB
3709 AS2 (mov,%A0,%C1) CR_TAB
3710 AS1 (clr,%D0) CR_TAB
3711 AS2 (sbrc,%B0,7) CR_TAB
3712 AS1 (com,%D0) CR_TAB
3713 AS2 (mov,%C0,%D0));
3716 case 24:
3717 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3718 return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3719 AS1 (clr,%D0) CR_TAB
3720 AS2 (sbrc,%A0,7) CR_TAB
3721 AS1 (com,%D0) CR_TAB
3722 AS2 (mov,%B0,%D0) CR_TAB
3723 AS2 (mov,%C0,%D0));
3724 else
3725 return *len = 5, (AS1 (clr,%D0) CR_TAB
3726 AS2 (sbrc,%A0,7) CR_TAB
3727 AS1 (com,%D0) CR_TAB
3728 AS2 (mov,%B0,%D0) CR_TAB
3729 AS2 (mov,%C0,%D0));
3731 default:
3732 if (INTVAL (operands[2]) < 32)
3733 break;
3735 /* fall through */
3737 case 31:
3738 if (AVR_ENHANCED)
3739 return *len = 4, (AS1 (lsl,%D0) CR_TAB
3740 AS2 (sbc,%A0,%A0) CR_TAB
3741 AS2 (mov,%B0,%A0) CR_TAB
3742 AS2 (movw,%C0,%A0));
3743 else
3744 return *len = 5, (AS1 (lsl,%D0) CR_TAB
3745 AS2 (sbc,%A0,%A0) CR_TAB
3746 AS2 (mov,%B0,%A0) CR_TAB
3747 AS2 (mov,%C0,%A0) CR_TAB
3748 AS2 (mov,%D0,%A0));
3750 len = t;
3752 out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
3753 AS1 (ror,%C0) CR_TAB
3754 AS1 (ror,%B0) CR_TAB
3755 AS1 (ror,%A0)),
3756 insn, operands, len, 4);
3757 return "";
3760 /* 8bit logic shift right ((unsigned char)x >> i) */
3762 const char *
3763 lshrqi3_out (rtx insn, rtx operands[], int *len)
3765 if (GET_CODE (operands[2]) == CONST_INT)
3767 int k;
3769 if (!len)
3770 len = &k;
3772 switch (INTVAL (operands[2]))
3774 default:
3775 if (INTVAL (operands[2]) < 8)
3776 break;
3778 *len = 1;
3779 return AS1 (clr,%0);
3781 case 1:
3782 *len = 1;
3783 return AS1 (lsr,%0);
3785 case 2:
3786 *len = 2;
3787 return (AS1 (lsr,%0) CR_TAB
3788 AS1 (lsr,%0));
3789 case 3:
3790 *len = 3;
3791 return (AS1 (lsr,%0) CR_TAB
3792 AS1 (lsr,%0) CR_TAB
3793 AS1 (lsr,%0));
3795 case 4:
3796 if (test_hard_reg_class (LD_REGS, operands[0]))
3798 *len=2;
3799 return (AS1 (swap,%0) CR_TAB
3800 AS2 (andi,%0,0x0f));
3802 *len = 4;
3803 return (AS1 (lsr,%0) CR_TAB
3804 AS1 (lsr,%0) CR_TAB
3805 AS1 (lsr,%0) CR_TAB
3806 AS1 (lsr,%0));
3808 case 5:
3809 if (test_hard_reg_class (LD_REGS, operands[0]))
3811 *len = 3;
3812 return (AS1 (swap,%0) CR_TAB
3813 AS1 (lsr,%0) CR_TAB
3814 AS2 (andi,%0,0x7));
3816 *len = 5;
3817 return (AS1 (lsr,%0) CR_TAB
3818 AS1 (lsr,%0) CR_TAB
3819 AS1 (lsr,%0) CR_TAB
3820 AS1 (lsr,%0) CR_TAB
3821 AS1 (lsr,%0));
3823 case 6:
3824 if (test_hard_reg_class (LD_REGS, operands[0]))
3826 *len = 4;
3827 return (AS1 (swap,%0) CR_TAB
3828 AS1 (lsr,%0) CR_TAB
3829 AS1 (lsr,%0) CR_TAB
3830 AS2 (andi,%0,0x3));
3832 *len = 6;
3833 return (AS1 (lsr,%0) CR_TAB
3834 AS1 (lsr,%0) CR_TAB
3835 AS1 (lsr,%0) CR_TAB
3836 AS1 (lsr,%0) CR_TAB
3837 AS1 (lsr,%0) CR_TAB
3838 AS1 (lsr,%0));
3840 case 7:
3841 *len = 3;
3842 return (AS1 (rol,%0) CR_TAB
3843 AS1 (clr,%0) CR_TAB
3844 AS1 (rol,%0));
3847 else if (CONSTANT_P (operands[2]))
3848 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3850 out_shift_with_cnt (AS1 (lsr,%0),
3851 insn, operands, len, 1);
3852 return "";
3855 /* 16bit logic shift right ((unsigned short)x >> i) */
3857 const char *
3858 lshrhi3_out (rtx insn, rtx operands[], int *len)
3860 if (GET_CODE (operands[2]) == CONST_INT)
3862 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3863 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3864 int k;
3865 int *t = len;
3867 if (!len)
3868 len = &k;
3870 switch (INTVAL (operands[2]))
3872 default:
3873 if (INTVAL (operands[2]) < 16)
3874 break;
3876 *len = 2;
3877 return (AS1 (clr,%B0) CR_TAB
3878 AS1 (clr,%A0));
3880 case 4:
3881 if (optimize_size && scratch)
3882 break; /* 5 */
3883 if (ldi_ok)
3885 *len = 6;
3886 return (AS1 (swap,%B0) CR_TAB
3887 AS1 (swap,%A0) CR_TAB
3888 AS2 (andi,%A0,0x0f) CR_TAB
3889 AS2 (eor,%A0,%B0) CR_TAB
3890 AS2 (andi,%B0,0x0f) CR_TAB
3891 AS2 (eor,%A0,%B0));
3893 if (scratch)
3895 *len = 7;
3896 return (AS1 (swap,%B0) CR_TAB
3897 AS1 (swap,%A0) CR_TAB
3898 AS2 (ldi,%3,0x0f) CR_TAB
3899 AS2 (and,%A0,%3) CR_TAB
3900 AS2 (eor,%A0,%B0) CR_TAB
3901 AS2 (and,%B0,%3) CR_TAB
3902 AS2 (eor,%A0,%B0));
3904 break; /* optimize_size ? 6 : 8 */
3906 case 5:
3907 if (optimize_size)
3908 break; /* scratch ? 5 : 6 */
3909 if (ldi_ok)
3911 *len = 8;
3912 return (AS1 (lsr,%B0) CR_TAB
3913 AS1 (ror,%A0) CR_TAB
3914 AS1 (swap,%B0) CR_TAB
3915 AS1 (swap,%A0) CR_TAB
3916 AS2 (andi,%A0,0x0f) CR_TAB
3917 AS2 (eor,%A0,%B0) CR_TAB
3918 AS2 (andi,%B0,0x0f) CR_TAB
3919 AS2 (eor,%A0,%B0));
3921 if (scratch)
3923 *len = 9;
3924 return (AS1 (lsr,%B0) CR_TAB
3925 AS1 (ror,%A0) CR_TAB
3926 AS1 (swap,%B0) CR_TAB
3927 AS1 (swap,%A0) CR_TAB
3928 AS2 (ldi,%3,0x0f) CR_TAB
3929 AS2 (and,%A0,%3) CR_TAB
3930 AS2 (eor,%A0,%B0) CR_TAB
3931 AS2 (and,%B0,%3) CR_TAB
3932 AS2 (eor,%A0,%B0));
3934 break; /* 10 */
3936 case 6:
3937 if (optimize_size)
3938 break; /* scratch ? 5 : 6 */
3939 *len = 9;
3940 return (AS1 (clr,__tmp_reg__) CR_TAB
3941 AS1 (lsl,%A0) CR_TAB
3942 AS1 (rol,%B0) CR_TAB
3943 AS1 (rol,__tmp_reg__) CR_TAB
3944 AS1 (lsl,%A0) CR_TAB
3945 AS1 (rol,%B0) CR_TAB
3946 AS1 (rol,__tmp_reg__) CR_TAB
3947 AS2 (mov,%A0,%B0) CR_TAB
3948 AS2 (mov,%B0,__tmp_reg__));
3950 case 7:
3951 *len = 5;
3952 return (AS1 (lsl,%A0) CR_TAB
3953 AS2 (mov,%A0,%B0) CR_TAB
3954 AS1 (rol,%A0) CR_TAB
3955 AS2 (sbc,%B0,%B0) CR_TAB
3956 AS1 (neg,%B0));
3958 case 8:
3959 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
3960 return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
3961 AS1 (clr,%B0));
3962 else
3963 return *len = 1, AS1 (clr,%B0);
3965 case 9:
3966 *len = 3;
3967 return (AS2 (mov,%A0,%B0) CR_TAB
3968 AS1 (clr,%B0) CR_TAB
3969 AS1 (lsr,%A0));
3971 case 10:
3972 *len = 4;
3973 return (AS2 (mov,%A0,%B0) CR_TAB
3974 AS1 (clr,%B0) CR_TAB
3975 AS1 (lsr,%A0) CR_TAB
3976 AS1 (lsr,%A0));
3978 case 11:
3979 *len = 5;
3980 return (AS2 (mov,%A0,%B0) CR_TAB
3981 AS1 (clr,%B0) CR_TAB
3982 AS1 (lsr,%A0) CR_TAB
3983 AS1 (lsr,%A0) CR_TAB
3984 AS1 (lsr,%A0));
3986 case 12:
3987 if (ldi_ok)
3989 *len = 4;
3990 return (AS2 (mov,%A0,%B0) CR_TAB
3991 AS1 (clr,%B0) CR_TAB
3992 AS1 (swap,%A0) CR_TAB
3993 AS2 (andi,%A0,0x0f));
3995 if (scratch)
3997 *len = 5;
3998 return (AS2 (mov,%A0,%B0) CR_TAB
3999 AS1 (clr,%B0) CR_TAB
4000 AS1 (swap,%A0) CR_TAB
4001 AS2 (ldi,%3,0x0f) CR_TAB
4002 AS2 (and,%A0,%3));
4004 *len = 6;
4005 return (AS2 (mov,%A0,%B0) CR_TAB
4006 AS1 (clr,%B0) CR_TAB
4007 AS1 (lsr,%A0) CR_TAB
4008 AS1 (lsr,%A0) CR_TAB
4009 AS1 (lsr,%A0) CR_TAB
4010 AS1 (lsr,%A0));
4012 case 13:
4013 if (ldi_ok)
4015 *len = 5;
4016 return (AS2 (mov,%A0,%B0) CR_TAB
4017 AS1 (clr,%B0) CR_TAB
4018 AS1 (swap,%A0) CR_TAB
4019 AS1 (lsr,%A0) CR_TAB
4020 AS2 (andi,%A0,0x07));
4022 if (AVR_ENHANCED && scratch)
4024 *len = 5;
4025 return (AS2 (ldi,%3,0x08) CR_TAB
4026 AS2 (mul,%B0,%3) CR_TAB
4027 AS2 (mov,%A0,r1) CR_TAB
4028 AS1 (clr,%B0) CR_TAB
4029 AS1 (clr,__zero_reg__));
4031 if (optimize_size && scratch)
4032 break; /* 5 */
4033 if (scratch)
4035 *len = 6;
4036 return (AS2 (mov,%A0,%B0) CR_TAB
4037 AS1 (clr,%B0) CR_TAB
4038 AS1 (swap,%A0) CR_TAB
4039 AS1 (lsr,%A0) CR_TAB
4040 AS2 (ldi,%3,0x07) CR_TAB
4041 AS2 (and,%A0,%3));
4043 if (AVR_ENHANCED)
4045 *len = 6;
4046 return ("set" CR_TAB
4047 AS2 (bld,r1,3) CR_TAB
4048 AS2 (mul,%B0,r1) CR_TAB
4049 AS2 (mov,%A0,r1) CR_TAB
4050 AS1 (clr,%B0) CR_TAB
4051 AS1 (clr,__zero_reg__));
4053 *len = 7;
4054 return (AS2 (mov,%A0,%B0) CR_TAB
4055 AS1 (clr,%B0) CR_TAB
4056 AS1 (lsr,%A0) CR_TAB
4057 AS1 (lsr,%A0) CR_TAB
4058 AS1 (lsr,%A0) CR_TAB
4059 AS1 (lsr,%A0) CR_TAB
4060 AS1 (lsr,%A0));
4062 case 14:
4063 if (AVR_ENHANCED && ldi_ok)
4065 *len = 5;
4066 return (AS2 (ldi,%A0,0x04) CR_TAB
4067 AS2 (mul,%B0,%A0) CR_TAB
4068 AS2 (mov,%A0,r1) CR_TAB
4069 AS1 (clr,%B0) CR_TAB
4070 AS1 (clr,__zero_reg__));
4072 if (AVR_ENHANCED && scratch)
4074 *len = 5;
4075 return (AS2 (ldi,%3,0x04) CR_TAB
4076 AS2 (mul,%B0,%3) CR_TAB
4077 AS2 (mov,%A0,r1) CR_TAB
4078 AS1 (clr,%B0) CR_TAB
4079 AS1 (clr,__zero_reg__));
4081 if (optimize_size && ldi_ok)
4083 *len = 5;
4084 return (AS2 (mov,%A0,%B0) CR_TAB
4085 AS2 (ldi,%B0,6) "\n1:\t"
4086 AS1 (lsr,%A0) CR_TAB
4087 AS1 (dec,%B0) CR_TAB
4088 AS1 (brne,1b));
4090 if (optimize_size && scratch)
4091 break; /* 5 */
4092 *len = 6;
4093 return (AS1 (clr,%A0) CR_TAB
4094 AS1 (lsl,%B0) CR_TAB
4095 AS1 (rol,%A0) CR_TAB
4096 AS1 (lsl,%B0) CR_TAB
4097 AS1 (rol,%A0) CR_TAB
4098 AS1 (clr,%B0));
4100 case 15:
4101 *len = 4;
4102 return (AS1 (clr,%A0) CR_TAB
4103 AS1 (lsl,%B0) CR_TAB
4104 AS1 (rol,%A0) CR_TAB
4105 AS1 (clr,%B0));
4107 len = t;
4109 out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
4110 AS1 (ror,%A0)),
4111 insn, operands, len, 2);
4112 return "";
4115 /* 32bit logic shift right ((unsigned int)x >> i) */
4117 const char *
4118 lshrsi3_out (rtx insn, rtx operands[], int *len)
4120 if (GET_CODE (operands[2]) == CONST_INT)
4122 int k;
4123 int *t = len;
4125 if (!len)
4126 len = &k;
4128 switch (INTVAL (operands[2]))
4130 default:
4131 if (INTVAL (operands[2]) < 32)
4132 break;
4134 if (AVR_ENHANCED)
4135 return *len = 3, (AS1 (clr,%D0) CR_TAB
4136 AS1 (clr,%C0) CR_TAB
4137 AS2 (movw,%A0,%C0));
4138 *len = 4;
4139 return (AS1 (clr,%D0) CR_TAB
4140 AS1 (clr,%C0) CR_TAB
4141 AS1 (clr,%B0) CR_TAB
4142 AS1 (clr,%A0));
4144 case 8:
4146 int reg0 = true_regnum (operands[0]);
4147 int reg1 = true_regnum (operands[1]);
4148 *len = 4;
4149 if (reg0 <= reg1)
4150 return (AS2 (mov,%A0,%B1) CR_TAB
4151 AS2 (mov,%B0,%C1) CR_TAB
4152 AS2 (mov,%C0,%D1) CR_TAB
4153 AS1 (clr,%D0));
4154 else if (reg0 == reg1 + 1)
4155 return *len = 1, AS1 (clr,%D0);
4156 else
4157 return (AS1 (clr,%D0) CR_TAB
4158 AS2 (mov,%C0,%D1) CR_TAB
4159 AS2 (mov,%B0,%C1) CR_TAB
4160 AS2 (mov,%A0,%B1));
4163 case 16:
4165 int reg0 = true_regnum (operands[0]);
4166 int reg1 = true_regnum (operands[1]);
4167 *len = 4;
4168 if (AVR_ENHANCED && (reg0 != reg1 + 2))
4170 *len = 3;
4171 return (AS2 (movw,%A0,%C1) CR_TAB
4172 AS1 (clr,%C0) CR_TAB
4173 AS1 (clr,%D0));
4175 if (reg0 <= reg1 + 1)
4176 return (AS2 (mov,%A0,%C1) CR_TAB
4177 AS2 (mov,%B0,%D1) CR_TAB
4178 AS1 (clr,%C0) CR_TAB
4179 AS1 (clr,%D0));
4180 else if (reg0 == reg1 + 2)
4181 return *len = 2, (AS1 (clr,%C0) CR_TAB
4182 AS1 (clr,%D0));
4183 else
4184 return (AS2 (mov,%B0,%D1) CR_TAB
4185 AS2 (mov,%A0,%C1) CR_TAB
4186 AS1 (clr,%C0) CR_TAB
4187 AS1 (clr,%D0));
4190 case 24:
4191 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
4192 return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4193 AS1 (clr,%B0) CR_TAB
4194 AS1 (clr,%C0) CR_TAB
4195 AS1 (clr,%D0));
4196 else
4197 return *len = 3, (AS1 (clr,%B0) CR_TAB
4198 AS1 (clr,%C0) CR_TAB
4199 AS1 (clr,%D0));
4201 case 31:
4202 *len = 6;
4203 return (AS1 (clr,%A0) CR_TAB
4204 AS2 (sbrc,%D0,7) CR_TAB
4205 AS1 (inc,%A0) CR_TAB
4206 AS1 (clr,%B0) CR_TAB
4207 AS1 (clr,%C0) CR_TAB
4208 AS1 (clr,%D0));
4210 len = t;
4212 out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4213 AS1 (ror,%C0) CR_TAB
4214 AS1 (ror,%B0) CR_TAB
4215 AS1 (ror,%A0)),
4216 insn, operands, len, 4);
4217 return "";
4220 /* Modifies the length assigned to instruction INSN
4221 LEN is the initially computed length of the insn. */
4224 adjust_insn_length (rtx insn, int len)
4226 rtx patt = PATTERN (insn);
4227 rtx set;
4229 if (GET_CODE (patt) == SET)
4231 rtx op[10];
4232 op[1] = SET_SRC (patt);
4233 op[0] = SET_DEST (patt);
4234 if (general_operand (op[1], VOIDmode)
4235 && general_operand (op[0], VOIDmode))
4237 switch (GET_MODE (op[0]))
4239 case QImode:
4240 output_movqi (insn, op, &len);
4241 break;
4242 case HImode:
4243 output_movhi (insn, op, &len);
4244 break;
4245 case SImode:
4246 case SFmode:
4247 output_movsisf (insn, op, &len);
4248 break;
4249 default:
4250 break;
4253 else if (op[0] == cc0_rtx && REG_P (op[1]))
4255 switch (GET_MODE (op[1]))
4257 case HImode: out_tsthi (insn,&len); break;
4258 case SImode: out_tstsi (insn,&len); break;
4259 default: break;
4262 else if (GET_CODE (op[1]) == AND)
4264 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4266 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4267 if (GET_MODE (op[1]) == SImode)
4268 len = (((mask & 0xff) != 0xff)
4269 + ((mask & 0xff00) != 0xff00)
4270 + ((mask & 0xff0000L) != 0xff0000L)
4271 + ((mask & 0xff000000L) != 0xff000000L));
4272 else if (GET_MODE (op[1]) == HImode)
4273 len = (((mask & 0xff) != 0xff)
4274 + ((mask & 0xff00) != 0xff00));
4277 else if (GET_CODE (op[1]) == IOR)
4279 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4281 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4282 if (GET_MODE (op[1]) == SImode)
4283 len = (((mask & 0xff) != 0)
4284 + ((mask & 0xff00) != 0)
4285 + ((mask & 0xff0000L) != 0)
4286 + ((mask & 0xff000000L) != 0));
4287 else if (GET_MODE (op[1]) == HImode)
4288 len = (((mask & 0xff) != 0)
4289 + ((mask & 0xff00) != 0));
4293 set = single_set (insn);
4294 if (set)
4296 rtx op[10];
4298 op[1] = SET_SRC (set);
4299 op[0] = SET_DEST (set);
4301 if (GET_CODE (patt) == PARALLEL
4302 && general_operand (op[1], VOIDmode)
4303 && general_operand (op[0], VOIDmode))
4305 if (XVECLEN (patt, 0) == 2)
4306 op[2] = XVECEXP (patt, 0, 1);
4308 switch (GET_MODE (op[0]))
4310 case QImode:
4311 len = 2;
4312 break;
4313 case HImode:
4314 output_reload_inhi (insn, op, &len);
4315 break;
4316 case SImode:
4317 case SFmode:
4318 output_reload_insisf (insn, op, &len);
4319 break;
4320 default:
4321 break;
4324 else if (GET_CODE (op[1]) == ASHIFT
4325 || GET_CODE (op[1]) == ASHIFTRT
4326 || GET_CODE (op[1]) == LSHIFTRT)
4328 rtx ops[10];
4329 ops[0] = op[0];
4330 ops[1] = XEXP (op[1],0);
4331 ops[2] = XEXP (op[1],1);
4332 switch (GET_CODE (op[1]))
4334 case ASHIFT:
4335 switch (GET_MODE (op[0]))
4337 case QImode: ashlqi3_out (insn,ops,&len); break;
4338 case HImode: ashlhi3_out (insn,ops,&len); break;
4339 case SImode: ashlsi3_out (insn,ops,&len); break;
4340 default: break;
4342 break;
4343 case ASHIFTRT:
4344 switch (GET_MODE (op[0]))
4346 case QImode: ashrqi3_out (insn,ops,&len); break;
4347 case HImode: ashrhi3_out (insn,ops,&len); break;
4348 case SImode: ashrsi3_out (insn,ops,&len); break;
4349 default: break;
4351 break;
4352 case LSHIFTRT:
4353 switch (GET_MODE (op[0]))
4355 case QImode: lshrqi3_out (insn,ops,&len); break;
4356 case HImode: lshrhi3_out (insn,ops,&len); break;
4357 case SImode: lshrsi3_out (insn,ops,&len); break;
4358 default: break;
4360 break;
4361 default:
4362 break;
4366 return len;
4369 /* Return nonzero if register REG dead after INSN. */
4372 reg_unused_after (rtx insn, rtx reg)
4374 return (dead_or_set_p (insn, reg)
4375 || (REG_P(reg) && _reg_unused_after (insn, reg)));
4378 /* Return nonzero if REG is not used after INSN.
4379 We assume REG is a reload reg, and therefore does
4380 not live past labels. It may live past calls or jumps though. */
4383 _reg_unused_after (rtx insn, rtx reg)
4385 enum rtx_code code;
4386 rtx set;
4388 /* If the reg is set by this instruction, then it is safe for our
4389 case. Disregard the case where this is a store to memory, since
4390 we are checking a register used in the store address. */
4391 set = single_set (insn);
4392 if (set && GET_CODE (SET_DEST (set)) != MEM
4393 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4394 return 1;
4396 while ((insn = NEXT_INSN (insn)))
4398 rtx set;
4399 code = GET_CODE (insn);
4401 #if 0
4402 /* If this is a label that existed before reload, then the register
4403 if dead here. However, if this is a label added by reorg, then
4404 the register may still be live here. We can't tell the difference,
4405 so we just ignore labels completely. */
4406 if (code == CODE_LABEL)
4407 return 1;
4408 /* else */
4409 #endif
4411 if (!INSN_P (insn))
4412 continue;
4414 if (code == JUMP_INSN)
4415 return 0;
4417 /* If this is a sequence, we must handle them all at once.
4418 We could have for instance a call that sets the target register,
4419 and an insn in a delay slot that uses the register. In this case,
4420 we must return 0. */
4421 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
4423 int i;
4424 int retval = 0;
4426 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
4428 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
4429 rtx set = single_set (this_insn);
4431 if (GET_CODE (this_insn) == CALL_INSN)
4432 code = CALL_INSN;
4433 else if (GET_CODE (this_insn) == JUMP_INSN)
4435 if (INSN_ANNULLED_BRANCH_P (this_insn))
4436 return 0;
4437 code = JUMP_INSN;
4440 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4441 return 0;
4442 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4444 if (GET_CODE (SET_DEST (set)) != MEM)
4445 retval = 1;
4446 else
4447 return 0;
4449 if (set == 0
4450 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
4451 return 0;
4453 if (retval == 1)
4454 return 1;
4455 else if (code == JUMP_INSN)
4456 return 0;
4459 if (code == CALL_INSN)
4461 rtx tem;
4462 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4463 if (GET_CODE (XEXP (tem, 0)) == USE
4464 && REG_P (XEXP (XEXP (tem, 0), 0))
4465 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
4466 return 0;
4467 if (call_used_regs[REGNO (reg)])
4468 return 1;
4471 set = single_set (insn);
4473 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4474 return 0;
4475 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4476 return GET_CODE (SET_DEST (set)) != MEM;
4477 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
4478 return 0;
4480 return 1;
4483 /* Target hook for assembling integer objects. The AVR version needs
4484 special handling for references to certain labels. */
4486 static bool
4487 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
4489 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
4490 && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x))
4491 || GET_CODE (x) == LABEL_REF))
4493 fputs ("\t.word\tpm(", asm_out_file);
4494 output_addr_const (asm_out_file, x);
4495 fputs (")\n", asm_out_file);
4496 return true;
4498 return default_assemble_integer (x, size, aligned_p);
4501 /* The routine used to output NUL terminated strings. We use a special
4502 version of this for most svr4 targets because doing so makes the
4503 generated assembly code more compact (and thus faster to assemble)
4504 as well as more readable, especially for targets like the i386
4505 (where the only alternative is to output character sequences as
4506 comma separated lists of numbers). */
4508 void
4509 gas_output_limited_string(FILE *file, const char *str)
4511 const unsigned char *_limited_str = (unsigned char *) str;
4512 unsigned ch;
4513 fprintf (file, "%s\"", STRING_ASM_OP);
4514 for (; (ch = *_limited_str); _limited_str++)
4516 int escape;
4517 switch (escape = ESCAPES[ch])
4519 case 0:
4520 putc (ch, file);
4521 break;
4522 case 1:
4523 fprintf (file, "\\%03o", ch);
4524 break;
4525 default:
4526 putc ('\\', file);
4527 putc (escape, file);
4528 break;
4531 fprintf (file, "\"\n");
4534 /* The routine used to output sequences of byte values. We use a special
4535 version of this for most svr4 targets because doing so makes the
4536 generated assembly code more compact (and thus faster to assemble)
4537 as well as more readable. Note that if we find subparts of the
4538 character sequence which end with NUL (and which are shorter than
4539 STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
4541 void
4542 gas_output_ascii(FILE *file, const char *str, size_t length)
4544 const unsigned char *_ascii_bytes = (const unsigned char *) str;
4545 const unsigned char *limit = _ascii_bytes + length;
4546 unsigned bytes_in_chunk = 0;
4547 for (; _ascii_bytes < limit; _ascii_bytes++)
4549 const unsigned char *p;
4550 if (bytes_in_chunk >= 60)
4552 fprintf (file, "\"\n");
4553 bytes_in_chunk = 0;
4555 for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
4556 continue;
4557 if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
4559 if (bytes_in_chunk > 0)
4561 fprintf (file, "\"\n");
4562 bytes_in_chunk = 0;
4564 gas_output_limited_string (file, (char*)_ascii_bytes);
4565 _ascii_bytes = p;
4567 else
4569 int escape;
4570 unsigned ch;
4571 if (bytes_in_chunk == 0)
4572 fprintf (file, "\t.ascii\t\"");
4573 switch (escape = ESCAPES[ch = *_ascii_bytes])
4575 case 0:
4576 putc (ch, file);
4577 bytes_in_chunk++;
4578 break;
4579 case 1:
4580 fprintf (file, "\\%03o", ch);
4581 bytes_in_chunk += 4;
4582 break;
4583 default:
4584 putc ('\\', file);
4585 putc (escape, file);
4586 bytes_in_chunk += 2;
4587 break;
4591 if (bytes_in_chunk > 0)
4592 fprintf (file, "\"\n");
4595 /* Return value is nonzero if pseudos that have been
4596 assigned to registers of class CLASS would likely be spilled
4597 because registers of CLASS are needed for spill registers. */
4599 enum reg_class
4600 class_likely_spilled_p (int c)
4602 return (c != ALL_REGS && c != ADDW_REGS);
4605 /* Valid attributes:
4606 progmem - put data to program memory;
4607 signal - make a function to be hardware interrupt. After function
4608 prologue interrupts are disabled;
4609 interrupt - make a function to be hardware interrupt. After function
4610 prologue interrupts are enabled;
4611 naked - don't generate function prologue/epilogue and `ret' command.
4613 Only `progmem' attribute valid for type. */
4615 const struct attribute_spec avr_attribute_table[] =
4617 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
4618 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute },
4619 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4620 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4621 { "naked", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4622 { NULL, 0, 0, false, false, false, NULL }
4625 /* Handle a "progmem" attribute; arguments as in
4626 struct attribute_spec.handler. */
4627 static tree
4628 avr_handle_progmem_attribute (tree *node, tree name,
4629 tree args ATTRIBUTE_UNUSED,
4630 int flags ATTRIBUTE_UNUSED,
4631 bool *no_add_attrs)
4633 if (DECL_P (*node))
4635 if (TREE_CODE (*node) == TYPE_DECL)
4637 /* This is really a decl attribute, not a type attribute,
4638 but try to handle it for GCC 3.0 backwards compatibility. */
4640 tree type = TREE_TYPE (*node);
4641 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
4642 tree newtype = build_type_attribute_variant (type, attr);
4644 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
4645 TREE_TYPE (*node) = newtype;
4646 *no_add_attrs = true;
4648 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
4650 if (DECL_INITIAL (*node) == NULL_TREE && !DECL_EXTERNAL (*node))
4652 warning (0, "only initialized variables can be placed into "
4653 "program memory area");
4654 *no_add_attrs = true;
4657 else
4659 warning (OPT_Wattributes, "%qs attribute ignored",
4660 IDENTIFIER_POINTER (name));
4661 *no_add_attrs = true;
4665 return NULL_TREE;
4668 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
4669 struct attribute_spec.handler. */
4671 static tree
4672 avr_handle_fndecl_attribute (tree *node, tree name,
4673 tree args ATTRIBUTE_UNUSED,
4674 int flags ATTRIBUTE_UNUSED,
4675 bool *no_add_attrs)
4677 if (TREE_CODE (*node) != FUNCTION_DECL)
4679 warning (OPT_Wattributes, "%qs attribute only applies to functions",
4680 IDENTIFIER_POINTER (name));
4681 *no_add_attrs = true;
4683 else
4685 const char *func_name = IDENTIFIER_POINTER (DECL_NAME (*node));
4686 const char *attr = IDENTIFIER_POINTER (name);
4688 /* If the function has the 'signal' or 'interrupt' attribute, test to
4689 make sure that the name of the function is "__vector_NN" so as to
4690 catch when the user misspells the interrupt vector name. */
4692 if (strncmp (attr, "interrupt", strlen ("interrupt")) == 0)
4694 if (strncmp (func_name, "__vector", strlen ("__vector")) != 0)
4696 warning (0, "%qs appears to be a misspelled interrupt handler",
4697 func_name);
4700 else if (strncmp (attr, "signal", strlen ("signal")) == 0)
4702 if (strncmp (func_name, "__vector", strlen ("__vector")) != 0)
4704 warning (0, "%qs appears to be a misspelled signal handler",
4705 func_name);
4710 return NULL_TREE;
4713 /* Look for attribute `progmem' in DECL
4714 if found return 1, otherwise 0. */
4717 avr_progmem_p (tree decl, tree attributes)
4719 tree a;
4721 if (TREE_CODE (decl) != VAR_DECL)
4722 return 0;
4724 if (NULL_TREE
4725 != lookup_attribute ("progmem", attributes))
4726 return 1;
4728 a=decl;
4730 a = TREE_TYPE(a);
4731 while (TREE_CODE (a) == ARRAY_TYPE);
4733 if (a == error_mark_node)
4734 return 0;
4736 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
4737 return 1;
4739 return 0;
4742 /* Add the section attribute if the variable is in progmem. */
4744 static void
4745 avr_insert_attributes (tree node, tree *attributes)
4747 if (TREE_CODE (node) == VAR_DECL
4748 && (TREE_STATIC (node) || DECL_EXTERNAL (node))
4749 && avr_progmem_p (node, *attributes))
4751 static const char dsec[] = ".progmem.data";
4752 *attributes = tree_cons (get_identifier ("section"),
4753 build_tree_list (NULL, build_string (strlen (dsec), dsec)),
4754 *attributes);
4756 /* ??? This seems sketchy. Why can't the user declare the
4757 thing const in the first place? */
4758 TREE_READONLY (node) = 1;
4762 /* A get_unnamed_section callback for switching to progmem_section. */
4764 static void
4765 avr_output_progmem_section_asm_op (const void *arg ATTRIBUTE_UNUSED)
4767 fprintf (asm_out_file,
4768 "\t.section .progmem.gcc_sw_table, \"%s\", @progbits\n",
4769 AVR_MEGA ? "a" : "ax");
4770 /* Should already be aligned, this is just to be safe if it isn't. */
4771 fprintf (asm_out_file, "\t.p2align 1\n");
4774 /* Implement TARGET_ASM_INIT_SECTIONS. */
4776 static void
4777 avr_asm_init_sections (void)
4779 progmem_section = get_unnamed_section (AVR_MEGA ? 0 : SECTION_CODE,
4780 avr_output_progmem_section_asm_op,
4781 NULL);
4782 readonly_data_section = data_section;
4785 static unsigned int
4786 avr_section_type_flags (tree decl, const char *name, int reloc)
4788 unsigned int flags = default_section_type_flags (decl, name, reloc);
4790 if (strncmp (name, ".noinit", 7) == 0)
4792 if (decl && TREE_CODE (decl) == VAR_DECL
4793 && DECL_INITIAL (decl) == NULL_TREE)
4794 flags |= SECTION_BSS; /* @nobits */
4795 else
4796 warning (0, "only uninitialized variables can be placed in the "
4797 ".noinit section");
4800 return flags;
4803 /* Outputs some appropriate text to go at the start of an assembler
4804 file. */
4806 static void
4807 avr_file_start (void)
4809 if (avr_asm_only_p)
4810 error ("MCU %qs supported for assembler only", avr_mcu_name);
4812 default_file_start ();
4814 fprintf (asm_out_file, "\t.arch %s\n", avr_mcu_name);
4815 fputs ("__SREG__ = 0x3f\n"
4816 "__SP_H__ = 0x3e\n"
4817 "__SP_L__ = 0x3d\n", asm_out_file);
4819 fputs ("__tmp_reg__ = 0\n"
4820 "__zero_reg__ = 1\n", asm_out_file);
4822 /* FIXME: output these only if there is anything in the .data / .bss
4823 sections - some code size could be saved by not linking in the
4824 initialization code from libgcc if one or both sections are empty. */
4825 fputs ("\t.global __do_copy_data\n", asm_out_file);
4826 fputs ("\t.global __do_clear_bss\n", asm_out_file);
4828 commands_in_file = 0;
4829 commands_in_prologues = 0;
4830 commands_in_epilogues = 0;
4833 /* Outputs to the stdio stream FILE some
4834 appropriate text to go at the end of an assembler file. */
4836 static void
4837 avr_file_end (void)
4839 fputs ("/* File ", asm_out_file);
4840 output_quoted_string (asm_out_file, main_input_filename);
4841 fprintf (asm_out_file,
4842 ": code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
4843 commands_in_file,
4844 commands_in_file,
4845 commands_in_file - commands_in_prologues - commands_in_epilogues,
4846 commands_in_prologues, commands_in_epilogues);
4849 /* Choose the order in which to allocate hard registers for
4850 pseudo-registers local to a basic block.
4852 Store the desired register order in the array `reg_alloc_order'.
4853 Element 0 should be the register to allocate first; element 1, the
4854 next register; and so on. */
4856 void
4857 order_regs_for_local_alloc (void)
4859 unsigned int i;
4860 static const int order_0[] = {
4861 24,25,
4862 18,19,
4863 20,21,
4864 22,23,
4865 30,31,
4866 26,27,
4867 28,29,
4868 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4869 0,1,
4870 32,33,34,35
4872 static const int order_1[] = {
4873 18,19,
4874 20,21,
4875 22,23,
4876 24,25,
4877 30,31,
4878 26,27,
4879 28,29,
4880 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4881 0,1,
4882 32,33,34,35
4884 static const int order_2[] = {
4885 25,24,
4886 23,22,
4887 21,20,
4888 19,18,
4889 30,31,
4890 26,27,
4891 28,29,
4892 17,16,
4893 15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4894 1,0,
4895 32,33,34,35
4898 const int *order = (TARGET_ORDER_1 ? order_1 :
4899 TARGET_ORDER_2 ? order_2 :
4900 order_0);
4901 for (i=0; i < ARRAY_SIZE (order_0); ++i)
4902 reg_alloc_order[i] = order[i];
4906 /* Mutually recursive subroutine of avr_rtx_cost for calculating the
4907 cost of an RTX operand given its context. X is the rtx of the
4908 operand, MODE is its mode, and OUTER is the rtx_code of this
4909 operand's parent operator. */
4911 static int
4912 avr_operand_rtx_cost (rtx x, enum machine_mode mode, enum rtx_code outer)
4914 enum rtx_code code = GET_CODE (x);
4915 int total;
4917 switch (code)
4919 case REG:
4920 case SUBREG:
4921 return 0;
4923 case CONST_INT:
4924 case CONST_DOUBLE:
4925 return COSTS_N_INSNS (GET_MODE_SIZE (mode));
4927 default:
4928 break;
4931 total = 0;
4932 avr_rtx_costs (x, code, outer, &total);
4933 return total;
4936 /* The AVR backend's rtx_cost function. X is rtx expression whose cost
4937 is to be calculated. Return true if the complete cost has been
4938 computed, and false if subexpressions should be scanned. In either
4939 case, *TOTAL contains the cost result. */
4941 static bool
4942 avr_rtx_costs (rtx x, int code, int outer_code, int *total)
4944 enum machine_mode mode = GET_MODE (x);
4945 HOST_WIDE_INT val;
4947 switch (code)
4949 case CONST_INT:
4950 case CONST_DOUBLE:
4951 /* Immediate constants are as cheap as registers. */
4952 *total = 0;
4953 return true;
4955 case MEM:
4956 case CONST:
4957 case LABEL_REF:
4958 case SYMBOL_REF:
4959 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
4960 return true;
4962 case NEG:
4963 switch (mode)
4965 case QImode:
4966 case SFmode:
4967 *total = COSTS_N_INSNS (1);
4968 break;
4970 case HImode:
4971 *total = COSTS_N_INSNS (3);
4972 break;
4974 case SImode:
4975 *total = COSTS_N_INSNS (7);
4976 break;
4978 default:
4979 return false;
4981 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
4982 return true;
4984 case ABS:
4985 switch (mode)
4987 case QImode:
4988 case SFmode:
4989 *total = COSTS_N_INSNS (1);
4990 break;
4992 default:
4993 return false;
4995 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
4996 return true;
4998 case NOT:
4999 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5000 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5001 return true;
5003 case ZERO_EXTEND:
5004 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
5005 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
5006 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5007 return true;
5009 case SIGN_EXTEND:
5010 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
5011 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
5012 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5013 return true;
5015 case PLUS:
5016 switch (mode)
5018 case QImode:
5019 *total = COSTS_N_INSNS (1);
5020 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5021 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5022 break;
5024 case HImode:
5025 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5027 *total = COSTS_N_INSNS (2);
5028 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5030 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
5031 *total = COSTS_N_INSNS (1);
5032 else
5033 *total = COSTS_N_INSNS (2);
5034 break;
5036 case SImode:
5037 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5039 *total = COSTS_N_INSNS (4);
5040 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5042 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
5043 *total = COSTS_N_INSNS (1);
5044 else
5045 *total = COSTS_N_INSNS (4);
5046 break;
5048 default:
5049 return false;
5051 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5052 return true;
5054 case MINUS:
5055 case AND:
5056 case IOR:
5057 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5058 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5059 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5060 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5061 return true;
5063 case XOR:
5064 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5065 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5066 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5067 return true;
5069 case MULT:
5070 switch (mode)
5072 case QImode:
5073 if (AVR_ENHANCED)
5074 *total = COSTS_N_INSNS (optimize_size ? 3 : 4);
5075 else if (optimize_size)
5076 *total = COSTS_N_INSNS (AVR_MEGA ? 2 : 1);
5077 else
5078 return false;
5080 case HImode:
5081 if (AVR_ENHANCED)
5082 *total = COSTS_N_INSNS (optimize_size ? 7 : 10);
5083 else if (optimize_size)
5084 *total = COSTS_N_INSNS (AVR_MEGA ? 2 : 1);
5085 else
5086 return false;
5088 default:
5089 return false;
5091 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5092 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5093 return true;
5095 case DIV:
5096 case MOD:
5097 case UDIV:
5098 case UMOD:
5099 if (optimize_size)
5100 *total = COSTS_N_INSNS (AVR_MEGA ? 2 : 1);
5101 else
5102 return false;
5103 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5104 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5105 return true;
5107 case ASHIFT:
5108 switch (mode)
5110 case QImode:
5111 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5113 *total = COSTS_N_INSNS (optimize_size ? 4 : 17);
5114 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5116 else
5118 val = INTVAL (XEXP (x, 1));
5119 if (val == 7)
5120 *total = COSTS_N_INSNS (3);
5121 else if (val >= 0 && val <= 7)
5122 *total = COSTS_N_INSNS (val);
5123 else
5124 *total = COSTS_N_INSNS (1);
5126 break;
5128 case HImode:
5129 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5131 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5132 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5134 else
5135 switch (INTVAL (XEXP (x, 1)))
5137 case 0:
5138 *total = 0;
5139 break;
5140 case 1:
5141 case 8:
5142 *total = COSTS_N_INSNS (2);
5143 break;
5144 case 9:
5145 *total = COSTS_N_INSNS (3);
5146 break;
5147 case 2:
5148 case 3:
5149 case 10:
5150 case 15:
5151 *total = COSTS_N_INSNS (4);
5152 break;
5153 case 7:
5154 case 11:
5155 case 12:
5156 *total = COSTS_N_INSNS (5);
5157 break;
5158 case 4:
5159 *total = COSTS_N_INSNS (optimize_size ? 5 : 8);
5160 break;
5161 case 6:
5162 *total = COSTS_N_INSNS (optimize_size ? 5 : 9);
5163 break;
5164 case 5:
5165 *total = COSTS_N_INSNS (optimize_size ? 5 : 10);
5166 break;
5167 default:
5168 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5169 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5171 break;
5173 case SImode:
5174 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5176 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5177 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5179 else
5180 switch (INTVAL (XEXP (x, 1)))
5182 case 0:
5183 *total = 0;
5184 break;
5185 case 24:
5186 *total = COSTS_N_INSNS (3);
5187 break;
5188 case 1:
5189 case 8:
5190 case 16:
5191 *total = COSTS_N_INSNS (4);
5192 break;
5193 case 31:
5194 *total = COSTS_N_INSNS (6);
5195 break;
5196 case 2:
5197 *total = COSTS_N_INSNS (optimize_size ? 7 : 8);
5198 break;
5199 default:
5200 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5201 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5203 break;
5205 default:
5206 return false;
5208 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5209 return true;
5211 case ASHIFTRT:
5212 switch (mode)
5214 case QImode:
5215 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5217 *total = COSTS_N_INSNS (optimize_size ? 4 : 17);
5218 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5220 else
5222 val = INTVAL (XEXP (x, 1));
5223 if (val == 6)
5224 *total = COSTS_N_INSNS (4);
5225 else if (val == 7)
5226 *total = COSTS_N_INSNS (2);
5227 else if (val >= 0 && val <= 7)
5228 *total = COSTS_N_INSNS (val);
5229 else
5230 *total = COSTS_N_INSNS (1);
5232 break;
5234 case HImode:
5235 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5237 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5238 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5240 else
5241 switch (INTVAL (XEXP (x, 1)))
5243 case 0:
5244 *total = 0;
5245 break;
5246 case 1:
5247 *total = COSTS_N_INSNS (2);
5248 break;
5249 case 15:
5250 *total = COSTS_N_INSNS (3);
5251 break;
5252 case 2:
5253 case 7:
5254 case 8:
5255 case 9:
5256 *total = COSTS_N_INSNS (4);
5257 break;
5258 case 10:
5259 case 14:
5260 *total = COSTS_N_INSNS (5);
5261 break;
5262 case 11:
5263 *total = COSTS_N_INSNS (optimize_size ? 5 : 6);
5264 break;
5265 case 12:
5266 *total = COSTS_N_INSNS (optimize_size ? 5 : 7);
5267 break;
5268 case 6:
5269 case 13:
5270 *total = COSTS_N_INSNS (optimize_size ? 5 : 8);
5271 break;
5272 default:
5273 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5274 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5276 break;
5278 case SImode:
5279 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5281 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5282 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5284 else
5285 switch (INTVAL (XEXP (x, 1)))
5287 case 0:
5288 *total = 0;
5289 break;
5290 case 1:
5291 *total = COSTS_N_INSNS (4);
5292 break;
5293 case 8:
5294 case 16:
5295 case 24:
5296 *total = COSTS_N_INSNS (6);
5297 break;
5298 case 2:
5299 *total = COSTS_N_INSNS (optimize_size ? 7 : 8);
5300 break;
5301 case 31:
5302 *total = COSTS_N_INSNS (AVR_ENHANCED ? 4 : 5);
5303 break;
5304 default:
5305 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5306 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5308 break;
5310 default:
5311 return false;
5313 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5314 return true;
5316 case LSHIFTRT:
5317 switch (mode)
5319 case QImode:
5320 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5322 *total = COSTS_N_INSNS (optimize_size ? 4 : 17);
5323 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5325 else
5327 val = INTVAL (XEXP (x, 1));
5328 if (val == 7)
5329 *total = COSTS_N_INSNS (3);
5330 else if (val >= 0 && val <= 7)
5331 *total = COSTS_N_INSNS (val);
5332 else
5333 *total = COSTS_N_INSNS (1);
5335 break;
5337 case HImode:
5338 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5340 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5341 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5343 else
5344 switch (INTVAL (XEXP (x, 1)))
5346 case 0:
5347 *total = 0;
5348 break;
5349 case 1:
5350 case 8:
5351 *total = COSTS_N_INSNS (2);
5352 break;
5353 case 9:
5354 *total = COSTS_N_INSNS (3);
5355 break;
5356 case 2:
5357 case 10:
5358 case 15:
5359 *total = COSTS_N_INSNS (4);
5360 break;
5361 case 7:
5362 case 11:
5363 *total = COSTS_N_INSNS (5);
5364 break;
5365 case 3:
5366 case 12:
5367 case 13:
5368 case 14:
5369 *total = COSTS_N_INSNS (optimize_size ? 5 : 6);
5370 break;
5371 case 4:
5372 *total = COSTS_N_INSNS (optimize_size ? 5 : 7);
5373 break;
5374 case 5:
5375 case 6:
5376 *total = COSTS_N_INSNS (optimize_size ? 5 : 9);
5377 break;
5378 default:
5379 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5380 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5382 break;
5384 case SImode:
5385 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5387 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5388 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5390 else
5391 switch (INTVAL (XEXP (x, 1)))
5393 case 0:
5394 *total = 0;
5395 break;
5396 case 1:
5397 *total = COSTS_N_INSNS (4);
5398 break;
5399 case 2:
5400 *total = COSTS_N_INSNS (optimize_size ? 7 : 8);
5401 break;
5402 case 8:
5403 case 16:
5404 case 24:
5405 *total = COSTS_N_INSNS (4);
5406 break;
5407 case 31:
5408 *total = COSTS_N_INSNS (6);
5409 break;
5410 default:
5411 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5412 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5414 break;
5416 default:
5417 return false;
5419 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5420 return true;
5422 case COMPARE:
5423 switch (GET_MODE (XEXP (x, 0)))
5425 case QImode:
5426 *total = COSTS_N_INSNS (1);
5427 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5428 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5429 break;
5431 case HImode:
5432 *total = COSTS_N_INSNS (2);
5433 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5434 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5435 else if (INTVAL (XEXP (x, 1)) != 0)
5436 *total += COSTS_N_INSNS (1);
5437 break;
5439 case SImode:
5440 *total = COSTS_N_INSNS (4);
5441 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5442 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5443 else if (INTVAL (XEXP (x, 1)) != 0)
5444 *total += COSTS_N_INSNS (3);
5445 break;
5447 default:
5448 return false;
5450 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5451 return true;
5453 default:
5454 break;
5456 return false;
5459 /* Calculate the cost of a memory address. */
5461 static int
5462 avr_address_cost (rtx x)
5464 if (GET_CODE (x) == PLUS
5465 && GET_CODE (XEXP (x,1)) == CONST_INT
5466 && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
5467 && INTVAL (XEXP (x,1)) >= 61)
5468 return 18;
5469 if (CONSTANT_ADDRESS_P (x))
5471 if (avr_io_address_p (x, 1))
5472 return 2;
5473 return 4;
5475 return 4;
5478 /* EXTRA_CONSTRAINT helper */
5481 extra_constraint (rtx x, int c)
5483 if (c == 'Q'
5484 && GET_CODE (x) == MEM
5485 && GET_CODE (XEXP (x,0)) == PLUS)
5487 if (TARGET_ALL_DEBUG)
5489 fprintf (stderr, ("extra_constraint:\n"
5490 "reload_completed: %d\n"
5491 "reload_in_progress: %d\n"),
5492 reload_completed, reload_in_progress);
5493 debug_rtx (x);
5495 if (GET_CODE (x) == MEM
5496 && GET_CODE (XEXP (x,0)) == PLUS
5497 && REG_P (XEXP (XEXP (x,0), 0))
5498 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
5499 && (INTVAL (XEXP (XEXP (x,0), 1))
5500 <= MAX_LD_OFFSET (GET_MODE (x))))
5502 rtx xx = XEXP (XEXP (x,0), 0);
5503 int regno = REGNO (xx);
5504 if (TARGET_ALL_DEBUG)
5506 fprintf (stderr, ("extra_constraint:\n"
5507 "reload_completed: %d\n"
5508 "reload_in_progress: %d\n"),
5509 reload_completed, reload_in_progress);
5510 debug_rtx (x);
5512 if (regno >= FIRST_PSEUDO_REGISTER)
5513 return 1; /* allocate pseudos */
5514 else if (regno == REG_Z || regno == REG_Y)
5515 return 1; /* strictly check */
5516 else if (xx == frame_pointer_rtx
5517 || xx == arg_pointer_rtx)
5518 return 1; /* XXX frame & arg pointer checks */
5521 return 0;
5524 /* Convert condition code CONDITION to the valid AVR condition code. */
5526 RTX_CODE
5527 avr_normalize_condition (RTX_CODE condition)
5529 switch (condition)
5531 case GT:
5532 return GE;
5533 case GTU:
5534 return GEU;
5535 case LE:
5536 return LT;
5537 case LEU:
5538 return LTU;
5539 default:
5540 gcc_unreachable ();
5544 /* This function optimizes conditional jumps. */
5546 static void
5547 avr_reorg (void)
5549 rtx insn, pattern;
5551 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5553 if (! (GET_CODE (insn) == INSN
5554 || GET_CODE (insn) == CALL_INSN
5555 || GET_CODE (insn) == JUMP_INSN)
5556 || !single_set (insn))
5557 continue;
5559 pattern = PATTERN (insn);
5561 if (GET_CODE (pattern) == PARALLEL)
5562 pattern = XVECEXP (pattern, 0, 0);
5563 if (GET_CODE (pattern) == SET
5564 && SET_DEST (pattern) == cc0_rtx
5565 && compare_diff_p (insn))
5567 if (GET_CODE (SET_SRC (pattern)) == COMPARE)
5569 /* Now we work under compare insn. */
5571 pattern = SET_SRC (pattern);
5572 if (true_regnum (XEXP (pattern,0)) >= 0
5573 && true_regnum (XEXP (pattern,1)) >= 0 )
5575 rtx x = XEXP (pattern,0);
5576 rtx next = next_real_insn (insn);
5577 rtx pat = PATTERN (next);
5578 rtx src = SET_SRC (pat);
5579 rtx t = XEXP (src,0);
5580 PUT_CODE (t, swap_condition (GET_CODE (t)));
5581 XEXP (pattern,0) = XEXP (pattern,1);
5582 XEXP (pattern,1) = x;
5583 INSN_CODE (next) = -1;
5585 else if (true_regnum (XEXP (pattern,0)) >= 0
5586 && GET_CODE (XEXP (pattern,1)) == CONST_INT)
5588 rtx x = XEXP (pattern,1);
5589 rtx next = next_real_insn (insn);
5590 rtx pat = PATTERN (next);
5591 rtx src = SET_SRC (pat);
5592 rtx t = XEXP (src,0);
5593 enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
5595 if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
5597 XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
5598 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
5599 INSN_CODE (next) = -1;
5600 INSN_CODE (insn) = -1;
5604 else if (true_regnum (SET_SRC (pattern)) >= 0)
5606 /* This is a tst insn */
5607 rtx next = next_real_insn (insn);
5608 rtx pat = PATTERN (next);
5609 rtx src = SET_SRC (pat);
5610 rtx t = XEXP (src,0);
5612 PUT_CODE (t, swap_condition (GET_CODE (t)));
5613 SET_SRC (pattern) = gen_rtx_NEG (GET_MODE (SET_SRC (pattern)),
5614 SET_SRC (pattern));
5615 INSN_CODE (next) = -1;
5616 INSN_CODE (insn) = -1;
5622 /* Returns register number for function return value.*/
5625 avr_ret_register (void)
5627 return 24;
5630 /* Ceate an RTX representing the place where a
5631 library function returns a value of mode MODE. */
5634 avr_libcall_value (enum machine_mode mode)
5636 int offs = GET_MODE_SIZE (mode);
5637 if (offs < 2)
5638 offs = 2;
5639 return gen_rtx_REG (mode, RET_REGISTER + 2 - offs);
5642 /* Create an RTX representing the place where a
5643 function returns a value of data type VALTYPE. */
5646 avr_function_value (tree type, tree func ATTRIBUTE_UNUSED)
5648 unsigned int offs;
5650 if (TYPE_MODE (type) != BLKmode)
5651 return avr_libcall_value (TYPE_MODE (type));
5653 offs = int_size_in_bytes (type);
5654 if (offs < 2)
5655 offs = 2;
5656 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
5657 offs = GET_MODE_SIZE (SImode);
5658 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
5659 offs = GET_MODE_SIZE (DImode);
5661 return gen_rtx_REG (BLKmode, RET_REGISTER + 2 - offs);
5664 /* Returns nonzero if the number MASK has only one bit set. */
5667 mask_one_bit_p (HOST_WIDE_INT mask)
5669 int i;
5670 unsigned HOST_WIDE_INT n=mask;
5671 for (i = 0; i < 32; ++i)
5673 if (n & 0x80000000L)
5675 if (n & 0x7fffffffL)
5676 return 0;
5677 else
5678 return 32-i;
5680 n<<=1;
5682 return 0;
5686 /* Places additional restrictions on the register class to
5687 use when it is necessary to copy value X into a register
5688 in class CLASS. */
5690 enum reg_class
5691 preferred_reload_class (rtx x ATTRIBUTE_UNUSED, enum reg_class class)
5693 return class;
5697 test_hard_reg_class (enum reg_class class, rtx x)
5699 int regno = true_regnum (x);
5700 if (regno < 0)
5701 return 0;
5703 if (TEST_HARD_REG_CLASS (class, regno))
5704 return 1;
5706 return 0;
5711 jump_over_one_insn_p (rtx insn, rtx dest)
5713 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
5714 ? XEXP (dest, 0)
5715 : dest);
5716 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
5717 int dest_addr = INSN_ADDRESSES (uid);
5718 return dest_addr - jump_addr == get_attr_length (insn) + 1;
5721 /* Returns 1 if a value of mode MODE can be stored starting with hard
5722 register number REGNO. On the enhanced core, anything larger than
5723 1 byte must start in even numbered register for "movw" to work
5724 (this way we don't have to check for odd registers everywhere). */
5727 avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
5729 /* The only thing that can go into registers r28:r29 is a Pmode. */
5730 if (regno == REG_Y && mode == Pmode)
5731 return 1;
5733 /* Otherwise disallow all regno/mode combinations that span r28:r29. */
5734 if (regno <= (REG_Y + 1) && (regno + GET_MODE_SIZE (mode)) >= (REG_Y + 1))
5735 return 0;
5737 if (mode == QImode)
5738 return 1;
5740 /* Modes larger than QImode occupy consecutive registers. */
5741 if (regno + GET_MODE_SIZE (mode) > FIRST_PSEUDO_REGISTER)
5742 return 0;
5744 /* All modes larger than QImode should start in an even register. */
5745 return !(regno & 1);
5748 /* Returns 1 if X is a valid address for an I/O register of size SIZE
5749 (1 or 2). Used for lds/sts -> in/out optimization. Add 0x20 to SIZE
5750 to check for the lower half of I/O space (for cbi/sbi/sbic/sbis). */
5753 avr_io_address_p (rtx x, int size)
5755 return (optimize > 0 && GET_CODE (x) == CONST_INT
5756 && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size);
5759 /* Returns nonzero (bit number + 1) if X, or -X, is a constant power of 2. */
5762 const_int_pow2_p (rtx x)
5764 if (GET_CODE (x) == CONST_INT)
5766 HOST_WIDE_INT d = INTVAL (x);
5767 HOST_WIDE_INT abs_d = (d >= 0) ? d : -d;
5768 return exact_log2 (abs_d) + 1;
5770 return 0;
5773 const char *
5774 output_reload_inhi (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
5776 int tmp;
5777 if (!len)
5778 len = &tmp;
5780 if (GET_CODE (operands[1]) == CONST_INT)
5782 int val = INTVAL (operands[1]);
5783 if ((val & 0xff) == 0)
5785 *len = 3;
5786 return (AS2 (mov,%A0,__zero_reg__) CR_TAB
5787 AS2 (ldi,%2,hi8(%1)) CR_TAB
5788 AS2 (mov,%B0,%2));
5790 else if ((val & 0xff00) == 0)
5792 *len = 3;
5793 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5794 AS2 (mov,%A0,%2) CR_TAB
5795 AS2 (mov,%B0,__zero_reg__));
5797 else if ((val & 0xff) == ((val & 0xff00) >> 8))
5799 *len = 3;
5800 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5801 AS2 (mov,%A0,%2) CR_TAB
5802 AS2 (mov,%B0,%2));
5805 *len = 4;
5806 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5807 AS2 (mov,%A0,%2) CR_TAB
5808 AS2 (ldi,%2,hi8(%1)) CR_TAB
5809 AS2 (mov,%B0,%2));
5813 const char *
5814 output_reload_insisf (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
5816 rtx src = operands[1];
5817 int cnst = (GET_CODE (src) == CONST_INT);
5819 if (len)
5821 if (cnst)
5822 *len = 4 + ((INTVAL (src) & 0xff) != 0)
5823 + ((INTVAL (src) & 0xff00) != 0)
5824 + ((INTVAL (src) & 0xff0000) != 0)
5825 + ((INTVAL (src) & 0xff000000) != 0);
5826 else
5827 *len = 8;
5829 return "";
5832 if (cnst && ((INTVAL (src) & 0xff) == 0))
5833 output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
5834 else
5836 output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
5837 output_asm_insn (AS2 (mov, %A0, %2), operands);
5839 if (cnst && ((INTVAL (src) & 0xff00) == 0))
5840 output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
5841 else
5843 output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
5844 output_asm_insn (AS2 (mov, %B0, %2), operands);
5846 if (cnst && ((INTVAL (src) & 0xff0000) == 0))
5847 output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
5848 else
5850 output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
5851 output_asm_insn (AS2 (mov, %C0, %2), operands);
5853 if (cnst && ((INTVAL (src) & 0xff000000) == 0))
5854 output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
5855 else
5857 output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
5858 output_asm_insn (AS2 (mov, %D0, %2), operands);
5860 return "";
5863 void
5864 avr_output_bld (rtx operands[], int bit_nr)
5866 static char s[] = "bld %A0,0";
5868 s[5] = 'A' + (bit_nr >> 3);
5869 s[8] = '0' + (bit_nr & 7);
5870 output_asm_insn (s, operands);
5873 void
5874 avr_output_addr_vec_elt (FILE *stream, int value)
5876 switch_to_section (progmem_section);
5877 if (AVR_MEGA)
5878 fprintf (stream, "\t.word pm(.L%d)\n", value);
5879 else
5880 fprintf (stream, "\trjmp .L%d\n", value);
5882 jump_tables_size++;
5885 /* Returns 1 if SCRATCH are safe to be allocated as a scratch
5886 registers (for a define_peephole2) in the current function. */
5889 avr_peep2_scratch_safe (rtx scratch)
5891 if ((interrupt_function_p (current_function_decl)
5892 || signal_function_p (current_function_decl))
5893 && leaf_function_p ())
5895 int first_reg = true_regnum (scratch);
5896 int last_reg = first_reg + GET_MODE_SIZE (GET_MODE (scratch)) - 1;
5897 int reg;
5899 for (reg = first_reg; reg <= last_reg; reg++)
5901 if (!regs_ever_live[reg])
5902 return 0;
5905 return 1;
5908 /* Output a branch that tests a single bit of a register (QI, HI or SImode)
5909 or memory location in the I/O space (QImode only).
5911 Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
5912 Operand 1: register operand to test, or CONST_INT memory address.
5913 Operand 2: bit number (for QImode operand) or mask (HImode, SImode).
5914 Operand 3: label to jump to if the test is true. */
5916 const char *
5917 avr_out_sbxx_branch (rtx insn, rtx operands[])
5919 enum rtx_code comp = GET_CODE (operands[0]);
5920 int long_jump = (get_attr_length (insn) >= 4);
5921 int reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
5923 if (comp == GE)
5924 comp = EQ;
5925 else if (comp == LT)
5926 comp = NE;
5928 if (reverse)
5929 comp = reverse_condition (comp);
5931 if (GET_CODE (operands[1]) == CONST_INT)
5933 if (INTVAL (operands[1]) < 0x40)
5935 if (comp == EQ)
5936 output_asm_insn (AS2 (sbis,%1-0x20,%2), operands);
5937 else
5938 output_asm_insn (AS2 (sbic,%1-0x20,%2), operands);
5940 else
5942 output_asm_insn (AS2 (in,__tmp_reg__,%1-0x20), operands);
5943 if (comp == EQ)
5944 output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands);
5945 else
5946 output_asm_insn (AS2 (sbrc,__tmp_reg__,%2), operands);
5949 else /* GET_CODE (operands[1]) == REG */
5951 if (GET_MODE (operands[1]) == QImode)
5953 if (comp == EQ)
5954 output_asm_insn (AS2 (sbrs,%1,%2), operands);
5955 else
5956 output_asm_insn (AS2 (sbrc,%1,%2), operands);
5958 else /* HImode or SImode */
5960 static char buf[] = "sbrc %A1,0";
5961 int bit_nr = exact_log2 (INTVAL (operands[2])
5962 & GET_MODE_MASK (GET_MODE (operands[1])));
5964 buf[3] = (comp == EQ) ? 's' : 'c';
5965 buf[6] = 'A' + (bit_nr >> 3);
5966 buf[9] = '0' + (bit_nr & 7);
5967 output_asm_insn (buf, operands);
5971 if (long_jump)
5972 return (AS1 (rjmp,.+4) CR_TAB
5973 AS1 (jmp,%3));
5974 if (!reverse)
5975 return AS1 (rjmp,%3);
5976 return "";
5979 /* Worker function for TARGET_ASM_CONSTRUCTOR. */
5981 static void
5982 avr_asm_out_ctor (rtx symbol, int priority)
5984 fputs ("\t.global __do_global_ctors\n", asm_out_file);
5985 default_ctor_section_asm_out_constructor (symbol, priority);
5988 /* Worker function for TARGET_ASM_DESTRUCTOR. */
5990 static void
5991 avr_asm_out_dtor (rtx symbol, int priority)
5993 fputs ("\t.global __do_global_dtors\n", asm_out_file);
5994 default_dtor_section_asm_out_destructor (symbol, priority);
5997 /* Worker function for TARGET_RETURN_IN_MEMORY. */
5999 static bool
6000 avr_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
6002 if (TYPE_MODE (type) == BLKmode)
6004 HOST_WIDE_INT size = int_size_in_bytes (type);
6005 return (size == -1 || size > 8);
6007 else
6008 return false;
6011 #include "gt-avr.h"