* config/alpha/alpha.c, config/arc/arc.c,
[official-gcc.git] / gcc / config / avr / avr.c
blob716667a2ae26a9c574f1ede22eafe043265f9f38
1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004
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, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, 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_unique_section (tree, int);
72 static void avr_insert_attributes (tree, tree *);
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 default_rtx_costs (rtx, enum rtx_code, 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 /* Initial stack value specified by the `-minit-stack=' option */
115 const char *avr_init_stack = "__stack";
117 /* Default MCU name */
118 const char *avr_mcu_name = "avr2";
120 /* Preprocessor macros to define depending on MCU type. */
121 const char *avr_base_arch_macro;
122 const char *avr_extra_arch_macro;
124 /* More than 8K of program memory: use "call" and "jmp". */
125 int avr_mega_p = 0;
127 /* Enhanced core: use "movw", "mul", ... */
128 int avr_enhanced_p = 0;
130 /* Assembler only. */
131 int avr_asm_only_p = 0;
133 struct base_arch_s {
134 int asm_only;
135 int enhanced;
136 int mega;
137 const char *const macro;
140 static const struct base_arch_s avr_arch_types[] = {
141 { 1, 0, 0, NULL }, /* unknown device specified */
142 { 1, 0, 0, "__AVR_ARCH__=1" },
143 { 0, 0, 0, "__AVR_ARCH__=2" },
144 { 0, 0, 1, "__AVR_ARCH__=3" },
145 { 0, 1, 0, "__AVR_ARCH__=4" },
146 { 0, 1, 1, "__AVR_ARCH__=5" }
149 struct mcu_type_s {
150 const char *const name;
151 int arch; /* index in avr_arch_types[] */
152 /* Must lie outside user's namespace. NULL == no macro. */
153 const char *const macro;
156 /* List of all known AVR MCU types - if updated, it has to be kept
157 in sync in several places (FIXME: is there a better way?):
158 - here
159 - avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
160 - t-avr (MULTILIB_MATCHES)
161 - gas/config/tc-avr.c
162 - avr-libc */
164 static const struct mcu_type_s avr_mcu_types[] = {
165 /* Classic, <= 8K. */
166 { "avr2", 2, NULL },
167 { "at90s2313", 2, "__AVR_AT90S2313__" },
168 { "at90s2323", 2, "__AVR_AT90S2323__" },
169 { "at90s2333", 2, "__AVR_AT90S2333__" },
170 { "at90s2343", 2, "__AVR_AT90S2343__" },
171 { "attiny22", 2, "__AVR_ATtiny22__" },
172 { "attiny26", 2, "__AVR_ATtiny26__" },
173 { "at90s4414", 2, "__AVR_AT90S4414__" },
174 { "at90s4433", 2, "__AVR_AT90S4433__" },
175 { "at90s4434", 2, "__AVR_AT90S4434__" },
176 { "at90s8515", 2, "__AVR_AT90S8515__" },
177 { "at90c8534", 2, "__AVR_AT90C8534__" },
178 { "at90s8535", 2, "__AVR_AT90S8535__" },
179 { "at86rf401", 2, "__AVR_AT86RF401__" },
180 /* Classic, > 8K. */
181 { "avr3", 3, NULL },
182 { "atmega103", 3, "__AVR_ATmega103__" },
183 { "atmega603", 3, "__AVR_ATmega603__" },
184 { "at43usb320", 3, "__AVR_AT43USB320__" },
185 { "at43usb355", 3, "__AVR_AT43USB355__" },
186 { "at76c711", 3, "__AVR_AT76C711__" },
187 /* Enhanced, <= 8K. */
188 { "avr4", 4, NULL },
189 { "atmega8", 4, "__AVR_ATmega8__" },
190 { "atmega8515", 4, "__AVR_ATmega8515__" },
191 { "atmega8535", 4, "__AVR_ATmega8535__" },
192 /* Enhanced, > 8K. */
193 { "avr5", 5, NULL },
194 { "atmega16", 5, "__AVR_ATmega16__" },
195 { "atmega161", 5, "__AVR_ATmega161__" },
196 { "atmega162", 5, "__AVR_ATmega162__" },
197 { "atmega163", 5, "__AVR_ATmega163__" },
198 { "atmega169", 5, "__AVR_ATmega169__" },
199 { "atmega32", 5, "__AVR_ATmega32__" },
200 { "atmega323", 5, "__AVR_ATmega323__" },
201 { "atmega64", 5, "__AVR_ATmega64__" },
202 { "atmega128", 5, "__AVR_ATmega128__" },
203 { "at94k", 5, "__AVR_AT94K__" },
204 /* Assembler only. */
205 { "avr1", 1, NULL },
206 { "at90s1200", 1, "__AVR_AT90S1200__" },
207 { "attiny11", 1, "__AVR_ATtiny11__" },
208 { "attiny12", 1, "__AVR_ATtiny12__" },
209 { "attiny15", 1, "__AVR_ATtiny15__" },
210 { "attiny28", 1, "__AVR_ATtiny28__" },
211 { NULL, 0, NULL }
214 int avr_case_values_threshold = 30000;
216 /* Initialize the GCC target structure. */
217 #undef TARGET_ASM_ALIGNED_HI_OP
218 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
219 #undef TARGET_ASM_INTEGER
220 #define TARGET_ASM_INTEGER avr_assemble_integer
221 #undef TARGET_ASM_FILE_START
222 #define TARGET_ASM_FILE_START avr_file_start
223 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
224 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
225 #undef TARGET_ASM_FILE_END
226 #define TARGET_ASM_FILE_END avr_file_end
228 #undef TARGET_ASM_FUNCTION_PROLOGUE
229 #define TARGET_ASM_FUNCTION_PROLOGUE avr_output_function_prologue
230 #undef TARGET_ASM_FUNCTION_EPILOGUE
231 #define TARGET_ASM_FUNCTION_EPILOGUE avr_output_function_epilogue
232 #undef TARGET_ATTRIBUTE_TABLE
233 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
234 #undef TARGET_ASM_UNIQUE_SECTION
235 #define TARGET_ASM_UNIQUE_SECTION avr_unique_section
236 #undef TARGET_INSERT_ATTRIBUTES
237 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
238 #undef TARGET_SECTION_TYPE_FLAGS
239 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
240 #undef TARGET_RTX_COSTS
241 #define TARGET_RTX_COSTS avr_rtx_costs
242 #undef TARGET_ADDRESS_COST
243 #define TARGET_ADDRESS_COST avr_address_cost
244 #undef TARGET_MACHINE_DEPENDENT_REORG
245 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
247 #undef TARGET_STRUCT_VALUE_RTX
248 #define TARGET_STRUCT_VALUE_RTX hook_rtx_tree_int_null
249 #undef TARGET_RETURN_IN_MEMORY
250 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
252 #undef TARGET_STRICT_ARGUMENT_NAMING
253 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
255 struct gcc_target targetm = TARGET_INITIALIZER;
257 void
258 avr_override_options (void)
260 const struct mcu_type_s *t;
261 const struct base_arch_s *base;
263 for (t = avr_mcu_types; t->name; t++)
264 if (strcmp (t->name, avr_mcu_name) == 0)
265 break;
267 if (!t->name)
269 fprintf (stderr, "unknown MCU `%s' specified\nKnown MCU names:\n",
270 avr_mcu_name);
271 for (t = avr_mcu_types; t->name; t++)
272 fprintf (stderr," %s\n", t->name);
275 base = &avr_arch_types[t->arch];
276 avr_asm_only_p = base->asm_only;
277 avr_enhanced_p = base->enhanced;
278 avr_mega_p = base->mega;
279 avr_base_arch_macro = base->macro;
280 avr_extra_arch_macro = t->macro;
282 if (optimize && !TARGET_NO_TABLEJUMP)
283 avr_case_values_threshold = (!AVR_MEGA || TARGET_CALL_PROLOGUES) ? 8 : 17;
285 tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO);
286 zero_reg_rtx = gen_rtx_REG (QImode, ZERO_REGNO);
289 /* return register class from register number. */
291 static const int reg_class_tab[]={
292 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
293 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
294 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
295 GENERAL_REGS, /* r0 - r15 */
296 LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
297 LD_REGS, /* r16 - 23 */
298 ADDW_REGS,ADDW_REGS, /* r24,r25 */
299 POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
300 POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
301 POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
302 STACK_REG,STACK_REG /* SPL,SPH */
305 /* Return register class for register R. */
307 enum reg_class
308 avr_regno_reg_class (int r)
310 if (r <= 33)
311 return reg_class_tab[r];
312 return ALL_REGS;
316 /* A C expression which defines the machine-dependent operand
317 constraint letters for register classes. If C is such a
318 letter, the value should be the register class corresponding to
319 it. Otherwise, the value should be `NO_REGS'. The register
320 letter `r', corresponding to class `GENERAL_REGS', will not be
321 passed to this macro; you do not need to handle it. */
323 enum reg_class
324 avr_reg_class_from_letter (int c)
326 switch (c)
328 case 't' : return R0_REG;
329 case 'b' : return BASE_POINTER_REGS;
330 case 'e' : return POINTER_REGS;
331 case 'w' : return ADDW_REGS;
332 case 'd' : return LD_REGS;
333 case 'l' : return NO_LD_REGS;
334 case 'a' : return SIMPLE_LD_REGS;
335 case 'x' : return POINTER_X_REGS;
336 case 'y' : return POINTER_Y_REGS;
337 case 'z' : return POINTER_Z_REGS;
338 case 'q' : return STACK_REG;
339 default: break;
341 return NO_REGS;
344 /* Return nonzero if FUNC is a naked function. */
346 static int
347 avr_naked_function_p (tree func)
349 tree a;
351 if (TREE_CODE (func) != FUNCTION_DECL)
352 abort ();
354 a = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
355 return a != NULL_TREE;
358 /* Return nonzero if FUNC is an interrupt function as specified
359 by the "interrupt" attribute. */
361 static int
362 interrupt_function_p (tree func)
364 tree a;
366 if (TREE_CODE (func) != FUNCTION_DECL)
367 return 0;
369 a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
370 return a != NULL_TREE;
373 /* Return nonzero if FUNC is a signal function as specified
374 by the "signal" attribute. */
376 static int
377 signal_function_p (tree func)
379 tree a;
381 if (TREE_CODE (func) != FUNCTION_DECL)
382 return 0;
384 a = lookup_attribute ("signal", DECL_ATTRIBUTES (func));
385 return a != NULL_TREE;
388 /* Return the number of hard registers to push/pop in the prologue/epilogue
389 of the current function, and optionally store these registers in SET. */
391 static int
392 avr_regs_to_save (HARD_REG_SET *set)
394 int reg, count;
395 int int_or_sig_p = (interrupt_function_p (current_function_decl)
396 || signal_function_p (current_function_decl));
397 int leaf_func_p = leaf_function_p ();
399 if (set)
400 CLEAR_HARD_REG_SET (*set);
401 count = 0;
403 /* No need to save any registers if the function never returns. */
404 if (TREE_THIS_VOLATILE (current_function_decl))
405 return 0;
407 for (reg = 0; reg < 32; reg++)
409 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
410 any global register variables. */
411 if (fixed_regs[reg])
412 continue;
414 if ((int_or_sig_p && !leaf_func_p && call_used_regs[reg])
415 || (regs_ever_live[reg]
416 && (int_or_sig_p || !call_used_regs[reg])
417 && !(frame_pointer_needed
418 && (reg == REG_Y || reg == (REG_Y+1)))))
420 if (set)
421 SET_HARD_REG_BIT (*set, reg);
422 count++;
425 return count;
428 /* Compute offset between arg_pointer and frame_pointer. */
431 initial_elimination_offset (int from, int to)
433 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
434 return 0;
435 else
437 int offset = frame_pointer_needed ? 2 : 0;
439 offset += avr_regs_to_save (NULL);
440 return get_frame_size () + 2 + 1 + offset;
444 /* Return 1 if the function epilogue is just a single "ret". */
447 avr_simple_epilogue (void)
449 return (! frame_pointer_needed
450 && get_frame_size () == 0
451 && avr_regs_to_save (NULL) == 0
452 && ! interrupt_function_p (current_function_decl)
453 && ! signal_function_p (current_function_decl)
454 && ! avr_naked_function_p (current_function_decl)
455 && ! MAIN_NAME_P (DECL_NAME (current_function_decl))
456 && ! TREE_THIS_VOLATILE (current_function_decl));
459 /* This function checks sequence of live registers. */
461 static int
462 sequent_regs_live (void)
464 int reg;
465 int live_seq=0;
466 int cur_seq=0;
468 for (reg = 0; reg < 18; ++reg)
470 if (!call_used_regs[reg])
472 if (regs_ever_live[reg])
474 ++live_seq;
475 ++cur_seq;
477 else
478 cur_seq = 0;
482 if (!frame_pointer_needed)
484 if (regs_ever_live[REG_Y])
486 ++live_seq;
487 ++cur_seq;
489 else
490 cur_seq = 0;
492 if (regs_ever_live[REG_Y+1])
494 ++live_seq;
495 ++cur_seq;
497 else
498 cur_seq = 0;
500 else
502 cur_seq += 2;
503 live_seq += 2;
505 return (cur_seq == live_seq) ? live_seq : 0;
509 /* Output to FILE the asm instructions to adjust the frame pointer by
510 ADJ (r29:r28 -= ADJ;) which can be positive (prologue) or negative
511 (epilogue). Returns the number of instructions generated. */
513 static int
514 out_adj_frame_ptr (FILE *file, int adj)
516 int size = 0;
518 if (adj)
520 if (TARGET_TINY_STACK)
522 if (adj < -63 || adj > 63)
523 warning ("large frame pointer change (%d) with -mtiny-stack", adj);
525 /* The high byte (r29) doesn't change - prefer "subi" (1 cycle)
526 over "sbiw" (2 cycles, same size). */
528 fprintf (file, (AS2 (subi, r28, %d) CR_TAB), adj);
529 size++;
531 else if (adj < -63 || adj > 63)
533 fprintf (file, (AS2 (subi, r28, lo8(%d)) CR_TAB
534 AS2 (sbci, r29, hi8(%d)) CR_TAB),
535 adj, adj);
536 size += 2;
538 else if (adj < 0)
540 fprintf (file, (AS2 (adiw, r28, %d) CR_TAB), -adj);
541 size++;
543 else
545 fprintf (file, (AS2 (sbiw, r28, %d) CR_TAB), adj);
546 size++;
549 return size;
553 /* Output to FILE the asm instructions to copy r29:r28 to SPH:SPL,
554 handling various cases of interrupt enable flag state BEFORE and AFTER
555 (0=disabled, 1=enabled, -1=unknown/unchanged) and target_flags.
556 Returns the number of instructions generated. */
558 static int
559 out_set_stack_ptr (FILE *file, int before, int after)
561 int do_sph, do_cli, do_save, do_sei, lock_sph, size;
563 /* The logic here is so that -mno-interrupts actually means
564 "it is safe to write SPH in one instruction, then SPL in the
565 next instruction, without disabling interrupts first".
566 The after != -1 case (interrupt/signal) is not affected. */
568 do_sph = !TARGET_TINY_STACK;
569 lock_sph = do_sph && !TARGET_NO_INTERRUPTS;
570 do_cli = (before != 0 && (after == 0 || lock_sph));
571 do_save = (do_cli && before == -1 && after == -1);
572 do_sei = ((do_cli || before != 1) && after == 1);
573 size = 1;
575 if (do_save)
577 fprintf (file, AS2 (in, __tmp_reg__, __SREG__) CR_TAB);
578 size++;
581 if (do_cli)
583 fprintf (file, "cli" CR_TAB);
584 size++;
587 /* Do SPH first - maybe this will disable interrupts for one instruction
588 someday (a suggestion has been sent to avr@atmel.com for consideration
589 in future devices - that would make -mno-interrupts always safe). */
590 if (do_sph)
592 fprintf (file, AS2 (out, __SP_H__, r29) CR_TAB);
593 size++;
596 /* Set/restore the I flag now - interrupts will be really enabled only
597 after the next instruction. This is not clearly documented, but
598 believed to be true for all AVR devices. */
599 if (do_save)
601 fprintf (file, AS2 (out, __SREG__, __tmp_reg__) CR_TAB);
602 size++;
604 else if (do_sei)
606 fprintf (file, "sei" CR_TAB);
607 size++;
610 fprintf (file, AS2 (out, __SP_L__, r28) "\n");
612 return size;
616 /* Output function prologue. */
618 static void
619 avr_output_function_prologue (FILE *file, HOST_WIDE_INT size)
621 int reg;
622 int interrupt_func_p;
623 int signal_func_p;
624 int main_p;
625 int live_seq;
626 int minimize;
628 last_insn_address = 0;
629 jump_tables_size = 0;
630 prologue_size = 0;
631 fprintf (file, "/* prologue: frame size=" HOST_WIDE_INT_PRINT_DEC " */\n",
632 size);
634 if (avr_naked_function_p (current_function_decl))
636 fputs ("/* prologue: naked */\n", file);
637 goto out;
640 interrupt_func_p = interrupt_function_p (current_function_decl);
641 signal_func_p = signal_function_p (current_function_decl);
642 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
643 live_seq = sequent_regs_live ();
644 minimize = (TARGET_CALL_PROLOGUES
645 && !interrupt_func_p && !signal_func_p && live_seq);
647 if (interrupt_func_p)
649 fprintf (file,"\tsei\n");
650 ++prologue_size;
652 if (interrupt_func_p || signal_func_p)
654 fprintf (file, "\t"
655 AS1 (push,__zero_reg__) CR_TAB
656 AS1 (push,__tmp_reg__) CR_TAB
657 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
658 AS1 (push,__tmp_reg__) CR_TAB
659 AS1 (clr,__zero_reg__) "\n");
660 prologue_size += 5;
662 if (main_p)
664 fprintf (file, ("\t"
665 AS1 (ldi,r28) ",lo8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
666 AS1 (ldi,r29) ",hi8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
667 AS2 (out,__SP_H__,r29) CR_TAB
668 AS2 (out,__SP_L__,r28) "\n"),
669 avr_init_stack, size, avr_init_stack, size);
671 prologue_size += 4;
673 else if (minimize && (frame_pointer_needed || live_seq > 6))
675 const char *cfun_name = current_function_name ();
676 fprintf (file, ("\t"
677 AS1 (ldi, r26) ",lo8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
678 AS1 (ldi, r27) ",hi8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB), size, size);
680 fprintf (file, (AS2 (ldi, r30, pm_lo8(.L_%s_body)) CR_TAB
681 AS2 (ldi, r31, pm_hi8(.L_%s_body)) CR_TAB),
682 cfun_name, cfun_name);
684 prologue_size += 4;
686 if (AVR_MEGA)
688 fprintf (file, AS1 (jmp,__prologue_saves__+%d) "\n",
689 (18 - live_seq) * 2);
690 prologue_size += 2;
692 else
694 fprintf (file, AS1 (rjmp,__prologue_saves__+%d) "\n",
695 (18 - live_seq) * 2);
696 ++prologue_size;
698 fprintf (file, ".L_%s_body:\n", cfun_name);
700 else
702 HARD_REG_SET set;
704 prologue_size += avr_regs_to_save (&set);
705 for (reg = 0; reg < 32; ++reg)
707 if (TEST_HARD_REG_BIT (set, reg))
709 fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
712 if (frame_pointer_needed)
714 fprintf (file, "\t"
715 AS1 (push,r28) CR_TAB
716 AS1 (push,r29) CR_TAB
717 AS2 (in,r28,__SP_L__) CR_TAB
718 AS2 (in,r29,__SP_H__) "\n");
719 prologue_size += 4;
720 if (size)
722 fputs ("\t", file);
723 prologue_size += out_adj_frame_ptr (file, size);
725 if (interrupt_func_p)
727 prologue_size += out_set_stack_ptr (file, 1, 1);
729 else if (signal_func_p)
731 prologue_size += out_set_stack_ptr (file, 0, 0);
733 else
735 prologue_size += out_set_stack_ptr (file, -1, -1);
741 out:
742 fprintf (file, "/* prologue end (size=%d) */\n", prologue_size);
745 /* Output function epilogue. */
747 static void
748 avr_output_function_epilogue (FILE *file, HOST_WIDE_INT size)
750 int reg;
751 int interrupt_func_p;
752 int signal_func_p;
753 int main_p;
754 int function_size;
755 int live_seq;
756 int minimize;
757 rtx last = get_last_nonnote_insn ();
759 function_size = jump_tables_size;
760 if (last)
762 rtx first = get_first_nonnote_insn ();
763 function_size += (INSN_ADDRESSES (INSN_UID (last)) -
764 INSN_ADDRESSES (INSN_UID (first)));
765 function_size += get_attr_length (last);
768 fprintf (file, "/* epilogue: frame size=" HOST_WIDE_INT_PRINT_DEC " */\n", size);
769 epilogue_size = 0;
771 if (avr_naked_function_p (current_function_decl))
773 fputs ("/* epilogue: naked */\n", file);
774 goto out;
777 if (last && GET_CODE (last) == BARRIER)
779 fputs ("/* epilogue: noreturn */\n", file);
780 goto out;
783 interrupt_func_p = interrupt_function_p (current_function_decl);
784 signal_func_p = signal_function_p (current_function_decl);
785 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
786 live_seq = sequent_regs_live ();
787 minimize = (TARGET_CALL_PROLOGUES
788 && !interrupt_func_p && !signal_func_p && live_seq);
790 if (main_p)
792 /* Return value from main() is already in the correct registers
793 (r25:r24) as the exit() argument. */
794 if (AVR_MEGA)
796 fputs ("\t" AS1 (jmp,exit) "\n", file);
797 epilogue_size += 2;
799 else
801 fputs ("\t" AS1 (rjmp,exit) "\n", file);
802 ++epilogue_size;
805 else if (minimize && (frame_pointer_needed || live_seq > 4))
807 fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
808 ++epilogue_size;
809 if (frame_pointer_needed)
811 epilogue_size += out_adj_frame_ptr (file, -size);
813 else
815 fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
816 AS2 (in , r29, __SP_H__) CR_TAB));
817 epilogue_size += 2;
820 if (AVR_MEGA)
822 fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
823 (18 - live_seq) * 2);
824 epilogue_size += 2;
826 else
828 fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
829 (18 - live_seq) * 2);
830 ++epilogue_size;
833 else
835 HARD_REG_SET set;
837 if (frame_pointer_needed)
839 if (size)
841 fputs ("\t", file);
842 epilogue_size += out_adj_frame_ptr (file, -size);
844 if (interrupt_func_p || signal_func_p)
846 epilogue_size += out_set_stack_ptr (file, -1, 0);
848 else
850 epilogue_size += out_set_stack_ptr (file, -1, -1);
853 fprintf (file, "\t"
854 AS1 (pop,r29) CR_TAB
855 AS1 (pop,r28) "\n");
856 epilogue_size += 2;
859 epilogue_size += avr_regs_to_save (&set);
860 for (reg = 31; reg >= 0; --reg)
862 if (TEST_HARD_REG_BIT (set, reg))
864 fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
868 if (interrupt_func_p || signal_func_p)
870 fprintf (file, "\t"
871 AS1 (pop,__tmp_reg__) CR_TAB
872 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
873 AS1 (pop,__tmp_reg__) CR_TAB
874 AS1 (pop,__zero_reg__) "\n");
875 epilogue_size += 4;
876 fprintf (file, "\treti\n");
878 else
879 fprintf (file, "\tret\n");
880 ++epilogue_size;
883 out:
884 fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
885 fprintf (file, "/* function %s size %d (%d) */\n", current_function_name (),
886 prologue_size + function_size + epilogue_size, function_size);
887 commands_in_file += prologue_size + function_size + epilogue_size;
888 commands_in_prologues += prologue_size;
889 commands_in_epilogues += epilogue_size;
893 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
894 machine for a memory operand of mode MODE. */
897 legitimate_address_p (enum machine_mode mode, rtx x, int strict)
899 enum reg_class r = NO_REGS;
901 if (TARGET_ALL_DEBUG)
903 fprintf (stderr, "mode: (%s) %s %s %s %s:",
904 GET_MODE_NAME(mode),
905 strict ? "(strict)": "",
906 reload_completed ? "(reload_completed)": "",
907 reload_in_progress ? "(reload_in_progress)": "",
908 reg_renumber ? "(reg_renumber)" : "");
909 if (GET_CODE (x) == PLUS
910 && REG_P (XEXP (x, 0))
911 && GET_CODE (XEXP (x, 1)) == CONST_INT
912 && INTVAL (XEXP (x, 1)) >= 0
913 && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
914 && reg_renumber
916 fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
917 true_regnum (XEXP (x, 0)));
918 debug_rtx (x);
920 if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
921 : REG_OK_FOR_BASE_NOSTRICT_P (x)))
922 r = POINTER_REGS;
923 else if (CONSTANT_ADDRESS_P (x))
924 r = ALL_REGS;
925 else if (GET_CODE (x) == PLUS
926 && REG_P (XEXP (x, 0))
927 && GET_CODE (XEXP (x, 1)) == CONST_INT
928 && INTVAL (XEXP (x, 1)) >= 0)
930 int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
931 if (fit)
933 if (! strict
934 || REGNO (XEXP (x,0)) == REG_Y
935 || REGNO (XEXP (x,0)) == REG_Z)
936 r = BASE_POINTER_REGS;
937 if (XEXP (x,0) == frame_pointer_rtx
938 || XEXP (x,0) == arg_pointer_rtx)
939 r = BASE_POINTER_REGS;
941 else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
942 r = POINTER_Y_REGS;
944 else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
945 && REG_P (XEXP (x, 0))
946 && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
947 : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
949 r = POINTER_REGS;
951 if (TARGET_ALL_DEBUG)
953 fprintf (stderr, " ret = %c\n", r);
955 return r == NO_REGS ? 0 : (int)r;
958 /* Attempts to replace X with a valid
959 memory address for an operand of mode MODE */
962 legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
964 x = oldx;
965 if (TARGET_ALL_DEBUG)
967 fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
968 debug_rtx (oldx);
971 if (GET_CODE (oldx) == PLUS
972 && REG_P (XEXP (oldx,0)))
974 if (REG_P (XEXP (oldx,1)))
975 x = force_reg (GET_MODE (oldx), oldx);
976 else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
978 int offs = INTVAL (XEXP (oldx,1));
979 if (frame_pointer_rtx != XEXP (oldx,0))
980 if (offs > MAX_LD_OFFSET (mode))
982 if (TARGET_ALL_DEBUG)
983 fprintf (stderr, "force_reg (big offset)\n");
984 x = force_reg (GET_MODE (oldx), oldx);
988 return x;
992 /* Return a pointer register name as a string. */
994 static const char *
995 ptrreg_to_str (int regno)
997 switch (regno)
999 case REG_X: return "X";
1000 case REG_Y: return "Y";
1001 case REG_Z: return "Z";
1002 default:
1003 abort ();
1005 return NULL;
1008 /* Return the condition name as a string.
1009 Used in conditional jump constructing */
1011 static const char *
1012 cond_string (enum rtx_code code)
1014 switch (code)
1016 case NE:
1017 return "ne";
1018 case EQ:
1019 return "eq";
1020 case GE:
1021 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1022 return "pl";
1023 else
1024 return "ge";
1025 case LT:
1026 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1027 return "mi";
1028 else
1029 return "lt";
1030 case GEU:
1031 return "sh";
1032 case LTU:
1033 return "lo";
1034 default:
1035 abort ();
1039 /* Output ADDR to FILE as address. */
1041 void
1042 print_operand_address (FILE *file, rtx addr)
1044 switch (GET_CODE (addr))
1046 case REG:
1047 fprintf (file, ptrreg_to_str (REGNO (addr)));
1048 break;
1050 case PRE_DEC:
1051 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1052 break;
1054 case POST_INC:
1055 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1056 break;
1058 default:
1059 if (CONSTANT_ADDRESS_P (addr)
1060 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (addr))
1061 || GET_CODE (addr) == LABEL_REF))
1063 fprintf (file, "pm(");
1064 output_addr_const (file,addr);
1065 fprintf (file ,")");
1067 else
1068 output_addr_const (file, addr);
1073 /* Output X as assembler operand to file FILE. */
1075 void
1076 print_operand (FILE *file, rtx x, int code)
1078 int abcd = 0;
1080 if (code >= 'A' && code <= 'D')
1081 abcd = code - 'A';
1083 if (code == '~')
1085 if (!AVR_MEGA)
1086 fputc ('r', file);
1088 else if (REG_P (x))
1090 if (x == zero_reg_rtx)
1091 fprintf (file, "__zero_reg__");
1092 else
1093 fprintf (file, reg_names[true_regnum (x) + abcd]);
1095 else if (GET_CODE (x) == CONST_INT)
1096 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd);
1097 else if (GET_CODE (x) == MEM)
1099 rtx addr = XEXP (x,0);
1101 if (CONSTANT_P (addr) && abcd)
1103 fputc ('(', file);
1104 output_address (addr);
1105 fprintf (file, ")+%d", abcd);
1107 else if (code == 'o')
1109 if (GET_CODE (addr) != PLUS)
1110 fatal_insn ("bad address, not (reg+disp):", addr);
1112 print_operand (file, XEXP (addr, 1), 0);
1114 else if (GET_CODE (addr) == PLUS)
1116 print_operand_address (file, XEXP (addr,0));
1117 if (REGNO (XEXP (addr, 0)) == REG_X)
1118 fatal_insn ("internal compiler error. Bad address:"
1119 ,addr);
1120 fputc ('+', file);
1121 print_operand (file, XEXP (addr,1), code);
1123 else
1124 print_operand_address (file, addr);
1126 else if (GET_CODE (x) == CONST_DOUBLE)
1128 long val;
1129 REAL_VALUE_TYPE rv;
1130 if (GET_MODE (x) != SFmode)
1131 fatal_insn ("internal compiler error. Unknown mode:", x);
1132 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1133 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1134 fprintf (file, "0x%lx", val);
1136 else if (code == 'j')
1137 fputs (cond_string (GET_CODE (x)), file);
1138 else if (code == 'k')
1139 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
1140 else
1141 print_operand_address (file, x);
1144 /* Recognize operand OP of mode MODE used in call instructions. */
1147 call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1149 if (GET_CODE (op) == MEM)
1151 rtx inside = XEXP (op, 0);
1152 if (register_operand (inside, Pmode))
1153 return 1;
1154 if (CONSTANT_ADDRESS_P (inside))
1155 return 1;
1157 return 0;
1160 /* Update the condition code in the INSN. */
1162 void
1163 notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
1165 rtx set;
1167 switch (get_attr_cc (insn))
1169 case CC_NONE:
1170 /* Insn does not affect CC at all. */
1171 break;
1173 case CC_SET_N:
1174 CC_STATUS_INIT;
1175 break;
1177 case CC_SET_ZN:
1178 set = single_set (insn);
1179 CC_STATUS_INIT;
1180 if (set)
1182 cc_status.flags |= CC_NO_OVERFLOW;
1183 cc_status.value1 = SET_DEST (set);
1185 break;
1187 case CC_SET_CZN:
1188 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1189 The V flag may or may not be known but that's ok because
1190 alter_cond will change tests to use EQ/NE. */
1191 set = single_set (insn);
1192 CC_STATUS_INIT;
1193 if (set)
1195 cc_status.value1 = SET_DEST (set);
1196 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1198 break;
1200 case CC_COMPARE:
1201 set = single_set (insn);
1202 CC_STATUS_INIT;
1203 if (set)
1204 cc_status.value1 = SET_SRC (set);
1205 break;
1207 case CC_CLOBBER:
1208 /* Insn doesn't leave CC in a usable state. */
1209 CC_STATUS_INIT;
1211 /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1212 set = single_set (insn);
1213 if (set)
1215 rtx src = SET_SRC (set);
1217 if (GET_CODE (src) == ASHIFTRT
1218 && GET_MODE (src) == QImode)
1220 rtx x = XEXP (src, 1);
1222 if (GET_CODE (x) == CONST_INT
1223 && INTVAL (x) != 6)
1225 cc_status.value1 = SET_DEST (set);
1226 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1230 break;
1234 /* Return maximum number of consecutive registers of
1235 class CLASS needed to hold a value of mode MODE. */
1238 class_max_nregs (enum reg_class class ATTRIBUTE_UNUSED,enum machine_mode mode)
1240 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1243 /* Choose mode for jump insn:
1244 1 - relative jump in range -63 <= x <= 62 ;
1245 2 - relative jump in range -2046 <= x <= 2045 ;
1246 3 - absolute jump (only for ATmega[16]03). */
1249 avr_jump_mode (rtx x, rtx insn)
1251 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1252 ? XEXP (x, 0) : x));
1253 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1254 int jump_distance = cur_addr - dest_addr;
1256 if (-63 <= jump_distance && jump_distance <= 62)
1257 return 1;
1258 else if (-2046 <= jump_distance && jump_distance <= 2045)
1259 return 2;
1260 else if (AVR_MEGA)
1261 return 3;
1263 return 2;
1266 /* return an AVR condition jump commands.
1267 X is a comparison RTX.
1268 LEN is a number returned by avr_jump_mode function.
1269 if REVERSE nonzero then condition code in X must be reversed. */
1271 const char *
1272 ret_cond_branch (rtx x, int len, int reverse)
1274 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1276 switch (cond)
1278 case GT:
1279 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1280 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1281 AS1 (brpl,%0)) :
1282 len == 2 ? (AS1 (breq,.+4) CR_TAB
1283 AS1 (brmi,.+2) CR_TAB
1284 AS1 (rjmp,%0)) :
1285 (AS1 (breq,.+6) CR_TAB
1286 AS1 (brmi,.+4) CR_TAB
1287 AS1 (jmp,%0)));
1289 else
1290 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1291 AS1 (brge,%0)) :
1292 len == 2 ? (AS1 (breq,.+4) CR_TAB
1293 AS1 (brlt,.+2) CR_TAB
1294 AS1 (rjmp,%0)) :
1295 (AS1 (breq,.+6) CR_TAB
1296 AS1 (brlt,.+4) CR_TAB
1297 AS1 (jmp,%0)));
1298 case GTU:
1299 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1300 AS1 (brsh,%0)) :
1301 len == 2 ? (AS1 (breq,.+4) CR_TAB
1302 AS1 (brlo,.+2) CR_TAB
1303 AS1 (rjmp,%0)) :
1304 (AS1 (breq,.+6) CR_TAB
1305 AS1 (brlo,.+4) CR_TAB
1306 AS1 (jmp,%0)));
1307 case LE:
1308 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1309 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1310 AS1 (brmi,%0)) :
1311 len == 2 ? (AS1 (breq,.+2) CR_TAB
1312 AS1 (brpl,.+2) CR_TAB
1313 AS1 (rjmp,%0)) :
1314 (AS1 (breq,.+2) CR_TAB
1315 AS1 (brpl,.+4) CR_TAB
1316 AS1 (jmp,%0)));
1317 else
1318 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1319 AS1 (brlt,%0)) :
1320 len == 2 ? (AS1 (breq,.+2) CR_TAB
1321 AS1 (brge,.+2) CR_TAB
1322 AS1 (rjmp,%0)) :
1323 (AS1 (breq,.+2) CR_TAB
1324 AS1 (brge,.+4) CR_TAB
1325 AS1 (jmp,%0)));
1326 case LEU:
1327 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1328 AS1 (brlo,%0)) :
1329 len == 2 ? (AS1 (breq,.+2) CR_TAB
1330 AS1 (brsh,.+2) CR_TAB
1331 AS1 (rjmp,%0)) :
1332 (AS1 (breq,.+2) CR_TAB
1333 AS1 (brsh,.+4) CR_TAB
1334 AS1 (jmp,%0)));
1335 default:
1336 if (reverse)
1338 switch (len)
1340 case 1:
1341 return AS1 (br%k1,%0);
1342 case 2:
1343 return (AS1 (br%j1,.+2) CR_TAB
1344 AS1 (rjmp,%0));
1345 default:
1346 return (AS1 (br%j1,.+4) CR_TAB
1347 AS1 (jmp,%0));
1350 else
1352 switch (len)
1354 case 1:
1355 return AS1 (br%j1,%0);
1356 case 2:
1357 return (AS1 (br%k1,.+2) CR_TAB
1358 AS1 (rjmp,%0));
1359 default:
1360 return (AS1 (br%k1,.+4) CR_TAB
1361 AS1 (jmp,%0));
1365 return "";
1368 /* Predicate function for immediate operand which fits to byte (8bit) */
1371 byte_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1373 return (GET_CODE (op) == CONST_INT
1374 && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1377 /* Output all insn addresses and their sizes into the assembly language
1378 output file. This is helpful for debugging whether the length attributes
1379 in the md file are correct.
1380 Output insn cost for next insn. */
1382 void
1383 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
1384 int num_operands ATTRIBUTE_UNUSED)
1386 int uid = INSN_UID (insn);
1388 if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1390 fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1391 INSN_ADDRESSES (uid),
1392 INSN_ADDRESSES (uid) - last_insn_address,
1393 rtx_cost (PATTERN (insn), INSN));
1395 last_insn_address = INSN_ADDRESSES (uid);
1398 /* Return 0 if undefined, 1 if always true or always false. */
1401 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE operator, rtx x)
1403 unsigned int max = (mode == QImode ? 0xff :
1404 mode == HImode ? 0xffff :
1405 mode == SImode ? 0xffffffff : 0);
1406 if (max && operator && GET_CODE (x) == CONST_INT)
1408 if (unsigned_condition (operator) != operator)
1409 max >>= 1;
1411 if (max != (INTVAL (x) & max)
1412 && INTVAL (x) != 0xff)
1413 return 1;
1415 return 0;
1419 /* Returns nonzero if REGNO is the number of a hard
1420 register in which function arguments are sometimes passed. */
1423 function_arg_regno_p(int r)
1425 return (r >= 8 && r <= 25);
1428 /* Initializing the variable cum for the state at the beginning
1429 of the argument list. */
1431 void
1432 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
1433 tree fndecl ATTRIBUTE_UNUSED)
1435 cum->nregs = 18;
1436 cum->regno = FIRST_CUM_REG;
1437 if (!libname && fntype)
1439 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1440 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1441 != void_type_node));
1442 if (stdarg)
1443 cum->nregs = 0;
1447 /* Returns the number of registers to allocate for a function argument. */
1449 static int
1450 avr_num_arg_regs (enum machine_mode mode, tree type)
1452 int size;
1454 if (mode == BLKmode)
1455 size = int_size_in_bytes (type);
1456 else
1457 size = GET_MODE_SIZE (mode);
1459 /* Align all function arguments to start in even-numbered registers.
1460 Odd-sized arguments leave holes above them. */
1462 return (size + 1) & ~1;
1465 /* Controls whether a function argument is passed
1466 in a register, and which register. */
1469 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1470 int named ATTRIBUTE_UNUSED)
1472 int bytes = avr_num_arg_regs (mode, type);
1474 if (cum->nregs && bytes <= cum->nregs)
1475 return gen_rtx_REG (mode, cum->regno - bytes);
1477 return NULL_RTX;
1480 /* Update the summarizer variable CUM to advance past an argument
1481 in the argument list. */
1483 void
1484 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1485 int named ATTRIBUTE_UNUSED)
1487 int bytes = avr_num_arg_regs (mode, type);
1489 cum->nregs -= bytes;
1490 cum->regno -= bytes;
1492 if (cum->nregs <= 0)
1494 cum->nregs = 0;
1495 cum->regno = FIRST_CUM_REG;
1499 /***********************************************************************
1500 Functions for outputting various mov's for a various modes
1501 ************************************************************************/
1502 const char *
1503 output_movqi (rtx insn, rtx operands[], int *l)
1505 int dummy;
1506 rtx dest = operands[0];
1507 rtx src = operands[1];
1508 int *real_l = l;
1510 if (!l)
1511 l = &dummy;
1513 *l = 1;
1515 if (register_operand (dest, QImode))
1517 if (register_operand (src, QImode)) /* mov r,r */
1519 if (test_hard_reg_class (STACK_REG, dest))
1520 return AS2 (out,%0,%1);
1521 else if (test_hard_reg_class (STACK_REG, src))
1522 return AS2 (in,%0,%1);
1524 return AS2 (mov,%0,%1);
1526 else if (CONSTANT_P (src))
1528 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1529 return AS2 (ldi,%0,lo8(%1));
1531 if (GET_CODE (src) == CONST_INT)
1533 if (src == const0_rtx) /* mov r,L */
1534 return AS1 (clr,%0);
1535 else if (src == const1_rtx)
1537 *l = 2;
1538 return (AS1 (clr,%0) CR_TAB
1539 AS1 (inc,%0));
1541 else if (src == constm1_rtx)
1543 /* Immediate constants -1 to any register */
1544 *l = 2;
1545 return (AS1 (clr,%0) CR_TAB
1546 AS1 (dec,%0));
1548 else
1550 int bit_nr = exact_log2 (INTVAL (src));
1552 if (bit_nr >= 0)
1554 *l = 3;
1555 if (!real_l)
1556 output_asm_insn ((AS1 (clr,%0) CR_TAB
1557 "set"), operands);
1558 if (!real_l)
1559 avr_output_bld (operands, bit_nr);
1561 return "";
1566 /* Last resort, larger than loading from memory. */
1567 *l = 4;
1568 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1569 AS2 (ldi,r31,lo8(%1)) CR_TAB
1570 AS2 (mov,%0,r31) CR_TAB
1571 AS2 (mov,r31,__tmp_reg__));
1573 else if (GET_CODE (src) == MEM)
1574 return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1576 else if (GET_CODE (dest) == MEM)
1578 const char *template;
1580 if (src == const0_rtx)
1581 operands[1] = zero_reg_rtx;
1583 template = out_movqi_mr_r (insn, operands, real_l);
1585 if (!real_l)
1586 output_asm_insn (template, operands);
1588 operands[1] = src;
1590 return "";
1594 const char *
1595 output_movhi (rtx insn, rtx operands[], int *l)
1597 int dummy;
1598 rtx dest = operands[0];
1599 rtx src = operands[1];
1600 int *real_l = l;
1602 if (!l)
1603 l = &dummy;
1605 if (register_operand (dest, HImode))
1607 if (register_operand (src, HImode)) /* mov r,r */
1609 if (test_hard_reg_class (STACK_REG, dest))
1611 if (TARGET_TINY_STACK)
1613 *l = 1;
1614 return AS2 (out,__SP_L__,%A1);
1616 else if (TARGET_NO_INTERRUPTS)
1618 *l = 2;
1619 return (AS2 (out,__SP_H__,%B1) CR_TAB
1620 AS2 (out,__SP_L__,%A1));
1623 *l = 5;
1624 return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB
1625 "cli" CR_TAB
1626 AS2 (out,__SP_H__,%B1) CR_TAB
1627 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1628 AS2 (out,__SP_L__,%A1));
1630 else if (test_hard_reg_class (STACK_REG, src))
1632 *l = 2;
1633 return (AS2 (in,%A0,__SP_L__) CR_TAB
1634 AS2 (in,%B0,__SP_H__));
1637 if (AVR_ENHANCED)
1639 *l = 1;
1640 return (AS2 (movw,%0,%1));
1643 if (true_regnum (dest) > true_regnum (src))
1645 *l = 2;
1646 return (AS2 (mov,%B0,%B1) CR_TAB
1647 AS2 (mov,%A0,%A1));
1649 else
1651 *l = 2;
1652 return (AS2 (mov,%A0,%A1) CR_TAB
1653 AS2 (mov,%B0,%B1));
1656 else if (CONSTANT_P (src))
1658 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1660 *l = 2;
1661 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1662 AS2 (ldi,%B0,hi8(%1)));
1665 if (GET_CODE (src) == CONST_INT)
1667 if (src == const0_rtx) /* mov r,L */
1669 *l = 2;
1670 return (AS1 (clr,%A0) CR_TAB
1671 AS1 (clr,%B0));
1673 else if (src == const1_rtx)
1675 *l = 3;
1676 return (AS1 (clr,%A0) CR_TAB
1677 AS1 (clr,%B0) CR_TAB
1678 AS1 (inc,%A0));
1680 else if (src == constm1_rtx)
1682 /* Immediate constants -1 to any register */
1683 *l = 3;
1684 return (AS1 (clr,%0) CR_TAB
1685 AS1 (dec,%A0) CR_TAB
1686 AS2 (mov,%B0,%A0));
1688 else
1690 int bit_nr = exact_log2 (INTVAL (src));
1692 if (bit_nr >= 0)
1694 *l = 4;
1695 if (!real_l)
1696 output_asm_insn ((AS1 (clr,%A0) CR_TAB
1697 AS1 (clr,%B0) CR_TAB
1698 "set"), operands);
1699 if (!real_l)
1700 avr_output_bld (operands, bit_nr);
1702 return "";
1706 if ((INTVAL (src) & 0xff) == 0)
1708 *l = 5;
1709 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1710 AS1 (clr,%A0) CR_TAB
1711 AS2 (ldi,r31,hi8(%1)) CR_TAB
1712 AS2 (mov,%B0,r31) CR_TAB
1713 AS2 (mov,r31,__tmp_reg__));
1715 else if ((INTVAL (src) & 0xff00) == 0)
1717 *l = 5;
1718 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1719 AS2 (ldi,r31,lo8(%1)) CR_TAB
1720 AS2 (mov,%A0,r31) CR_TAB
1721 AS1 (clr,%B0) CR_TAB
1722 AS2 (mov,r31,__tmp_reg__));
1726 /* Last resort, equal to loading from memory. */
1727 *l = 6;
1728 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1729 AS2 (ldi,r31,lo8(%1)) CR_TAB
1730 AS2 (mov,%A0,r31) 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 (GET_CODE (src) == MEM)
1736 return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1738 else if (GET_CODE (dest) == MEM)
1740 const char *template;
1742 if (src == const0_rtx)
1743 operands[1] = zero_reg_rtx;
1745 template = out_movhi_mr_r (insn, operands, real_l);
1747 if (!real_l)
1748 output_asm_insn (template, operands);
1750 operands[1] = src;
1751 return "";
1753 fatal_insn ("invalid insn:", insn);
1754 return "";
1757 const char *
1758 out_movqi_r_mr (rtx insn, rtx op[], int *l)
1760 rtx dest = op[0];
1761 rtx src = op[1];
1762 rtx x = XEXP (src, 0);
1763 int dummy;
1765 if (!l)
1766 l = &dummy;
1768 if (CONSTANT_ADDRESS_P (x))
1770 if (avr_io_address_p (x, 1))
1772 *l = 1;
1773 return AS2 (in,%0,%1-0x20);
1775 *l = 2;
1776 return AS2 (lds,%0,%1);
1778 /* memory access by reg+disp */
1779 else if (GET_CODE (x) == PLUS
1780 && REG_P (XEXP (x,0))
1781 && GET_CODE (XEXP (x,1)) == CONST_INT)
1783 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1785 int disp = INTVAL (XEXP (x,1));
1786 if (REGNO (XEXP (x,0)) != REG_Y)
1787 fatal_insn ("incorrect insn:",insn);
1789 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1790 return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
1791 AS2 (ldd,%0,Y+63) CR_TAB
1792 AS2 (sbiw,r28,%o1-63));
1794 return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1795 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1796 AS2 (ld,%0,Y) CR_TAB
1797 AS2 (subi,r28,lo8(%o1)) CR_TAB
1798 AS2 (sbci,r29,hi8(%o1)));
1800 else if (REGNO (XEXP (x,0)) == REG_X)
1802 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1803 it but I have this situation with extremal optimizing options. */
1804 if (reg_overlap_mentioned_p (dest, XEXP (x,0))
1805 || reg_unused_after (insn, XEXP (x,0)))
1806 return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
1807 AS2 (ld,%0,X));
1809 return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
1810 AS2 (ld,%0,X) CR_TAB
1811 AS2 (sbiw,r26,%o1));
1813 *l = 1;
1814 return AS2 (ldd,%0,%1);
1816 *l = 1;
1817 return AS2 (ld,%0,%1);
1820 const char *
1821 out_movhi_r_mr (rtx insn, rtx op[], int *l)
1823 rtx dest = op[0];
1824 rtx src = op[1];
1825 rtx base = XEXP (src, 0);
1826 int reg_dest = true_regnum (dest);
1827 int reg_base = true_regnum (base);
1828 int tmp;
1830 if (!l)
1831 l = &tmp;
1833 if (reg_base > 0)
1835 if (reg_dest == reg_base) /* R = (R) */
1837 *l = 3;
1838 return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1839 AS2 (ld,%B0,%1) CR_TAB
1840 AS2 (mov,%A0,__tmp_reg__));
1842 else if (reg_base == REG_X) /* (R26) */
1844 if (reg_unused_after (insn, base))
1846 *l = 2;
1847 return (AS2 (ld,%A0,X+) CR_TAB
1848 AS2 (ld,%B0,X));
1850 *l = 3;
1851 return (AS2 (ld,%A0,X+) CR_TAB
1852 AS2 (ld,%B0,X) CR_TAB
1853 AS2 (sbiw,r26,1));
1855 else /* (R) */
1857 *l = 2;
1858 return (AS2 (ld,%A0,%1) CR_TAB
1859 AS2 (ldd,%B0,%1+1));
1862 else if (GET_CODE (base) == PLUS) /* (R + i) */
1864 int disp = INTVAL (XEXP (base, 1));
1865 int reg_base = true_regnum (XEXP (base, 0));
1867 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
1869 if (REGNO (XEXP (base, 0)) != REG_Y)
1870 fatal_insn ("incorrect insn:",insn);
1872 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1873 return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
1874 AS2 (ldd,%A0,Y+62) CR_TAB
1875 AS2 (ldd,%B0,Y+63) CR_TAB
1876 AS2 (sbiw,r28,%o1-62));
1878 return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1879 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1880 AS2 (ld,%A0,Y) CR_TAB
1881 AS2 (ldd,%B0,Y+1) CR_TAB
1882 AS2 (subi,r28,lo8(%o1)) CR_TAB
1883 AS2 (sbci,r29,hi8(%o1)));
1885 if (reg_base == REG_X)
1887 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1888 it but I have this situation with extremal
1889 optimization options. */
1891 *l = 4;
1892 if (reg_base == reg_dest)
1893 return (AS2 (adiw,r26,%o1) CR_TAB
1894 AS2 (ld,__tmp_reg__,X+) CR_TAB
1895 AS2 (ld,%B0,X) CR_TAB
1896 AS2 (mov,%A0,__tmp_reg__));
1898 return (AS2 (adiw,r26,%o1) CR_TAB
1899 AS2 (ld,%A0,X+) CR_TAB
1900 AS2 (ld,%B0,X) CR_TAB
1901 AS2 (sbiw,r26,%o1+1));
1904 if (reg_base == reg_dest)
1906 *l = 3;
1907 return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
1908 AS2 (ldd,%B0,%B1) CR_TAB
1909 AS2 (mov,%A0,__tmp_reg__));
1912 *l = 2;
1913 return (AS2 (ldd,%A0,%A1) CR_TAB
1914 AS2 (ldd,%B0,%B1));
1916 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
1918 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1919 fatal_insn ("incorrect insn:", insn);
1921 *l = 2;
1922 return (AS2 (ld,%B0,%1) CR_TAB
1923 AS2 (ld,%A0,%1));
1925 else if (GET_CODE (base) == POST_INC) /* (R++) */
1927 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1928 fatal_insn ("incorrect insn:", insn);
1930 *l = 2;
1931 return (AS2 (ld,%A0,%1) CR_TAB
1932 AS2 (ld,%B0,%1));
1934 else if (CONSTANT_ADDRESS_P (base))
1936 if (avr_io_address_p (base, 2))
1938 *l = 2;
1939 return (AS2 (in,%A0,%A1-0x20) CR_TAB
1940 AS2 (in,%B0,%B1-0x20));
1942 *l = 4;
1943 return (AS2 (lds,%A0,%A1) CR_TAB
1944 AS2 (lds,%B0,%B1));
1947 fatal_insn ("unknown move insn:",insn);
1948 return "";
1951 const char *
1952 out_movsi_r_mr (rtx insn, rtx op[], int *l)
1954 rtx dest = op[0];
1955 rtx src = op[1];
1956 rtx base = XEXP (src, 0);
1957 int reg_dest = true_regnum (dest);
1958 int reg_base = true_regnum (base);
1959 int tmp;
1961 if (!l)
1962 l = &tmp;
1964 if (reg_base > 0)
1966 if (reg_base == REG_X) /* (R26) */
1968 if (reg_dest == REG_X)
1969 /* "ld r26,-X" is undefined */
1970 return *l=7, (AS2 (adiw,r26,3) CR_TAB
1971 AS2 (ld,r29,X) CR_TAB
1972 AS2 (ld,r28,-X) CR_TAB
1973 AS2 (ld,__tmp_reg__,-X) CR_TAB
1974 AS2 (sbiw,r26,1) CR_TAB
1975 AS2 (ld,r26,X) CR_TAB
1976 AS2 (mov,r27,__tmp_reg__));
1977 else if (reg_dest == REG_X - 2)
1978 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
1979 AS2 (ld,%B0,X+) CR_TAB
1980 AS2 (ld,__tmp_reg__,X+) CR_TAB
1981 AS2 (ld,%D0,X) CR_TAB
1982 AS2 (mov,%C0,__tmp_reg__));
1983 else if (reg_unused_after (insn, base))
1984 return *l=4, (AS2 (ld,%A0,X+) CR_TAB
1985 AS2 (ld,%B0,X+) CR_TAB
1986 AS2 (ld,%C0,X+) CR_TAB
1987 AS2 (ld,%D0,X));
1988 else
1989 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
1990 AS2 (ld,%B0,X+) CR_TAB
1991 AS2 (ld,%C0,X+) CR_TAB
1992 AS2 (ld,%D0,X) CR_TAB
1993 AS2 (sbiw,r26,3));
1995 else
1997 if (reg_dest == reg_base)
1998 return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
1999 AS2 (ldd,%C0,%1+2) CR_TAB
2000 AS2 (ldd,__tmp_reg__,%1+1) CR_TAB
2001 AS2 (ld,%A0,%1) CR_TAB
2002 AS2 (mov,%B0,__tmp_reg__));
2003 else if (reg_base == reg_dest + 2)
2004 return *l=5, (AS2 (ld ,%A0,%1) CR_TAB
2005 AS2 (ldd,%B0,%1+1) CR_TAB
2006 AS2 (ldd,__tmp_reg__,%1+2) CR_TAB
2007 AS2 (ldd,%D0,%1+3) CR_TAB
2008 AS2 (mov,%C0,__tmp_reg__));
2009 else
2010 return *l=4, (AS2 (ld ,%A0,%1) CR_TAB
2011 AS2 (ldd,%B0,%1+1) CR_TAB
2012 AS2 (ldd,%C0,%1+2) CR_TAB
2013 AS2 (ldd,%D0,%1+3));
2016 else if (GET_CODE (base) == PLUS) /* (R + i) */
2018 int disp = INTVAL (XEXP (base, 1));
2020 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2022 if (REGNO (XEXP (base, 0)) != REG_Y)
2023 fatal_insn ("incorrect insn:",insn);
2025 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2026 return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2027 AS2 (ldd,%A0,Y+60) CR_TAB
2028 AS2 (ldd,%B0,Y+61) CR_TAB
2029 AS2 (ldd,%C0,Y+62) CR_TAB
2030 AS2 (ldd,%D0,Y+63) CR_TAB
2031 AS2 (sbiw,r28,%o1-60));
2033 return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2034 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2035 AS2 (ld,%A0,Y) CR_TAB
2036 AS2 (ldd,%B0,Y+1) CR_TAB
2037 AS2 (ldd,%C0,Y+2) CR_TAB
2038 AS2 (ldd,%D0,Y+3) CR_TAB
2039 AS2 (subi,r28,lo8(%o1)) CR_TAB
2040 AS2 (sbci,r29,hi8(%o1)));
2043 reg_base = true_regnum (XEXP (base, 0));
2044 if (reg_base == REG_X)
2046 /* R = (X + d) */
2047 if (reg_dest == REG_X)
2049 *l = 7;
2050 /* "ld r26,-X" is undefined */
2051 return (AS2 (adiw,r26,%o1+3) CR_TAB
2052 AS2 (ld,r29,X) CR_TAB
2053 AS2 (ld,r28,-X) CR_TAB
2054 AS2 (ld,__tmp_reg__,-X) CR_TAB
2055 AS2 (sbiw,r26,1) CR_TAB
2056 AS2 (ld,r26,X) CR_TAB
2057 AS2 (mov,r27,__tmp_reg__));
2059 *l = 6;
2060 if (reg_dest == REG_X - 2)
2061 return (AS2 (adiw,r26,%o1) CR_TAB
2062 AS2 (ld,r24,X+) CR_TAB
2063 AS2 (ld,r25,X+) CR_TAB
2064 AS2 (ld,__tmp_reg__,X+) CR_TAB
2065 AS2 (ld,r27,X) CR_TAB
2066 AS2 (mov,r26,__tmp_reg__));
2068 return (AS2 (adiw,r26,%o1) CR_TAB
2069 AS2 (ld,%A0,X+) CR_TAB
2070 AS2 (ld,%B0,X+) CR_TAB
2071 AS2 (ld,%C0,X+) CR_TAB
2072 AS2 (ld,%D0,X) CR_TAB
2073 AS2 (sbiw,r26,%o1+3));
2075 if (reg_dest == reg_base)
2076 return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2077 AS2 (ldd,%C0,%C1) CR_TAB
2078 AS2 (ldd,__tmp_reg__,%B1) CR_TAB
2079 AS2 (ldd,%A0,%A1) CR_TAB
2080 AS2 (mov,%B0,__tmp_reg__));
2081 else if (reg_dest == reg_base - 2)
2082 return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2083 AS2 (ldd,%B0,%B1) CR_TAB
2084 AS2 (ldd,__tmp_reg__,%C1) CR_TAB
2085 AS2 (ldd,%D0,%D1) CR_TAB
2086 AS2 (mov,%C0,__tmp_reg__));
2087 return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2088 AS2 (ldd,%B0,%B1) CR_TAB
2089 AS2 (ldd,%C0,%C1) CR_TAB
2090 AS2 (ldd,%D0,%D1));
2092 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2093 return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2094 AS2 (ld,%C0,%1) CR_TAB
2095 AS2 (ld,%B0,%1) CR_TAB
2096 AS2 (ld,%A0,%1));
2097 else if (GET_CODE (base) == POST_INC) /* (R++) */
2098 return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2099 AS2 (ld,%B0,%1) CR_TAB
2100 AS2 (ld,%C0,%1) CR_TAB
2101 AS2 (ld,%D0,%1));
2102 else if (CONSTANT_ADDRESS_P (base))
2103 return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2104 AS2 (lds,%B0,%B1) CR_TAB
2105 AS2 (lds,%C0,%C1) CR_TAB
2106 AS2 (lds,%D0,%D1));
2108 fatal_insn ("unknown move insn:",insn);
2109 return "";
2112 const char *
2113 out_movsi_mr_r (rtx insn, rtx op[], int *l)
2115 rtx dest = op[0];
2116 rtx src = op[1];
2117 rtx base = XEXP (dest, 0);
2118 int reg_base = true_regnum (base);
2119 int reg_src = true_regnum (src);
2120 int tmp;
2122 if (!l)
2123 l = &tmp;
2125 if (CONSTANT_ADDRESS_P (base))
2126 return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2127 AS2 (sts,%B0,%B1) CR_TAB
2128 AS2 (sts,%C0,%C1) CR_TAB
2129 AS2 (sts,%D0,%D1));
2130 if (reg_base > 0) /* (r) */
2132 if (reg_base == REG_X) /* (R26) */
2134 if (reg_src == REG_X)
2136 /* "st X+,r26" is undefined */
2137 if (reg_unused_after (insn, base))
2138 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2139 AS2 (st,X,r26) CR_TAB
2140 AS2 (adiw,r26,1) CR_TAB
2141 AS2 (st,X+,__tmp_reg__) CR_TAB
2142 AS2 (st,X+,r28) CR_TAB
2143 AS2 (st,X,r29));
2144 else
2145 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2146 AS2 (st,X,r26) CR_TAB
2147 AS2 (adiw,r26,1) CR_TAB
2148 AS2 (st,X+,__tmp_reg__) CR_TAB
2149 AS2 (st,X+,r28) CR_TAB
2150 AS2 (st,X,r29) CR_TAB
2151 AS2 (sbiw,r26,3));
2153 else if (reg_base == reg_src + 2)
2155 if (reg_unused_after (insn, base))
2156 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2157 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2158 AS2 (st,%0+,%A1) CR_TAB
2159 AS2 (st,%0+,%B1) CR_TAB
2160 AS2 (st,%0+,__zero_reg__) CR_TAB
2161 AS2 (st,%0,__tmp_reg__) CR_TAB
2162 AS1 (clr,__zero_reg__));
2163 else
2164 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2165 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2166 AS2 (st,%0+,%A1) CR_TAB
2167 AS2 (st,%0+,%B1) CR_TAB
2168 AS2 (st,%0+,__zero_reg__) CR_TAB
2169 AS2 (st,%0,__tmp_reg__) CR_TAB
2170 AS1 (clr,__zero_reg__) CR_TAB
2171 AS2 (sbiw,r26,3));
2173 return *l=5, (AS2 (st,%0+,%A1) CR_TAB
2174 AS2 (st,%0+,%B1) CR_TAB
2175 AS2 (st,%0+,%C1) CR_TAB
2176 AS2 (st,%0,%D1) CR_TAB
2177 AS2 (sbiw,r26,3));
2179 else
2180 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2181 AS2 (std,%0+1,%B1) CR_TAB
2182 AS2 (std,%0+2,%C1) CR_TAB
2183 AS2 (std,%0+3,%D1));
2185 else if (GET_CODE (base) == PLUS) /* (R + i) */
2187 int disp = INTVAL (XEXP (base, 1));
2188 reg_base = REGNO (XEXP (base, 0));
2189 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2191 if (reg_base != REG_Y)
2192 fatal_insn ("incorrect insn:",insn);
2194 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2195 return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2196 AS2 (std,Y+60,%A1) CR_TAB
2197 AS2 (std,Y+61,%B1) CR_TAB
2198 AS2 (std,Y+62,%C1) CR_TAB
2199 AS2 (std,Y+63,%D1) CR_TAB
2200 AS2 (sbiw,r28,%o0-60));
2202 return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2203 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2204 AS2 (st,Y,%A1) CR_TAB
2205 AS2 (std,Y+1,%B1) CR_TAB
2206 AS2 (std,Y+2,%C1) CR_TAB
2207 AS2 (std,Y+3,%D1) CR_TAB
2208 AS2 (subi,r28,lo8(%o0)) CR_TAB
2209 AS2 (sbci,r29,hi8(%o0)));
2211 if (reg_base == REG_X)
2213 /* (X + d) = R */
2214 if (reg_src == REG_X)
2216 *l = 9;
2217 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2218 AS2 (mov,__zero_reg__,r27) CR_TAB
2219 AS2 (adiw,r26,%o0) CR_TAB
2220 AS2 (st,X+,__tmp_reg__) CR_TAB
2221 AS2 (st,X+,__zero_reg__) CR_TAB
2222 AS2 (st,X+,r28) CR_TAB
2223 AS2 (st,X,r29) CR_TAB
2224 AS1 (clr,__zero_reg__) CR_TAB
2225 AS2 (sbiw,r26,%o0+3));
2227 else if (reg_src == REG_X - 2)
2229 *l = 9;
2230 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2231 AS2 (mov,__zero_reg__,r27) CR_TAB
2232 AS2 (adiw,r26,%o0) CR_TAB
2233 AS2 (st,X+,r24) CR_TAB
2234 AS2 (st,X+,r25) CR_TAB
2235 AS2 (st,X+,__tmp_reg__) CR_TAB
2236 AS2 (st,X,__zero_reg__) CR_TAB
2237 AS1 (clr,__zero_reg__) CR_TAB
2238 AS2 (sbiw,r26,%o0+3));
2240 *l = 6;
2241 return (AS2 (adiw,r26,%o0) CR_TAB
2242 AS2 (st,X+,%A1) CR_TAB
2243 AS2 (st,X+,%B1) CR_TAB
2244 AS2 (st,X+,%C1) CR_TAB
2245 AS2 (st,X,%D1) CR_TAB
2246 AS2 (sbiw,r26,%o0+3));
2248 return *l=4, (AS2 (std,%A0,%A1) CR_TAB
2249 AS2 (std,%B0,%B1) CR_TAB
2250 AS2 (std,%C0,%C1) CR_TAB
2251 AS2 (std,%D0,%D1));
2253 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2254 return *l=4, (AS2 (st,%0,%D1) CR_TAB
2255 AS2 (st,%0,%C1) CR_TAB
2256 AS2 (st,%0,%B1) CR_TAB
2257 AS2 (st,%0,%A1));
2258 else if (GET_CODE (base) == POST_INC) /* (R++) */
2259 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2260 AS2 (st,%0,%B1) CR_TAB
2261 AS2 (st,%0,%C1) CR_TAB
2262 AS2 (st,%0,%D1));
2263 fatal_insn ("unknown move insn:",insn);
2264 return "";
2267 const char *
2268 output_movsisf(rtx insn, rtx operands[], int *l)
2270 int dummy;
2271 rtx dest = operands[0];
2272 rtx src = operands[1];
2273 int *real_l = l;
2275 if (!l)
2276 l = &dummy;
2278 if (register_operand (dest, VOIDmode))
2280 if (register_operand (src, VOIDmode)) /* mov r,r */
2282 if (true_regnum (dest) > true_regnum (src))
2284 if (AVR_ENHANCED)
2286 *l = 2;
2287 return (AS2 (movw,%C0,%C1) CR_TAB
2288 AS2 (movw,%A0,%A1));
2290 *l = 4;
2291 return (AS2 (mov,%D0,%D1) CR_TAB
2292 AS2 (mov,%C0,%C1) CR_TAB
2293 AS2 (mov,%B0,%B1) CR_TAB
2294 AS2 (mov,%A0,%A1));
2296 else
2298 if (AVR_ENHANCED)
2300 *l = 2;
2301 return (AS2 (movw,%A0,%A1) CR_TAB
2302 AS2 (movw,%C0,%C1));
2304 *l = 4;
2305 return (AS2 (mov,%A0,%A1) CR_TAB
2306 AS2 (mov,%B0,%B1) CR_TAB
2307 AS2 (mov,%C0,%C1) CR_TAB
2308 AS2 (mov,%D0,%D1));
2311 else if (CONSTANT_P (src))
2313 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2315 *l = 4;
2316 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
2317 AS2 (ldi,%B0,hi8(%1)) CR_TAB
2318 AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2319 AS2 (ldi,%D0,hhi8(%1)));
2322 if (GET_CODE (src) == CONST_INT)
2324 const char *const clr_op0 =
2325 AVR_ENHANCED ? (AS1 (clr,%A0) CR_TAB
2326 AS1 (clr,%B0) CR_TAB
2327 AS2 (movw,%C0,%A0))
2328 : (AS1 (clr,%A0) CR_TAB
2329 AS1 (clr,%B0) CR_TAB
2330 AS1 (clr,%C0) CR_TAB
2331 AS1 (clr,%D0));
2333 if (src == const0_rtx) /* mov r,L */
2335 *l = AVR_ENHANCED ? 3 : 4;
2336 return clr_op0;
2338 else if (src == const1_rtx)
2340 if (!real_l)
2341 output_asm_insn (clr_op0, operands);
2342 *l = AVR_ENHANCED ? 4 : 5;
2343 return AS1 (inc,%A0);
2345 else if (src == constm1_rtx)
2347 /* Immediate constants -1 to any register */
2348 if (AVR_ENHANCED)
2350 *l = 4;
2351 return (AS1 (clr,%A0) CR_TAB
2352 AS1 (dec,%A0) CR_TAB
2353 AS2 (mov,%B0,%A0) CR_TAB
2354 AS2 (movw,%C0,%A0));
2356 *l = 5;
2357 return (AS1 (clr,%A0) CR_TAB
2358 AS1 (dec,%A0) CR_TAB
2359 AS2 (mov,%B0,%A0) CR_TAB
2360 AS2 (mov,%C0,%A0) CR_TAB
2361 AS2 (mov,%D0,%A0));
2363 else
2365 int bit_nr = exact_log2 (INTVAL (src));
2367 if (bit_nr >= 0)
2369 *l = AVR_ENHANCED ? 5 : 6;
2370 if (!real_l)
2372 output_asm_insn (clr_op0, operands);
2373 output_asm_insn ("set", operands);
2375 if (!real_l)
2376 avr_output_bld (operands, bit_nr);
2378 return "";
2383 /* Last resort, better than loading from memory. */
2384 *l = 10;
2385 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2386 AS2 (ldi,r31,lo8(%1)) CR_TAB
2387 AS2 (mov,%A0,r31) CR_TAB
2388 AS2 (ldi,r31,hi8(%1)) CR_TAB
2389 AS2 (mov,%B0,r31) CR_TAB
2390 AS2 (ldi,r31,hlo8(%1)) CR_TAB
2391 AS2 (mov,%C0,r31) CR_TAB
2392 AS2 (ldi,r31,hhi8(%1)) CR_TAB
2393 AS2 (mov,%D0,r31) CR_TAB
2394 AS2 (mov,r31,__tmp_reg__));
2396 else if (GET_CODE (src) == MEM)
2397 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2399 else if (GET_CODE (dest) == MEM)
2401 const char *template;
2403 if (src == const0_rtx)
2404 operands[1] = zero_reg_rtx;
2406 template = out_movsi_mr_r (insn, operands, real_l);
2408 if (!real_l)
2409 output_asm_insn (template, operands);
2411 operands[1] = src;
2412 return "";
2414 fatal_insn ("invalid insn:", insn);
2415 return "";
2418 const char *
2419 out_movqi_mr_r (rtx insn, rtx op[], int *l)
2421 rtx dest = op[0];
2422 rtx src = op[1];
2423 rtx x = XEXP (dest, 0);
2424 int dummy;
2426 if (!l)
2427 l = &dummy;
2429 if (CONSTANT_ADDRESS_P (x))
2431 if (avr_io_address_p (x, 1))
2433 *l = 1;
2434 return AS2 (out,%0-0x20,%1);
2436 *l = 2;
2437 return AS2 (sts,%0,%1);
2439 /* memory access by reg+disp */
2440 else if (GET_CODE (x) == PLUS
2441 && REG_P (XEXP (x,0))
2442 && GET_CODE (XEXP (x,1)) == CONST_INT)
2444 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2446 int disp = INTVAL (XEXP (x,1));
2447 if (REGNO (XEXP (x,0)) != REG_Y)
2448 fatal_insn ("incorrect insn:",insn);
2450 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2451 return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2452 AS2 (std,Y+63,%1) CR_TAB
2453 AS2 (sbiw,r28,%o0-63));
2455 return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2456 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2457 AS2 (st,Y,%1) CR_TAB
2458 AS2 (subi,r28,lo8(%o0)) CR_TAB
2459 AS2 (sbci,r29,hi8(%o0)));
2461 else if (REGNO (XEXP (x,0)) == REG_X)
2463 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2465 if (reg_unused_after (insn, XEXP (x,0)))
2466 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2467 AS2 (adiw,r26,%o0) CR_TAB
2468 AS2 (st,X,__tmp_reg__));
2470 return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2471 AS2 (adiw,r26,%o0) CR_TAB
2472 AS2 (st,X,__tmp_reg__) CR_TAB
2473 AS2 (sbiw,r26,%o0));
2475 else
2477 if (reg_unused_after (insn, XEXP (x,0)))
2478 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2479 AS2 (st,X,%1));
2481 return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2482 AS2 (st,X,%1) CR_TAB
2483 AS2 (sbiw,r26,%o0));
2486 *l = 1;
2487 return AS2 (std,%0,%1);
2489 *l = 1;
2490 return AS2 (st,%0,%1);
2493 const char *
2494 out_movhi_mr_r (rtx insn, rtx op[], int *l)
2496 rtx dest = op[0];
2497 rtx src = op[1];
2498 rtx base = XEXP (dest, 0);
2499 int reg_base = true_regnum (base);
2500 int reg_src = true_regnum (src);
2501 int tmp;
2502 if (!l)
2503 l = &tmp;
2504 if (CONSTANT_ADDRESS_P (base))
2506 if (avr_io_address_p (base, 2))
2508 *l = 2;
2509 return (AS2 (out,%B0-0x20,%B1) CR_TAB
2510 AS2 (out,%A0-0x20,%A1));
2512 return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2513 AS2 (sts,%A0,%A1));
2515 if (reg_base > 0)
2517 if (reg_base == REG_X)
2519 if (reg_src == REG_X)
2521 /* "st X+,r26" is undefined */
2522 if (reg_unused_after (insn, src))
2523 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2524 AS2 (st,X,r26) CR_TAB
2525 AS2 (adiw,r26,1) CR_TAB
2526 AS2 (st,X,__tmp_reg__));
2527 else
2528 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2529 AS2 (st,X,r26) CR_TAB
2530 AS2 (adiw,r26,1) CR_TAB
2531 AS2 (st,X,__tmp_reg__) CR_TAB
2532 AS2 (sbiw,r26,1));
2534 else
2536 if (reg_unused_after (insn, base))
2537 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2538 AS2 (st,X,%B1));
2539 else
2540 return *l=3, (AS2 (st ,X+,%A1) CR_TAB
2541 AS2 (st ,X,%B1) CR_TAB
2542 AS2 (sbiw,r26,1));
2545 else
2546 return *l=2, (AS2 (st ,%0,%A1) CR_TAB
2547 AS2 (std,%0+1,%B1));
2549 else if (GET_CODE (base) == PLUS)
2551 int disp = INTVAL (XEXP (base, 1));
2552 reg_base = REGNO (XEXP (base, 0));
2553 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2555 if (reg_base != REG_Y)
2556 fatal_insn ("incorrect insn:",insn);
2558 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2559 return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2560 AS2 (std,Y+62,%A1) CR_TAB
2561 AS2 (std,Y+63,%B1) CR_TAB
2562 AS2 (sbiw,r28,%o0-62));
2564 return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2565 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2566 AS2 (st,Y,%A1) CR_TAB
2567 AS2 (std,Y+1,%B1) CR_TAB
2568 AS2 (subi,r28,lo8(%o0)) CR_TAB
2569 AS2 (sbci,r29,hi8(%o0)));
2571 if (reg_base == REG_X)
2573 /* (X + d) = R */
2574 if (reg_src == REG_X)
2576 *l = 7;
2577 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2578 AS2 (mov,__zero_reg__,r27) CR_TAB
2579 AS2 (adiw,r26,%o0) CR_TAB
2580 AS2 (st,X+,__tmp_reg__) CR_TAB
2581 AS2 (st,X,__zero_reg__) CR_TAB
2582 AS1 (clr,__zero_reg__) CR_TAB
2583 AS2 (sbiw,r26,%o0+1));
2585 *l = 4;
2586 return (AS2 (adiw,r26,%o0) CR_TAB
2587 AS2 (st,X+,%A1) CR_TAB
2588 AS2 (st,X,%B1) CR_TAB
2589 AS2 (sbiw,r26,%o0+1));
2591 return *l=2, (AS2 (std,%A0,%A1) CR_TAB
2592 AS2 (std,%B0,%B1));
2594 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2595 return *l=2, (AS2 (st,%0,%B1) CR_TAB
2596 AS2 (st,%0,%A1));
2597 else if (GET_CODE (base) == POST_INC) /* (R++) */
2598 return *l=2, (AS2 (st,%0,%A1) CR_TAB
2599 AS2 (st,%0,%B1));
2600 fatal_insn ("unknown move insn:",insn);
2601 return "";
2604 /* Return 1 if frame pointer for current function required. */
2607 frame_pointer_required_p (void)
2609 return (current_function_calls_alloca
2610 || current_function_args_info.nregs == 0
2611 || get_frame_size () > 0);
2614 /* Returns the condition of compare insn INSN, or UNKNOWN. */
2616 static RTX_CODE
2617 compare_condition (rtx insn)
2619 rtx next = next_real_insn (insn);
2620 RTX_CODE cond = UNKNOWN;
2621 if (next && GET_CODE (next) == JUMP_INSN)
2623 rtx pat = PATTERN (next);
2624 rtx src = SET_SRC (pat);
2625 rtx t = XEXP (src, 0);
2626 cond = GET_CODE (t);
2628 return cond;
2631 /* Returns nonzero if INSN is a tst insn that only tests the sign. */
2633 static int
2634 compare_sign_p (rtx insn)
2636 RTX_CODE cond = compare_condition (insn);
2637 return (cond == GE || cond == LT);
2640 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
2641 that needs to be swapped (GT, GTU, LE, LEU). */
2644 compare_diff_p (rtx insn)
2646 RTX_CODE cond = compare_condition (insn);
2647 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2650 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition. */
2653 compare_eq_p (rtx insn)
2655 RTX_CODE cond = compare_condition (insn);
2656 return (cond == EQ || cond == NE);
2660 /* Output test instruction for HImode. */
2662 const char *
2663 out_tsthi (rtx insn, int *l)
2665 if (compare_sign_p (insn))
2667 if (l) *l = 1;
2668 return AS1 (tst,%B0);
2670 if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
2671 && compare_eq_p (insn))
2673 /* Faster than sbiw if we can clobber the operand. */
2674 if (l) *l = 1;
2675 return AS2 (or,%A0,%B0);
2677 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2679 if (l) *l = 1;
2680 return AS2 (sbiw,%0,0);
2682 if (l) *l = 2;
2683 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2684 AS2 (cpc,%B0,__zero_reg__));
2688 /* Output test instruction for SImode. */
2690 const char *
2691 out_tstsi (rtx insn, int *l)
2693 if (compare_sign_p (insn))
2695 if (l) *l = 1;
2696 return AS1 (tst,%D0);
2698 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2700 if (l) *l = 3;
2701 return (AS2 (sbiw,%A0,0) CR_TAB
2702 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2703 AS2 (cpc,%D0,__zero_reg__));
2705 if (l) *l = 4;
2706 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2707 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2708 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2709 AS2 (cpc,%D0,__zero_reg__));
2713 /* Generate asm equivalent for various shifts.
2714 Shift count is a CONST_INT, MEM or REG.
2715 This only handles cases that are not already
2716 carefully hand-optimized in ?sh??i3_out. */
2718 void
2719 out_shift_with_cnt (const char *template, rtx insn, rtx operands[],
2720 int *len, int t_len)
2722 rtx op[10];
2723 char str[500];
2724 int second_label = 1;
2725 int saved_in_tmp = 0;
2726 int use_zero_reg = 0;
2728 op[0] = operands[0];
2729 op[1] = operands[1];
2730 op[2] = operands[2];
2731 op[3] = operands[3];
2732 str[0] = 0;
2734 if (len)
2735 *len = 1;
2737 if (GET_CODE (operands[2]) == CONST_INT)
2739 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2740 int count = INTVAL (operands[2]);
2741 int max_len = 10; /* If larger than this, always use a loop. */
2743 if (count < 8 && !scratch)
2744 use_zero_reg = 1;
2746 if (optimize_size)
2747 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
2749 if (t_len * count <= max_len)
2751 /* Output shifts inline with no loop - faster. */
2752 if (len)
2753 *len = t_len * count;
2754 else
2756 while (count-- > 0)
2757 output_asm_insn (template, op);
2760 return;
2763 if (scratch)
2765 if (!len)
2766 strcat (str, AS2 (ldi,%3,%2));
2768 else if (use_zero_reg)
2770 /* Hack to save one word: use __zero_reg__ as loop counter.
2771 Set one bit, then shift in a loop until it is 0 again. */
2773 op[3] = zero_reg_rtx;
2774 if (len)
2775 *len = 2;
2776 else
2777 strcat (str, ("set" CR_TAB
2778 AS2 (bld,%3,%2-1)));
2780 else
2782 /* No scratch register available, use one from LD_REGS (saved in
2783 __tmp_reg__) that doesn't overlap with registers to shift. */
2785 op[3] = gen_rtx_REG (QImode,
2786 ((true_regnum (operands[0]) - 1) & 15) + 16);
2787 op[4] = tmp_reg_rtx;
2788 saved_in_tmp = 1;
2790 if (len)
2791 *len = 3; /* Includes "mov %3,%4" after the loop. */
2792 else
2793 strcat (str, (AS2 (mov,%4,%3) CR_TAB
2794 AS2 (ldi,%3,%2)));
2797 second_label = 0;
2799 else if (GET_CODE (operands[2]) == MEM)
2801 rtx op_mov[10];
2803 op[3] = op_mov[0] = tmp_reg_rtx;
2804 op_mov[1] = op[2];
2806 if (len)
2807 out_movqi_r_mr (insn, op_mov, len);
2808 else
2809 output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2811 else if (register_operand (operands[2], QImode))
2813 if (reg_unused_after (insn, operands[2]))
2814 op[3] = op[2];
2815 else
2817 op[3] = tmp_reg_rtx;
2818 if (!len)
2819 strcat (str, (AS2 (mov,%3,%2) CR_TAB));
2822 else
2823 fatal_insn ("bad shift insn:", insn);
2825 if (second_label)
2827 if (len)
2828 ++*len;
2829 else
2830 strcat (str, AS1 (rjmp,2f));
2833 if (len)
2834 *len += t_len + 2; /* template + dec + brXX */
2835 else
2837 strcat (str, "\n1:\t");
2838 strcat (str, template);
2839 strcat (str, second_label ? "\n2:\t" : "\n\t");
2840 strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
2841 strcat (str, CR_TAB);
2842 strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
2843 if (saved_in_tmp)
2844 strcat (str, (CR_TAB AS2 (mov,%3,%4)));
2845 output_asm_insn (str, op);
2850 /* 8bit shift left ((char)x << i) */
2852 const char *
2853 ashlqi3_out (rtx insn, rtx operands[], int *len)
2855 if (GET_CODE (operands[2]) == CONST_INT)
2857 int k;
2859 if (!len)
2860 len = &k;
2862 switch (INTVAL (operands[2]))
2864 default:
2865 *len = 1;
2866 return AS1 (clr,%0);
2868 case 1:
2869 *len = 1;
2870 return AS1 (lsl,%0);
2872 case 2:
2873 *len = 2;
2874 return (AS1 (lsl,%0) CR_TAB
2875 AS1 (lsl,%0));
2877 case 3:
2878 *len = 3;
2879 return (AS1 (lsl,%0) CR_TAB
2880 AS1 (lsl,%0) CR_TAB
2881 AS1 (lsl,%0));
2883 case 4:
2884 if (test_hard_reg_class (LD_REGS, operands[0]))
2886 *len = 2;
2887 return (AS1 (swap,%0) CR_TAB
2888 AS2 (andi,%0,0xf0));
2890 *len = 4;
2891 return (AS1 (lsl,%0) CR_TAB
2892 AS1 (lsl,%0) CR_TAB
2893 AS1 (lsl,%0) CR_TAB
2894 AS1 (lsl,%0));
2896 case 5:
2897 if (test_hard_reg_class (LD_REGS, operands[0]))
2899 *len = 3;
2900 return (AS1 (swap,%0) CR_TAB
2901 AS1 (lsl,%0) CR_TAB
2902 AS2 (andi,%0,0xe0));
2904 *len = 5;
2905 return (AS1 (lsl,%0) CR_TAB
2906 AS1 (lsl,%0) CR_TAB
2907 AS1 (lsl,%0) CR_TAB
2908 AS1 (lsl,%0) CR_TAB
2909 AS1 (lsl,%0));
2911 case 6:
2912 if (test_hard_reg_class (LD_REGS, operands[0]))
2914 *len = 4;
2915 return (AS1 (swap,%0) CR_TAB
2916 AS1 (lsl,%0) CR_TAB
2917 AS1 (lsl,%0) CR_TAB
2918 AS2 (andi,%0,0xc0));
2920 *len = 6;
2921 return (AS1 (lsl,%0) CR_TAB
2922 AS1 (lsl,%0) CR_TAB
2923 AS1 (lsl,%0) CR_TAB
2924 AS1 (lsl,%0) CR_TAB
2925 AS1 (lsl,%0) CR_TAB
2926 AS1 (lsl,%0));
2928 case 7:
2929 *len = 3;
2930 return (AS1 (ror,%0) CR_TAB
2931 AS1 (clr,%0) CR_TAB
2932 AS1 (ror,%0));
2935 else if (CONSTANT_P (operands[2]))
2936 fatal_insn ("internal compiler error. Incorrect shift:", insn);
2938 out_shift_with_cnt (AS1 (lsl,%0),
2939 insn, operands, len, 1);
2940 return "";
2944 /* 16bit shift left ((short)x << i) */
2946 const char *
2947 ashlhi3_out (rtx insn, rtx operands[], int *len)
2949 if (GET_CODE (operands[2]) == CONST_INT)
2951 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2952 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
2953 int k;
2954 int *t = len;
2956 if (!len)
2957 len = &k;
2959 switch (INTVAL (operands[2]))
2961 case 4:
2962 if (optimize_size && scratch)
2963 break; /* 5 */
2964 if (ldi_ok)
2966 *len = 6;
2967 return (AS1 (swap,%A0) CR_TAB
2968 AS1 (swap,%B0) CR_TAB
2969 AS2 (andi,%B0,0xf0) CR_TAB
2970 AS2 (eor,%B0,%A0) CR_TAB
2971 AS2 (andi,%A0,0xf0) CR_TAB
2972 AS2 (eor,%B0,%A0));
2974 if (scratch)
2976 *len = 7;
2977 return (AS1 (swap,%A0) CR_TAB
2978 AS1 (swap,%B0) CR_TAB
2979 AS2 (ldi,%3,0xf0) CR_TAB
2980 AS2 (and,%B0,%3) CR_TAB
2981 AS2 (eor,%B0,%A0) CR_TAB
2982 AS2 (and,%A0,%3) CR_TAB
2983 AS2 (eor,%B0,%A0));
2985 break; /* optimize_size ? 6 : 8 */
2987 case 5:
2988 if (optimize_size)
2989 break; /* scratch ? 5 : 6 */
2990 if (ldi_ok)
2992 *len = 8;
2993 return (AS1 (lsl,%A0) CR_TAB
2994 AS1 (rol,%B0) CR_TAB
2995 AS1 (swap,%A0) CR_TAB
2996 AS1 (swap,%B0) CR_TAB
2997 AS2 (andi,%B0,0xf0) CR_TAB
2998 AS2 (eor,%B0,%A0) CR_TAB
2999 AS2 (andi,%A0,0xf0) CR_TAB
3000 AS2 (eor,%B0,%A0));
3002 if (scratch)
3004 *len = 9;
3005 return (AS1 (lsl,%A0) CR_TAB
3006 AS1 (rol,%B0) CR_TAB
3007 AS1 (swap,%A0) CR_TAB
3008 AS1 (swap,%B0) CR_TAB
3009 AS2 (ldi,%3,0xf0) CR_TAB
3010 AS2 (and,%B0,%3) CR_TAB
3011 AS2 (eor,%B0,%A0) CR_TAB
3012 AS2 (and,%A0,%3) CR_TAB
3013 AS2 (eor,%B0,%A0));
3015 break; /* 10 */
3017 case 6:
3018 if (optimize_size)
3019 break; /* scratch ? 5 : 6 */
3020 *len = 9;
3021 return (AS1 (clr,__tmp_reg__) CR_TAB
3022 AS1 (lsr,%B0) CR_TAB
3023 AS1 (ror,%A0) CR_TAB
3024 AS1 (ror,__tmp_reg__) CR_TAB
3025 AS1 (lsr,%B0) CR_TAB
3026 AS1 (ror,%A0) CR_TAB
3027 AS1 (ror,__tmp_reg__) CR_TAB
3028 AS2 (mov,%B0,%A0) CR_TAB
3029 AS2 (mov,%A0,__tmp_reg__));
3031 case 7:
3032 *len = 5;
3033 return (AS1 (lsr,%B0) CR_TAB
3034 AS2 (mov,%B0,%A0) CR_TAB
3035 AS1 (clr,%A0) CR_TAB
3036 AS1 (ror,%B0) CR_TAB
3037 AS1 (ror,%A0));
3039 case 8:
3040 if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
3041 return *len = 1, AS1 (clr,%A0);
3042 else
3043 return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3044 AS1 (clr,%A0));
3046 case 9:
3047 *len = 3;
3048 return (AS2 (mov,%B0,%A0) CR_TAB
3049 AS1 (clr,%A0) CR_TAB
3050 AS1 (lsl,%B0));
3052 case 10:
3053 *len = 4;
3054 return (AS2 (mov,%B0,%A0) CR_TAB
3055 AS1 (clr,%A0) CR_TAB
3056 AS1 (lsl,%B0) CR_TAB
3057 AS1 (lsl,%B0));
3059 case 11:
3060 *len = 5;
3061 return (AS2 (mov,%B0,%A0) CR_TAB
3062 AS1 (clr,%A0) CR_TAB
3063 AS1 (lsl,%B0) CR_TAB
3064 AS1 (lsl,%B0) CR_TAB
3065 AS1 (lsl,%B0));
3067 case 12:
3068 if (ldi_ok)
3070 *len = 4;
3071 return (AS2 (mov,%B0,%A0) CR_TAB
3072 AS1 (clr,%A0) CR_TAB
3073 AS1 (swap,%B0) CR_TAB
3074 AS2 (andi,%B0,0xf0));
3076 if (scratch)
3078 *len = 5;
3079 return (AS2 (mov,%B0,%A0) CR_TAB
3080 AS1 (clr,%A0) CR_TAB
3081 AS1 (swap,%B0) CR_TAB
3082 AS2 (ldi,%3,0xf0) CR_TAB
3083 AS2 (and,%B0,%3));
3085 *len = 6;
3086 return (AS2 (mov,%B0,%A0) CR_TAB
3087 AS1 (clr,%A0) CR_TAB
3088 AS1 (lsl,%B0) CR_TAB
3089 AS1 (lsl,%B0) CR_TAB
3090 AS1 (lsl,%B0) CR_TAB
3091 AS1 (lsl,%B0));
3093 case 13:
3094 if (ldi_ok)
3096 *len = 5;
3097 return (AS2 (mov,%B0,%A0) CR_TAB
3098 AS1 (clr,%A0) CR_TAB
3099 AS1 (swap,%B0) CR_TAB
3100 AS1 (lsl,%B0) CR_TAB
3101 AS2 (andi,%B0,0xe0));
3103 if (AVR_ENHANCED && scratch)
3105 *len = 5;
3106 return (AS2 (ldi,%3,0x20) CR_TAB
3107 AS2 (mul,%A0,%3) CR_TAB
3108 AS2 (mov,%B0,r0) CR_TAB
3109 AS1 (clr,%A0) CR_TAB
3110 AS1 (clr,__zero_reg__));
3112 if (optimize_size && scratch)
3113 break; /* 5 */
3114 if (scratch)
3116 *len = 6;
3117 return (AS2 (mov,%B0,%A0) CR_TAB
3118 AS1 (clr,%A0) CR_TAB
3119 AS1 (swap,%B0) CR_TAB
3120 AS1 (lsl,%B0) CR_TAB
3121 AS2 (ldi,%3,0xe0) CR_TAB
3122 AS2 (and,%B0,%3));
3124 if (AVR_ENHANCED)
3126 *len = 6;
3127 return ("set" CR_TAB
3128 AS2 (bld,r1,5) CR_TAB
3129 AS2 (mul,%A0,r1) CR_TAB
3130 AS2 (mov,%B0,r0) CR_TAB
3131 AS1 (clr,%A0) CR_TAB
3132 AS1 (clr,__zero_reg__));
3134 *len = 7;
3135 return (AS2 (mov,%B0,%A0) CR_TAB
3136 AS1 (clr,%A0) CR_TAB
3137 AS1 (lsl,%B0) CR_TAB
3138 AS1 (lsl,%B0) CR_TAB
3139 AS1 (lsl,%B0) CR_TAB
3140 AS1 (lsl,%B0) CR_TAB
3141 AS1 (lsl,%B0));
3143 case 14:
3144 if (AVR_ENHANCED && ldi_ok)
3146 *len = 5;
3147 return (AS2 (ldi,%B0,0x40) CR_TAB
3148 AS2 (mul,%A0,%B0) CR_TAB
3149 AS2 (mov,%B0,r0) CR_TAB
3150 AS1 (clr,%A0) CR_TAB
3151 AS1 (clr,__zero_reg__));
3153 if (AVR_ENHANCED && scratch)
3155 *len = 5;
3156 return (AS2 (ldi,%3,0x40) CR_TAB
3157 AS2 (mul,%A0,%3) CR_TAB
3158 AS2 (mov,%B0,r0) CR_TAB
3159 AS1 (clr,%A0) CR_TAB
3160 AS1 (clr,__zero_reg__));
3162 if (optimize_size && ldi_ok)
3164 *len = 5;
3165 return (AS2 (mov,%B0,%A0) CR_TAB
3166 AS2 (ldi,%A0,6) "\n1:\t"
3167 AS1 (lsl,%B0) CR_TAB
3168 AS1 (dec,%A0) CR_TAB
3169 AS1 (brne,1b));
3171 if (optimize_size && scratch)
3172 break; /* 5 */
3173 *len = 6;
3174 return (AS1 (clr,%B0) CR_TAB
3175 AS1 (lsr,%A0) CR_TAB
3176 AS1 (ror,%B0) CR_TAB
3177 AS1 (lsr,%A0) CR_TAB
3178 AS1 (ror,%B0) CR_TAB
3179 AS1 (clr,%A0));
3181 case 15:
3182 *len = 4;
3183 return (AS1 (clr,%B0) CR_TAB
3184 AS1 (lsr,%A0) CR_TAB
3185 AS1 (ror,%B0) CR_TAB
3186 AS1 (clr,%A0));
3188 len = t;
3190 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3191 AS1 (rol,%B0)),
3192 insn, operands, len, 2);
3193 return "";
3197 /* 32bit shift left ((long)x << i) */
3199 const char *
3200 ashlsi3_out (rtx insn, rtx operands[], int *len)
3202 if (GET_CODE (operands[2]) == CONST_INT)
3204 int k;
3205 int *t = len;
3207 if (!len)
3208 len = &k;
3210 switch (INTVAL (operands[2]))
3212 case 8:
3214 int reg0 = true_regnum (operands[0]);
3215 int reg1 = true_regnum (operands[1]);
3216 *len = 4;
3217 if (reg0 >= reg1)
3218 return (AS2 (mov,%D0,%C1) CR_TAB
3219 AS2 (mov,%C0,%B1) CR_TAB
3220 AS2 (mov,%B0,%A1) CR_TAB
3221 AS1 (clr,%A0));
3222 else if (reg0 + 1 == reg1)
3224 *len = 1;
3225 return AS1 (clr,%A0);
3227 else
3228 return (AS1 (clr,%A0) CR_TAB
3229 AS2 (mov,%B0,%A1) CR_TAB
3230 AS2 (mov,%C0,%B1) CR_TAB
3231 AS2 (mov,%D0,%C1));
3234 case 16:
3236 int reg0 = true_regnum (operands[0]);
3237 int reg1 = true_regnum (operands[1]);
3238 *len = 4;
3239 if (AVR_ENHANCED && (reg0 + 2 != reg1))
3241 *len = 3;
3242 return (AS2 (movw,%C0,%A1) CR_TAB
3243 AS1 (clr,%B0) CR_TAB
3244 AS1 (clr,%A0));
3246 if (reg0 + 1 >= reg1)
3247 return (AS2 (mov,%D0,%B1) CR_TAB
3248 AS2 (mov,%C0,%A1) CR_TAB
3249 AS1 (clr,%B0) CR_TAB
3250 AS1 (clr,%A0));
3251 if (reg0 + 2 == reg1)
3253 *len = 2;
3254 return (AS1 (clr,%B0) CR_TAB
3255 AS1 (clr,%A0));
3257 else
3258 return (AS2 (mov,%C0,%A1) CR_TAB
3259 AS2 (mov,%D0,%B1) CR_TAB
3260 AS1 (clr,%B0) CR_TAB
3261 AS1 (clr,%A0));
3264 case 24:
3265 *len = 4;
3266 if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
3267 return (AS2 (mov,%D0,%A1) CR_TAB
3268 AS1 (clr,%C0) CR_TAB
3269 AS1 (clr,%B0) CR_TAB
3270 AS1 (clr,%A0));
3271 else
3273 *len = 3;
3274 return (AS1 (clr,%C0) CR_TAB
3275 AS1 (clr,%B0) CR_TAB
3276 AS1 (clr,%A0));
3279 case 31:
3280 *len = 6;
3281 return (AS1 (clr,%D0) CR_TAB
3282 AS1 (lsr,%A0) CR_TAB
3283 AS1 (ror,%D0) CR_TAB
3284 AS1 (clr,%C0) CR_TAB
3285 AS1 (clr,%B0) CR_TAB
3286 AS1 (clr,%A0));
3288 len = t;
3290 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3291 AS1 (rol,%B0) CR_TAB
3292 AS1 (rol,%C0) CR_TAB
3293 AS1 (rol,%D0)),
3294 insn, operands, len, 4);
3295 return "";
3298 /* 8bit arithmetic shift right ((signed char)x >> i) */
3300 const char *
3301 ashrqi3_out (rtx insn, rtx operands[], int *len)
3303 if (GET_CODE (operands[2]) == CONST_INT)
3305 int k;
3307 if (!len)
3308 len = &k;
3310 switch (INTVAL (operands[2]))
3312 case 1:
3313 *len = 1;
3314 return AS1 (asr,%0);
3316 case 2:
3317 *len = 2;
3318 return (AS1 (asr,%0) CR_TAB
3319 AS1 (asr,%0));
3321 case 3:
3322 *len = 3;
3323 return (AS1 (asr,%0) CR_TAB
3324 AS1 (asr,%0) CR_TAB
3325 AS1 (asr,%0));
3327 case 4:
3328 *len = 4;
3329 return (AS1 (asr,%0) CR_TAB
3330 AS1 (asr,%0) CR_TAB
3331 AS1 (asr,%0) CR_TAB
3332 AS1 (asr,%0));
3334 case 5:
3335 *len = 5;
3336 return (AS1 (asr,%0) CR_TAB
3337 AS1 (asr,%0) CR_TAB
3338 AS1 (asr,%0) CR_TAB
3339 AS1 (asr,%0) CR_TAB
3340 AS1 (asr,%0));
3342 case 6:
3343 *len = 4;
3344 return (AS2 (bst,%0,6) CR_TAB
3345 AS1 (lsl,%0) CR_TAB
3346 AS2 (sbc,%0,%0) CR_TAB
3347 AS2 (bld,%0,0));
3349 default:
3350 case 7:
3351 *len = 2;
3352 return (AS1 (lsl,%0) CR_TAB
3353 AS2 (sbc,%0,%0));
3356 else if (CONSTANT_P (operands[2]))
3357 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3359 out_shift_with_cnt (AS1 (asr,%0),
3360 insn, operands, len, 1);
3361 return "";
3365 /* 16bit arithmetic shift right ((signed short)x >> i) */
3367 const char *
3368 ashrhi3_out (rtx insn, rtx operands[], int *len)
3370 if (GET_CODE (operands[2]) == CONST_INT)
3372 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3373 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3374 int k;
3375 int *t = len;
3377 if (!len)
3378 len = &k;
3380 switch (INTVAL (operands[2]))
3382 case 4:
3383 case 5:
3384 /* XXX try to optimize this too? */
3385 break;
3387 case 6:
3388 if (optimize_size)
3389 break; /* scratch ? 5 : 6 */
3390 *len = 8;
3391 return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3392 AS2 (mov,%A0,%B0) CR_TAB
3393 AS1 (lsl,__tmp_reg__) CR_TAB
3394 AS1 (rol,%A0) CR_TAB
3395 AS2 (sbc,%B0,%B0) CR_TAB
3396 AS1 (lsl,__tmp_reg__) CR_TAB
3397 AS1 (rol,%A0) CR_TAB
3398 AS1 (rol,%B0));
3400 case 7:
3401 *len = 4;
3402 return (AS1 (lsl,%A0) CR_TAB
3403 AS2 (mov,%A0,%B0) CR_TAB
3404 AS1 (rol,%A0) CR_TAB
3405 AS2 (sbc,%B0,%B0));
3407 case 8:
3409 int reg0 = true_regnum (operands[0]);
3410 int reg1 = true_regnum (operands[1]);
3412 if (reg0 == reg1)
3413 return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3414 AS1 (lsl,%B0) CR_TAB
3415 AS2 (sbc,%B0,%B0));
3416 else if (reg0 == reg1 + 1)
3417 return *len = 3, (AS1 (clr,%B0) CR_TAB
3418 AS2 (sbrc,%A0,7) CR_TAB
3419 AS1 (dec,%B0));
3421 return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3422 AS1 (clr,%B0) CR_TAB
3423 AS2 (sbrc,%A0,7) CR_TAB
3424 AS1 (dec,%B0));
3427 case 9:
3428 *len = 4;
3429 return (AS2 (mov,%A0,%B0) CR_TAB
3430 AS1 (lsl,%B0) CR_TAB
3431 AS2 (sbc,%B0,%B0) CR_TAB
3432 AS1 (asr,%A0));
3434 case 10:
3435 *len = 5;
3436 return (AS2 (mov,%A0,%B0) CR_TAB
3437 AS1 (lsl,%B0) CR_TAB
3438 AS2 (sbc,%B0,%B0) CR_TAB
3439 AS1 (asr,%A0) CR_TAB
3440 AS1 (asr,%A0));
3442 case 11:
3443 if (AVR_ENHANCED && ldi_ok)
3445 *len = 5;
3446 return (AS2 (ldi,%A0,0x20) CR_TAB
3447 AS2 (muls,%B0,%A0) CR_TAB
3448 AS2 (mov,%A0,r1) CR_TAB
3449 AS2 (sbc,%B0,%B0) CR_TAB
3450 AS1 (clr,__zero_reg__));
3452 if (optimize_size && scratch)
3453 break; /* 5 */
3454 *len = 6;
3455 return (AS2 (mov,%A0,%B0) CR_TAB
3456 AS1 (lsl,%B0) CR_TAB
3457 AS2 (sbc,%B0,%B0) CR_TAB
3458 AS1 (asr,%A0) CR_TAB
3459 AS1 (asr,%A0) CR_TAB
3460 AS1 (asr,%A0));
3462 case 12:
3463 if (AVR_ENHANCED && ldi_ok)
3465 *len = 5;
3466 return (AS2 (ldi,%A0,0x10) CR_TAB
3467 AS2 (muls,%B0,%A0) CR_TAB
3468 AS2 (mov,%A0,r1) CR_TAB
3469 AS2 (sbc,%B0,%B0) CR_TAB
3470 AS1 (clr,__zero_reg__));
3472 if (optimize_size && scratch)
3473 break; /* 5 */
3474 *len = 7;
3475 return (AS2 (mov,%A0,%B0) CR_TAB
3476 AS1 (lsl,%B0) CR_TAB
3477 AS2 (sbc,%B0,%B0) CR_TAB
3478 AS1 (asr,%A0) CR_TAB
3479 AS1 (asr,%A0) CR_TAB
3480 AS1 (asr,%A0) CR_TAB
3481 AS1 (asr,%A0));
3483 case 13:
3484 if (AVR_ENHANCED && ldi_ok)
3486 *len = 5;
3487 return (AS2 (ldi,%A0,0x08) CR_TAB
3488 AS2 (muls,%B0,%A0) CR_TAB
3489 AS2 (mov,%A0,r1) CR_TAB
3490 AS2 (sbc,%B0,%B0) CR_TAB
3491 AS1 (clr,__zero_reg__));
3493 if (optimize_size)
3494 break; /* scratch ? 5 : 7 */
3495 *len = 8;
3496 return (AS2 (mov,%A0,%B0) CR_TAB
3497 AS1 (lsl,%B0) CR_TAB
3498 AS2 (sbc,%B0,%B0) CR_TAB
3499 AS1 (asr,%A0) CR_TAB
3500 AS1 (asr,%A0) CR_TAB
3501 AS1 (asr,%A0) CR_TAB
3502 AS1 (asr,%A0) CR_TAB
3503 AS1 (asr,%A0));
3505 case 14:
3506 *len = 5;
3507 return (AS1 (lsl,%B0) CR_TAB
3508 AS2 (sbc,%A0,%A0) CR_TAB
3509 AS1 (lsl,%B0) CR_TAB
3510 AS2 (mov,%B0,%A0) CR_TAB
3511 AS1 (rol,%A0));
3513 case 15:
3514 return *len = 3, (AS1 (lsl,%B0) CR_TAB
3515 AS2 (sbc,%A0,%A0) CR_TAB
3516 AS2 (mov,%B0,%A0));
3518 len = t;
3520 out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3521 AS1 (ror,%A0)),
3522 insn, operands, len, 2);
3523 return "";
3527 /* 32bit arithmetic shift right ((signed long)x >> i) */
3529 const char *
3530 ashrsi3_out (rtx insn, rtx operands[], int *len)
3532 if (GET_CODE (operands[2]) == CONST_INT)
3534 int k;
3535 int *t = len;
3537 if (!len)
3538 len = &k;
3540 switch (INTVAL (operands[2]))
3542 case 8:
3544 int reg0 = true_regnum (operands[0]);
3545 int reg1 = true_regnum (operands[1]);
3546 *len=6;
3547 if (reg0 <= reg1)
3548 return (AS2 (mov,%A0,%B1) CR_TAB
3549 AS2 (mov,%B0,%C1) CR_TAB
3550 AS2 (mov,%C0,%D1) CR_TAB
3551 AS1 (clr,%D0) CR_TAB
3552 AS2 (sbrc,%C0,7) CR_TAB
3553 AS1 (dec,%D0));
3554 else if (reg0 == reg1 + 1)
3556 *len = 3;
3557 return (AS1 (clr,%D0) CR_TAB
3558 AS2 (sbrc,%C0,7) CR_TAB
3559 AS1 (dec,%D0));
3561 else
3562 return (AS1 (clr,%D0) CR_TAB
3563 AS2 (sbrc,%D1,7) CR_TAB
3564 AS1 (dec,%D0) CR_TAB
3565 AS2 (mov,%C0,%D1) CR_TAB
3566 AS2 (mov,%B0,%C1) CR_TAB
3567 AS2 (mov,%A0,%B1));
3570 case 16:
3572 int reg0 = true_regnum (operands[0]);
3573 int reg1 = true_regnum (operands[1]);
3574 *len=6;
3575 if (AVR_ENHANCED && (reg0 != reg1 + 2))
3577 *len = 5;
3578 return (AS2 (movw,%A0,%C1) CR_TAB
3579 AS1 (clr,%D0) CR_TAB
3580 AS2 (sbrc,%B0,7) CR_TAB
3581 AS1 (com,%D0) CR_TAB
3582 AS2 (mov,%C0,%D0));
3584 if (reg0 <= reg1 + 1)
3585 return (AS2 (mov,%A0,%C1) CR_TAB
3586 AS2 (mov,%B0,%D1) CR_TAB
3587 AS1 (clr,%D0) CR_TAB
3588 AS2 (sbrc,%B0,7) CR_TAB
3589 AS1 (com,%D0) CR_TAB
3590 AS2 (mov,%C0,%D0));
3591 else if (reg0 == reg1 + 2)
3592 return *len = 4, (AS1 (clr,%D0) CR_TAB
3593 AS2 (sbrc,%B0,7) CR_TAB
3594 AS1 (com,%D0) CR_TAB
3595 AS2 (mov,%C0,%D0));
3596 else
3597 return (AS2 (mov,%B0,%D1) CR_TAB
3598 AS2 (mov,%A0,%C1) CR_TAB
3599 AS1 (clr,%D0) CR_TAB
3600 AS2 (sbrc,%B0,7) CR_TAB
3601 AS1 (com,%D0) CR_TAB
3602 AS2 (mov,%C0,%D0));
3605 case 24:
3606 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3607 return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3608 AS1 (clr,%D0) CR_TAB
3609 AS2 (sbrc,%A0,7) CR_TAB
3610 AS1 (com,%D0) CR_TAB
3611 AS2 (mov,%B0,%D0) CR_TAB
3612 AS2 (mov,%C0,%D0));
3613 else
3614 return *len = 5, (AS1 (clr,%D0) CR_TAB
3615 AS2 (sbrc,%A0,7) CR_TAB
3616 AS1 (com,%D0) CR_TAB
3617 AS2 (mov,%B0,%D0) CR_TAB
3618 AS2 (mov,%C0,%D0));
3620 case 31:
3621 if (AVR_ENHANCED)
3622 return *len = 4, (AS1 (lsl,%D0) CR_TAB
3623 AS2 (sbc,%A0,%A0) CR_TAB
3624 AS2 (mov,%B0,%A0) CR_TAB
3625 AS2 (movw,%C0,%A0));
3626 else
3627 return *len = 5, (AS1 (lsl,%D0) CR_TAB
3628 AS2 (sbc,%A0,%A0) CR_TAB
3629 AS2 (mov,%B0,%A0) CR_TAB
3630 AS2 (mov,%C0,%A0) CR_TAB
3631 AS2 (mov,%D0,%A0));
3633 len = t;
3635 out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
3636 AS1 (ror,%C0) CR_TAB
3637 AS1 (ror,%B0) CR_TAB
3638 AS1 (ror,%A0)),
3639 insn, operands, len, 4);
3640 return "";
3643 /* 8bit logic shift right ((unsigned char)x >> i) */
3645 const char *
3646 lshrqi3_out (rtx insn, rtx operands[], int *len)
3648 if (GET_CODE (operands[2]) == CONST_INT)
3650 int k;
3652 if (!len)
3653 len = &k;
3655 switch (INTVAL (operands[2]))
3657 default:
3658 *len = 1;
3659 return AS1 (clr,%0);
3661 case 1:
3662 *len = 1;
3663 return AS1 (lsr,%0);
3665 case 2:
3666 *len = 2;
3667 return (AS1 (lsr,%0) CR_TAB
3668 AS1 (lsr,%0));
3669 case 3:
3670 *len = 3;
3671 return (AS1 (lsr,%0) CR_TAB
3672 AS1 (lsr,%0) CR_TAB
3673 AS1 (lsr,%0));
3675 case 4:
3676 if (test_hard_reg_class (LD_REGS, operands[0]))
3678 *len=2;
3679 return (AS1 (swap,%0) CR_TAB
3680 AS2 (andi,%0,0x0f));
3682 *len = 4;
3683 return (AS1 (lsr,%0) CR_TAB
3684 AS1 (lsr,%0) CR_TAB
3685 AS1 (lsr,%0) CR_TAB
3686 AS1 (lsr,%0));
3688 case 5:
3689 if (test_hard_reg_class (LD_REGS, operands[0]))
3691 *len = 3;
3692 return (AS1 (swap,%0) CR_TAB
3693 AS1 (lsr,%0) CR_TAB
3694 AS2 (andi,%0,0x7));
3696 *len = 5;
3697 return (AS1 (lsr,%0) CR_TAB
3698 AS1 (lsr,%0) CR_TAB
3699 AS1 (lsr,%0) CR_TAB
3700 AS1 (lsr,%0) CR_TAB
3701 AS1 (lsr,%0));
3703 case 6:
3704 if (test_hard_reg_class (LD_REGS, operands[0]))
3706 *len = 4;
3707 return (AS1 (swap,%0) CR_TAB
3708 AS1 (lsr,%0) CR_TAB
3709 AS1 (lsr,%0) CR_TAB
3710 AS2 (andi,%0,0x3));
3712 *len = 6;
3713 return (AS1 (lsr,%0) CR_TAB
3714 AS1 (lsr,%0) CR_TAB
3715 AS1 (lsr,%0) CR_TAB
3716 AS1 (lsr,%0) CR_TAB
3717 AS1 (lsr,%0) CR_TAB
3718 AS1 (lsr,%0));
3720 case 7:
3721 *len = 3;
3722 return (AS1 (rol,%0) CR_TAB
3723 AS1 (clr,%0) CR_TAB
3724 AS1 (rol,%0));
3727 else if (CONSTANT_P (operands[2]))
3728 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3730 out_shift_with_cnt (AS1 (lsr,%0),
3731 insn, operands, len, 1);
3732 return "";
3735 /* 16bit logic shift right ((unsigned short)x >> i) */
3737 const char *
3738 lshrhi3_out (rtx insn, rtx operands[], int *len)
3740 if (GET_CODE (operands[2]) == CONST_INT)
3742 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3743 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3744 int k;
3745 int *t = len;
3747 if (!len)
3748 len = &k;
3750 switch (INTVAL (operands[2]))
3752 case 4:
3753 if (optimize_size && scratch)
3754 break; /* 5 */
3755 if (ldi_ok)
3757 *len = 6;
3758 return (AS1 (swap,%B0) CR_TAB
3759 AS1 (swap,%A0) CR_TAB
3760 AS2 (andi,%A0,0x0f) CR_TAB
3761 AS2 (eor,%A0,%B0) CR_TAB
3762 AS2 (andi,%B0,0x0f) CR_TAB
3763 AS2 (eor,%A0,%B0));
3765 if (scratch)
3767 *len = 7;
3768 return (AS1 (swap,%B0) CR_TAB
3769 AS1 (swap,%A0) CR_TAB
3770 AS2 (ldi,%3,0x0f) CR_TAB
3771 AS2 (and,%A0,%3) CR_TAB
3772 AS2 (eor,%A0,%B0) CR_TAB
3773 AS2 (and,%B0,%3) CR_TAB
3774 AS2 (eor,%A0,%B0));
3776 break; /* optimize_size ? 6 : 8 */
3778 case 5:
3779 if (optimize_size)
3780 break; /* scratch ? 5 : 6 */
3781 if (ldi_ok)
3783 *len = 8;
3784 return (AS1 (lsr,%B0) CR_TAB
3785 AS1 (ror,%A0) CR_TAB
3786 AS1 (swap,%B0) CR_TAB
3787 AS1 (swap,%A0) CR_TAB
3788 AS2 (andi,%A0,0x0f) CR_TAB
3789 AS2 (eor,%A0,%B0) CR_TAB
3790 AS2 (andi,%B0,0x0f) CR_TAB
3791 AS2 (eor,%A0,%B0));
3793 if (scratch)
3795 *len = 9;
3796 return (AS1 (lsr,%B0) CR_TAB
3797 AS1 (ror,%A0) CR_TAB
3798 AS1 (swap,%B0) CR_TAB
3799 AS1 (swap,%A0) CR_TAB
3800 AS2 (ldi,%3,0x0f) CR_TAB
3801 AS2 (and,%A0,%3) CR_TAB
3802 AS2 (eor,%A0,%B0) CR_TAB
3803 AS2 (and,%B0,%3) CR_TAB
3804 AS2 (eor,%A0,%B0));
3806 break; /* 10 */
3808 case 6:
3809 if (optimize_size)
3810 break; /* scratch ? 5 : 6 */
3811 *len = 9;
3812 return (AS1 (clr,__tmp_reg__) CR_TAB
3813 AS1 (lsl,%A0) CR_TAB
3814 AS1 (rol,%B0) CR_TAB
3815 AS1 (rol,__tmp_reg__) CR_TAB
3816 AS1 (lsl,%A0) CR_TAB
3817 AS1 (rol,%B0) CR_TAB
3818 AS1 (rol,__tmp_reg__) CR_TAB
3819 AS2 (mov,%A0,%B0) CR_TAB
3820 AS2 (mov,%B0,__tmp_reg__));
3822 case 7:
3823 *len = 5;
3824 return (AS1 (lsl,%A0) CR_TAB
3825 AS2 (mov,%A0,%B0) CR_TAB
3826 AS1 (rol,%A0) CR_TAB
3827 AS2 (sbc,%B0,%B0) CR_TAB
3828 AS1 (neg,%B0));
3830 case 8:
3831 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
3832 return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
3833 AS1 (clr,%B0));
3834 else
3835 return *len = 1, AS1 (clr,%B0);
3837 case 9:
3838 *len = 3;
3839 return (AS2 (mov,%A0,%B0) CR_TAB
3840 AS1 (clr,%B0) CR_TAB
3841 AS1 (lsr,%A0));
3843 case 10:
3844 *len = 4;
3845 return (AS2 (mov,%A0,%B0) CR_TAB
3846 AS1 (clr,%B0) CR_TAB
3847 AS1 (lsr,%A0) CR_TAB
3848 AS1 (lsr,%A0));
3850 case 11:
3851 *len = 5;
3852 return (AS2 (mov,%A0,%B0) CR_TAB
3853 AS1 (clr,%B0) CR_TAB
3854 AS1 (lsr,%A0) CR_TAB
3855 AS1 (lsr,%A0) CR_TAB
3856 AS1 (lsr,%A0));
3858 case 12:
3859 if (ldi_ok)
3861 *len = 4;
3862 return (AS2 (mov,%A0,%B0) CR_TAB
3863 AS1 (clr,%B0) CR_TAB
3864 AS1 (swap,%A0) CR_TAB
3865 AS2 (andi,%A0,0x0f));
3867 if (scratch)
3869 *len = 5;
3870 return (AS2 (mov,%A0,%B0) CR_TAB
3871 AS1 (clr,%B0) CR_TAB
3872 AS1 (swap,%A0) CR_TAB
3873 AS2 (ldi,%3,0x0f) CR_TAB
3874 AS2 (and,%A0,%3));
3876 *len = 6;
3877 return (AS2 (mov,%A0,%B0) CR_TAB
3878 AS1 (clr,%B0) CR_TAB
3879 AS1 (lsr,%A0) CR_TAB
3880 AS1 (lsr,%A0) CR_TAB
3881 AS1 (lsr,%A0) CR_TAB
3882 AS1 (lsr,%A0));
3884 case 13:
3885 if (ldi_ok)
3887 *len = 5;
3888 return (AS2 (mov,%A0,%B0) CR_TAB
3889 AS1 (clr,%B0) CR_TAB
3890 AS1 (swap,%A0) CR_TAB
3891 AS1 (lsr,%A0) CR_TAB
3892 AS2 (andi,%A0,0x07));
3894 if (AVR_ENHANCED && scratch)
3896 *len = 5;
3897 return (AS2 (ldi,%3,0x08) CR_TAB
3898 AS2 (mul,%B0,%3) CR_TAB
3899 AS2 (mov,%A0,r1) CR_TAB
3900 AS1 (clr,%B0) CR_TAB
3901 AS1 (clr,__zero_reg__));
3903 if (optimize_size && scratch)
3904 break; /* 5 */
3905 if (scratch)
3907 *len = 6;
3908 return (AS2 (mov,%A0,%B0) CR_TAB
3909 AS1 (clr,%B0) CR_TAB
3910 AS1 (swap,%A0) CR_TAB
3911 AS1 (lsr,%A0) CR_TAB
3912 AS2 (ldi,%3,0x07) CR_TAB
3913 AS2 (and,%A0,%3));
3915 if (AVR_ENHANCED)
3917 *len = 6;
3918 return ("set" CR_TAB
3919 AS2 (bld,r1,3) CR_TAB
3920 AS2 (mul,%B0,r1) CR_TAB
3921 AS2 (mov,%A0,r1) CR_TAB
3922 AS1 (clr,%B0) CR_TAB
3923 AS1 (clr,__zero_reg__));
3925 *len = 7;
3926 return (AS2 (mov,%A0,%B0) CR_TAB
3927 AS1 (clr,%B0) CR_TAB
3928 AS1 (lsr,%A0) CR_TAB
3929 AS1 (lsr,%A0) CR_TAB
3930 AS1 (lsr,%A0) CR_TAB
3931 AS1 (lsr,%A0) CR_TAB
3932 AS1 (lsr,%A0));
3934 case 14:
3935 if (AVR_ENHANCED && ldi_ok)
3937 *len = 5;
3938 return (AS2 (ldi,%A0,0x04) CR_TAB
3939 AS2 (mul,%B0,%A0) CR_TAB
3940 AS2 (mov,%A0,r1) CR_TAB
3941 AS1 (clr,%B0) CR_TAB
3942 AS1 (clr,__zero_reg__));
3944 if (AVR_ENHANCED && scratch)
3946 *len = 5;
3947 return (AS2 (ldi,%3,0x04) CR_TAB
3948 AS2 (mul,%B0,%3) CR_TAB
3949 AS2 (mov,%A0,r1) CR_TAB
3950 AS1 (clr,%B0) CR_TAB
3951 AS1 (clr,__zero_reg__));
3953 if (optimize_size && ldi_ok)
3955 *len = 5;
3956 return (AS2 (mov,%A0,%B0) CR_TAB
3957 AS2 (ldi,%B0,6) "\n1:\t"
3958 AS1 (lsr,%A0) CR_TAB
3959 AS1 (dec,%B0) CR_TAB
3960 AS1 (brne,1b));
3962 if (optimize_size && scratch)
3963 break; /* 5 */
3964 *len = 6;
3965 return (AS1 (clr,%A0) CR_TAB
3966 AS1 (lsl,%B0) CR_TAB
3967 AS1 (rol,%A0) CR_TAB
3968 AS1 (lsl,%B0) CR_TAB
3969 AS1 (rol,%A0) CR_TAB
3970 AS1 (clr,%B0));
3972 case 15:
3973 *len = 4;
3974 return (AS1 (clr,%A0) CR_TAB
3975 AS1 (lsl,%B0) CR_TAB
3976 AS1 (rol,%A0) CR_TAB
3977 AS1 (clr,%B0));
3979 len = t;
3981 out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
3982 AS1 (ror,%A0)),
3983 insn, operands, len, 2);
3984 return "";
3987 /* 32bit logic shift right ((unsigned int)x >> i) */
3989 const char *
3990 lshrsi3_out (rtx insn, rtx operands[], int *len)
3992 if (GET_CODE (operands[2]) == CONST_INT)
3994 int k;
3995 int *t = len;
3997 if (!len)
3998 len = &k;
4000 switch (INTVAL (operands[2]))
4002 case 8:
4004 int reg0 = true_regnum (operands[0]);
4005 int reg1 = true_regnum (operands[1]);
4006 *len = 4;
4007 if (reg0 <= reg1)
4008 return (AS2 (mov,%A0,%B1) CR_TAB
4009 AS2 (mov,%B0,%C1) CR_TAB
4010 AS2 (mov,%C0,%D1) CR_TAB
4011 AS1 (clr,%D0));
4012 else if (reg0 == reg1 + 1)
4013 return *len = 1, AS1 (clr,%D0);
4014 else
4015 return (AS1 (clr,%D0) CR_TAB
4016 AS2 (mov,%C0,%D1) CR_TAB
4017 AS2 (mov,%B0,%C1) CR_TAB
4018 AS2 (mov,%A0,%B1));
4021 case 16:
4023 int reg0 = true_regnum (operands[0]);
4024 int reg1 = true_regnum (operands[1]);
4025 *len = 4;
4026 if (AVR_ENHANCED && (reg0 != reg1 + 2))
4028 *len = 3;
4029 return (AS2 (movw,%A0,%C1) CR_TAB
4030 AS1 (clr,%C0) CR_TAB
4031 AS1 (clr,%D0));
4033 if (reg0 <= reg1 + 1)
4034 return (AS2 (mov,%A0,%C1) CR_TAB
4035 AS2 (mov,%B0,%D1) CR_TAB
4036 AS1 (clr,%C0) CR_TAB
4037 AS1 (clr,%D0));
4038 else if (reg0 == reg1 + 2)
4039 return *len = 2, (AS1 (clr,%C0) CR_TAB
4040 AS1 (clr,%D0));
4041 else
4042 return (AS2 (mov,%B0,%D1) CR_TAB
4043 AS2 (mov,%A0,%C1) CR_TAB
4044 AS1 (clr,%C0) CR_TAB
4045 AS1 (clr,%D0));
4048 case 24:
4049 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
4050 return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4051 AS1 (clr,%B0) CR_TAB
4052 AS1 (clr,%C0) CR_TAB
4053 AS1 (clr,%D0));
4054 else
4055 return *len = 3, (AS1 (clr,%B0) CR_TAB
4056 AS1 (clr,%C0) CR_TAB
4057 AS1 (clr,%D0));
4059 case 31:
4060 *len = 6;
4061 return (AS1 (clr,%A0) CR_TAB
4062 AS2 (sbrc,%D0,7) CR_TAB
4063 AS1 (inc,%A0) CR_TAB
4064 AS1 (clr,%B0) CR_TAB
4065 AS1 (clr,%C0) CR_TAB
4066 AS1 (clr,%D0));
4068 len = t;
4070 out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4071 AS1 (ror,%C0) CR_TAB
4072 AS1 (ror,%B0) CR_TAB
4073 AS1 (ror,%A0)),
4074 insn, operands, len, 4);
4075 return "";
4078 /* Modifies the length assigned to instruction INSN
4079 LEN is the initially computed length of the insn. */
4082 adjust_insn_length (rtx insn, int len)
4084 rtx patt = PATTERN (insn);
4085 rtx set;
4087 if (GET_CODE (patt) == SET)
4089 rtx op[10];
4090 op[1] = SET_SRC (patt);
4091 op[0] = SET_DEST (patt);
4092 if (general_operand (op[1], VOIDmode)
4093 && general_operand (op[0], VOIDmode))
4095 switch (GET_MODE (op[0]))
4097 case QImode:
4098 output_movqi (insn, op, &len);
4099 break;
4100 case HImode:
4101 output_movhi (insn, op, &len);
4102 break;
4103 case SImode:
4104 case SFmode:
4105 output_movsisf (insn, op, &len);
4106 break;
4107 default:
4108 break;
4111 else if (op[0] == cc0_rtx && REG_P (op[1]))
4113 switch (GET_MODE (op[1]))
4115 case HImode: out_tsthi (insn,&len); break;
4116 case SImode: out_tstsi (insn,&len); break;
4117 default: break;
4120 else if (GET_CODE (op[1]) == AND)
4122 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4124 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4125 if (GET_MODE (op[1]) == SImode)
4126 len = (((mask & 0xff) != 0xff)
4127 + ((mask & 0xff00) != 0xff00)
4128 + ((mask & 0xff0000L) != 0xff0000L)
4129 + ((mask & 0xff000000L) != 0xff000000L));
4130 else if (GET_MODE (op[1]) == HImode)
4131 len = (((mask & 0xff) != 0xff)
4132 + ((mask & 0xff00) != 0xff00));
4135 else if (GET_CODE (op[1]) == IOR)
4137 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4139 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4140 if (GET_MODE (op[1]) == SImode)
4141 len = (((mask & 0xff) != 0)
4142 + ((mask & 0xff00) != 0)
4143 + ((mask & 0xff0000L) != 0)
4144 + ((mask & 0xff000000L) != 0));
4145 else if (GET_MODE (op[1]) == HImode)
4146 len = (((mask & 0xff) != 0)
4147 + ((mask & 0xff00) != 0));
4151 set = single_set (insn);
4152 if (set)
4154 rtx op[10];
4156 op[1] = SET_SRC (set);
4157 op[0] = SET_DEST (set);
4159 if (GET_CODE (patt) == PARALLEL
4160 && general_operand (op[1], VOIDmode)
4161 && general_operand (op[0], VOIDmode))
4163 if (XVECLEN (patt, 0) == 2)
4164 op[2] = XVECEXP (patt, 0, 1);
4166 switch (GET_MODE (op[0]))
4168 case QImode:
4169 len = 2;
4170 break;
4171 case HImode:
4172 output_reload_inhi (insn, op, &len);
4173 break;
4174 case SImode:
4175 case SFmode:
4176 output_reload_insisf (insn, op, &len);
4177 break;
4178 default:
4179 break;
4182 else if (GET_CODE (op[1]) == ASHIFT
4183 || GET_CODE (op[1]) == ASHIFTRT
4184 || GET_CODE (op[1]) == LSHIFTRT)
4186 rtx ops[10];
4187 ops[0] = op[0];
4188 ops[1] = XEXP (op[1],0);
4189 ops[2] = XEXP (op[1],1);
4190 switch (GET_CODE (op[1]))
4192 case ASHIFT:
4193 switch (GET_MODE (op[0]))
4195 case QImode: ashlqi3_out (insn,ops,&len); break;
4196 case HImode: ashlhi3_out (insn,ops,&len); break;
4197 case SImode: ashlsi3_out (insn,ops,&len); break;
4198 default: break;
4200 break;
4201 case ASHIFTRT:
4202 switch (GET_MODE (op[0]))
4204 case QImode: ashrqi3_out (insn,ops,&len); break;
4205 case HImode: ashrhi3_out (insn,ops,&len); break;
4206 case SImode: ashrsi3_out (insn,ops,&len); break;
4207 default: break;
4209 break;
4210 case LSHIFTRT:
4211 switch (GET_MODE (op[0]))
4213 case QImode: lshrqi3_out (insn,ops,&len); break;
4214 case HImode: lshrhi3_out (insn,ops,&len); break;
4215 case SImode: lshrsi3_out (insn,ops,&len); break;
4216 default: break;
4218 break;
4219 default:
4220 break;
4224 return len;
4227 /* Return nonzero if register REG dead after INSN. */
4230 reg_unused_after (rtx insn, rtx reg)
4232 return (dead_or_set_p (insn, reg)
4233 || (REG_P(reg) && _reg_unused_after (insn, reg)));
4236 /* Return nonzero if REG is not used after INSN.
4237 We assume REG is a reload reg, and therefore does
4238 not live past labels. It may live past calls or jumps though. */
4241 _reg_unused_after (rtx insn, rtx reg)
4243 enum rtx_code code;
4244 rtx set;
4246 /* If the reg is set by this instruction, then it is safe for our
4247 case. Disregard the case where this is a store to memory, since
4248 we are checking a register used in the store address. */
4249 set = single_set (insn);
4250 if (set && GET_CODE (SET_DEST (set)) != MEM
4251 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4252 return 1;
4254 while ((insn = NEXT_INSN (insn)))
4256 code = GET_CODE (insn);
4258 #if 0
4259 /* If this is a label that existed before reload, then the register
4260 if dead here. However, if this is a label added by reorg, then
4261 the register may still be live here. We can't tell the difference,
4262 so we just ignore labels completely. */
4263 if (code == CODE_LABEL)
4264 return 1;
4265 /* else */
4266 #endif
4268 if (code == JUMP_INSN)
4269 return 0;
4271 /* If this is a sequence, we must handle them all at once.
4272 We could have for instance a call that sets the target register,
4273 and an insn in a delay slot that uses the register. In this case,
4274 we must return 0. */
4275 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
4277 int i;
4278 int retval = 0;
4280 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
4282 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
4283 rtx set = single_set (this_insn);
4285 if (GET_CODE (this_insn) == CALL_INSN)
4286 code = CALL_INSN;
4287 else if (GET_CODE (this_insn) == JUMP_INSN)
4289 if (INSN_ANNULLED_BRANCH_P (this_insn))
4290 return 0;
4291 code = JUMP_INSN;
4294 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4295 return 0;
4296 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4298 if (GET_CODE (SET_DEST (set)) != MEM)
4299 retval = 1;
4300 else
4301 return 0;
4303 if (set == 0
4304 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
4305 return 0;
4307 if (retval == 1)
4308 return 1;
4309 else if (code == JUMP_INSN)
4310 return 0;
4313 if (code == CALL_INSN)
4315 rtx tem;
4316 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4317 if (GET_CODE (XEXP (tem, 0)) == USE
4318 && REG_P (XEXP (XEXP (tem, 0), 0))
4319 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
4320 return 0;
4321 if (call_used_regs[REGNO (reg)])
4322 return 1;
4325 if (GET_RTX_CLASS (code) == 'i')
4327 rtx set = single_set (insn);
4329 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4330 return 0;
4331 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4332 return GET_CODE (SET_DEST (set)) != MEM;
4333 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
4334 return 0;
4337 return 1;
4340 /* Target hook for assembling integer objects. The AVR version needs
4341 special handling for references to certain labels. */
4343 static bool
4344 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
4346 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
4347 && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x))
4348 || GET_CODE (x) == LABEL_REF))
4350 fputs ("\t.word\tpm(", asm_out_file);
4351 output_addr_const (asm_out_file, x);
4352 fputs (")\n", asm_out_file);
4353 return true;
4355 return default_assemble_integer (x, size, aligned_p);
4358 /* Sets section name for declaration DECL. */
4360 static void
4361 avr_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
4363 int len;
4364 const char *name, *prefix;
4365 char *string;
4367 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
4368 name = (* targetm.strip_name_encoding) (name);
4370 if (TREE_CODE (decl) == FUNCTION_DECL)
4372 if (flag_function_sections)
4373 prefix = ".text.";
4374 else
4375 prefix = ".text";
4377 else
4378 abort ();
4380 if (flag_function_sections)
4382 len = strlen (name) + strlen (prefix);
4383 string = alloca (len + 1);
4384 sprintf (string, "%s%s", prefix, name);
4385 DECL_SECTION_NAME (decl) = build_string (len, string);
4390 /* The routine used to output NUL terminated strings. We use a special
4391 version of this for most svr4 targets because doing so makes the
4392 generated assembly code more compact (and thus faster to assemble)
4393 as well as more readable, especially for targets like the i386
4394 (where the only alternative is to output character sequences as
4395 comma separated lists of numbers). */
4397 void
4398 gas_output_limited_string(FILE *file, const char *str)
4400 const unsigned char *_limited_str = (unsigned char *) str;
4401 unsigned ch;
4402 fprintf (file, "%s\"", STRING_ASM_OP);
4403 for (; (ch = *_limited_str); _limited_str++)
4405 int escape;
4406 switch (escape = ESCAPES[ch])
4408 case 0:
4409 putc (ch, file);
4410 break;
4411 case 1:
4412 fprintf (file, "\\%03o", ch);
4413 break;
4414 default:
4415 putc ('\\', file);
4416 putc (escape, file);
4417 break;
4420 fprintf (file, "\"\n");
4423 /* The routine used to output sequences of byte values. We use a special
4424 version of this for most svr4 targets because doing so makes the
4425 generated assembly code more compact (and thus faster to assemble)
4426 as well as more readable. Note that if we find subparts of the
4427 character sequence which end with NUL (and which are shorter than
4428 STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
4430 void
4431 gas_output_ascii(FILE *file, const char *str, size_t length)
4433 const unsigned char *_ascii_bytes = (const unsigned char *) str;
4434 const unsigned char *limit = _ascii_bytes + length;
4435 unsigned bytes_in_chunk = 0;
4436 for (; _ascii_bytes < limit; _ascii_bytes++)
4438 const unsigned char *p;
4439 if (bytes_in_chunk >= 60)
4441 fprintf (file, "\"\n");
4442 bytes_in_chunk = 0;
4444 for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
4445 continue;
4446 if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
4448 if (bytes_in_chunk > 0)
4450 fprintf (file, "\"\n");
4451 bytes_in_chunk = 0;
4453 gas_output_limited_string (file, (char*)_ascii_bytes);
4454 _ascii_bytes = p;
4456 else
4458 int escape;
4459 unsigned ch;
4460 if (bytes_in_chunk == 0)
4461 fprintf (file, "\t.ascii\t\"");
4462 switch (escape = ESCAPES[ch = *_ascii_bytes])
4464 case 0:
4465 putc (ch, file);
4466 bytes_in_chunk++;
4467 break;
4468 case 1:
4469 fprintf (file, "\\%03o", ch);
4470 bytes_in_chunk += 4;
4471 break;
4472 default:
4473 putc ('\\', file);
4474 putc (escape, file);
4475 bytes_in_chunk += 2;
4476 break;
4480 if (bytes_in_chunk > 0)
4481 fprintf (file, "\"\n");
4484 /* Return value is nonzero if pseudos that have been
4485 assigned to registers of class CLASS would likely be spilled
4486 because registers of CLASS are needed for spill registers. */
4488 enum reg_class
4489 class_likely_spilled_p (int c)
4491 return (c != ALL_REGS && c != ADDW_REGS);
4494 /* Valid attributes:
4495 progmem - put data to program memory;
4496 signal - make a function to be hardware interrupt. After function
4497 prologue interrupts are disabled;
4498 interrupt - make a function to be hardware interrupt. After function
4499 prologue interrupts are enabled;
4500 naked - don't generate function prologue/epilogue and `ret' command.
4502 Only `progmem' attribute valid for type. */
4504 const struct attribute_spec avr_attribute_table[] =
4506 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
4507 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute },
4508 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4509 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4510 { "naked", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4511 { NULL, 0, 0, false, false, false, NULL }
4514 /* Handle a "progmem" attribute; arguments as in
4515 struct attribute_spec.handler. */
4516 static tree
4517 avr_handle_progmem_attribute (tree *node, tree name,
4518 tree args ATTRIBUTE_UNUSED,
4519 int flags ATTRIBUTE_UNUSED,
4520 bool *no_add_attrs)
4522 if (DECL_P (*node))
4524 if (TREE_CODE (*node) == TYPE_DECL)
4526 /* This is really a decl attribute, not a type attribute,
4527 but try to handle it for GCC 3.0 backwards compatibility. */
4529 tree type = TREE_TYPE (*node);
4530 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
4531 tree newtype = build_type_attribute_variant (type, attr);
4533 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
4534 TREE_TYPE (*node) = newtype;
4535 *no_add_attrs = true;
4537 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
4539 if (DECL_INITIAL (*node) == NULL_TREE && !DECL_EXTERNAL (*node))
4541 warning ("only initialized variables can be placed into "
4542 "program memory area");
4543 *no_add_attrs = true;
4546 else
4548 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
4549 *no_add_attrs = true;
4553 return NULL_TREE;
4556 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
4557 struct attribute_spec.handler. */
4559 static tree
4560 avr_handle_fndecl_attribute (tree *node, tree name,
4561 tree args ATTRIBUTE_UNUSED,
4562 int flags ATTRIBUTE_UNUSED,
4563 bool *no_add_attrs)
4565 if (TREE_CODE (*node) != FUNCTION_DECL)
4567 warning ("`%s' attribute only applies to functions",
4568 IDENTIFIER_POINTER (name));
4569 *no_add_attrs = true;
4572 return NULL_TREE;
4575 /* Look for attribute `progmem' in DECL
4576 if found return 1, otherwise 0. */
4579 avr_progmem_p (tree decl)
4581 tree a;
4583 if (TREE_CODE (decl) != VAR_DECL)
4584 return 0;
4586 if (NULL_TREE
4587 != lookup_attribute ("progmem", DECL_ATTRIBUTES (decl)))
4588 return 1;
4590 a=decl;
4592 a = TREE_TYPE(a);
4593 while (TREE_CODE (a) == ARRAY_TYPE);
4595 if (a == error_mark_node)
4596 return 0;
4598 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
4599 return 1;
4601 return 0;
4604 /* Add the section attribute if the variable is in progmem. */
4606 static void
4607 avr_insert_attributes (tree node, tree *attributes)
4609 if (TREE_CODE (node) == VAR_DECL
4610 && (TREE_STATIC (node) || DECL_EXTERNAL (node))
4611 && avr_progmem_p (node))
4613 static const char dsec[] = ".progmem.data";
4614 *attributes = tree_cons (get_identifier ("section"),
4615 build_tree_list (NULL, build_string (strlen (dsec), dsec)),
4616 *attributes);
4618 /* ??? This seems sketchy. Why can't the user declare the
4619 thing const in the first place? */
4620 TREE_READONLY (node) = 1;
4624 static unsigned int
4625 avr_section_type_flags (tree decl, const char *name, int reloc)
4627 unsigned int flags = default_section_type_flags (decl, name, reloc);
4629 if (strncmp (name, ".noinit", 7) == 0)
4631 if (decl && TREE_CODE (decl) == VAR_DECL
4632 && DECL_INITIAL (decl) == NULL_TREE)
4633 flags |= SECTION_BSS; /* @nobits */
4634 else
4635 warning ("only uninitialized variables can be placed in the "
4636 ".noinit section");
4639 return flags;
4642 /* Outputs some appropriate text to go at the start of an assembler
4643 file. */
4645 static void
4646 avr_file_start (void)
4648 if (avr_asm_only_p)
4649 error ("MCU `%s' supported for assembler only", avr_mcu_name);
4651 default_file_start ();
4653 fprintf (asm_out_file, "\t.arch %s\n", avr_mcu_name);
4654 fputs ("__SREG__ = 0x3f\n"
4655 "__SP_H__ = 0x3e\n"
4656 "__SP_L__ = 0x3d\n", asm_out_file);
4658 fputs ("__tmp_reg__ = 0\n"
4659 "__zero_reg__ = 1\n", asm_out_file);
4661 /* FIXME: output these only if there is anything in the .data / .bss
4662 sections - some code size could be saved by not linking in the
4663 initialization code from libgcc if one or both sections are empty. */
4664 fputs ("\t.global __do_copy_data\n", asm_out_file);
4665 fputs ("\t.global __do_clear_bss\n", asm_out_file);
4667 commands_in_file = 0;
4668 commands_in_prologues = 0;
4669 commands_in_epilogues = 0;
4672 /* Outputs to the stdio stream FILE some
4673 appropriate text to go at the end of an assembler file. */
4675 static void
4676 avr_file_end (void)
4678 fputs ("/* File ", asm_out_file);
4679 output_quoted_string (asm_out_file, main_input_filename);
4680 fprintf (asm_out_file,
4681 ": code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
4682 commands_in_file,
4683 commands_in_file,
4684 commands_in_file - commands_in_prologues - commands_in_epilogues,
4685 commands_in_prologues, commands_in_epilogues);
4688 /* Choose the order in which to allocate hard registers for
4689 pseudo-registers local to a basic block.
4691 Store the desired register order in the array `reg_alloc_order'.
4692 Element 0 should be the register to allocate first; element 1, the
4693 next register; and so on. */
4695 void
4696 order_regs_for_local_alloc (void)
4698 unsigned int i;
4699 static const int order_0[] = {
4700 24,25,
4701 18,19,
4702 20,21,
4703 22,23,
4704 30,31,
4705 26,27,
4706 28,29,
4707 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4708 0,1,
4709 32,33,34,35
4711 static const int order_1[] = {
4712 18,19,
4713 20,21,
4714 22,23,
4715 24,25,
4716 30,31,
4717 26,27,
4718 28,29,
4719 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4720 0,1,
4721 32,33,34,35
4723 static const int order_2[] = {
4724 25,24,
4725 23,22,
4726 21,20,
4727 19,18,
4728 30,31,
4729 26,27,
4730 28,29,
4731 17,16,
4732 15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4733 1,0,
4734 32,33,34,35
4737 const int *order = (TARGET_ORDER_1 ? order_1 :
4738 TARGET_ORDER_2 ? order_2 :
4739 order_0);
4740 for (i=0; i < ARRAY_SIZE (order_0); ++i)
4741 reg_alloc_order[i] = order[i];
4744 /* Calculate the cost of X code of the expression in which it is contained,
4745 found in OUTER_CODE */
4747 static int
4748 default_rtx_costs (rtx X, enum rtx_code code, enum rtx_code outer_code)
4750 int cost=0;
4751 switch (code)
4753 case SYMBOL_REF:
4754 case LABEL_REF:
4755 cost = 2 * GET_MODE_SIZE (GET_MODE (X));
4756 break;
4757 case MEM:
4758 if (outer_code != SET)
4759 cost = 1;
4760 if (GET_CODE (XEXP (X,0)) == SYMBOL_REF)
4761 cost += 2 * GET_MODE_SIZE (GET_MODE (X));
4762 else
4763 cost += GET_MODE_SIZE (GET_MODE (X));
4764 break;
4765 case CONST_INT:
4766 cost = 0;
4767 break;
4768 case SIGN_EXTEND:
4769 if (outer_code == SET)
4770 cost = GET_MODE_SIZE (GET_MODE (X));
4771 else
4772 cost = -GET_MODE_SIZE (GET_MODE (X));
4773 break;
4774 case ZERO_EXTEND:
4775 if (outer_code == SET)
4776 cost = GET_MODE_SIZE (GET_MODE (X));
4777 else
4778 cost = -1;
4779 break;
4780 case PLUS:
4781 case MINUS:
4782 if (outer_code == SET)
4784 if (X == stack_pointer_rtx)
4785 cost = -10;
4786 else if (GET_CODE (XEXP (X,1)) == CONST_INT)
4787 cost = (INTVAL (XEXP (X,1)) <= 63 ? 1 :
4788 GET_MODE_SIZE (GET_MODE (X)));
4789 else
4790 cost = GET_MODE_SIZE (GET_MODE (X));
4792 break;
4793 case COMPARE:
4794 if (GET_CODE (XEXP (X,1)) == CONST_INT)
4795 cost = GET_MODE_SIZE (GET_MODE (XEXP (X,0)));
4796 break;
4797 default:
4798 break;
4800 return cost;
4803 static bool
4804 avr_rtx_costs (rtx x, int code, int outer_code, int *total)
4806 int cst;
4808 switch (code)
4810 case CONST_INT:
4811 if (outer_code == PLUS
4812 || outer_code == IOR
4813 || outer_code == AND
4814 || outer_code == MINUS
4815 || outer_code == SET
4816 || INTVAL (x) == 0)
4818 *total = 2;
4819 return true;
4821 if (outer_code == COMPARE
4822 && INTVAL (x) >= 0
4823 && INTVAL (x) <= 255)
4825 *total = 2;
4826 return true;
4828 /* Fall through. */
4830 case CONST:
4831 case LABEL_REF:
4832 case SYMBOL_REF:
4833 case CONST_DOUBLE:
4834 *total = 4;
4835 return true;
4837 default:
4838 cst = default_rtx_costs (x, code, outer_code);
4839 if (cst > 0)
4841 *total = cst;
4842 return true;
4844 else if (cst < 0)
4845 *total += -cst;
4846 return false;
4850 /* Calculate the cost of a memory address. */
4852 static int
4853 avr_address_cost (rtx x)
4855 if (GET_CODE (x) == PLUS
4856 && GET_CODE (XEXP (x,1)) == CONST_INT
4857 && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
4858 && INTVAL (XEXP (x,1)) >= 61)
4859 return 18;
4860 if (CONSTANT_ADDRESS_P (x))
4862 if (avr_io_address_p (x, 1))
4863 return 2;
4864 return 4;
4866 return 4;
4869 /* EXTRA_CONSTRAINT helper */
4872 extra_constraint (rtx x, int c)
4874 if (c == 'Q'
4875 && GET_CODE (x) == MEM
4876 && GET_CODE (XEXP (x,0)) == PLUS)
4878 if (TARGET_ALL_DEBUG)
4880 fprintf (stderr, ("extra_constraint:\n"
4881 "reload_completed: %d\n"
4882 "reload_in_progress: %d\n"),
4883 reload_completed, reload_in_progress);
4884 debug_rtx (x);
4886 if (GET_CODE (x) == MEM
4887 && GET_CODE (XEXP (x,0)) == PLUS
4888 && REG_P (XEXP (XEXP (x,0), 0))
4889 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
4890 && (INTVAL (XEXP (XEXP (x,0), 1))
4891 <= MAX_LD_OFFSET (GET_MODE (x))))
4893 rtx xx = XEXP (XEXP (x,0), 0);
4894 int regno = REGNO (xx);
4895 if (TARGET_ALL_DEBUG)
4897 fprintf (stderr, ("extra_constraint:\n"
4898 "reload_completed: %d\n"
4899 "reload_in_progress: %d\n"),
4900 reload_completed, reload_in_progress);
4901 debug_rtx (x);
4903 if (regno >= FIRST_PSEUDO_REGISTER)
4904 return 1; /* allocate pseudos */
4905 else if (regno == REG_Z || regno == REG_Y)
4906 return 1; /* strictly check */
4907 else if (xx == frame_pointer_rtx
4908 || xx == arg_pointer_rtx)
4909 return 1; /* XXX frame & arg pointer checks */
4912 return 0;
4915 /* Convert condition code CONDITION to the valid AVR condition code. */
4917 RTX_CODE
4918 avr_normalize_condition (RTX_CODE condition)
4920 switch (condition)
4922 case GT:
4923 return GE;
4924 case GTU:
4925 return GEU;
4926 case LE:
4927 return LT;
4928 case LEU:
4929 return LTU;
4930 default:
4931 abort ();
4935 /* This function optimizes conditional jumps. */
4937 static void
4938 avr_reorg (void)
4940 rtx insn, pattern;
4942 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4944 if (! (GET_CODE (insn) == INSN
4945 || GET_CODE (insn) == CALL_INSN
4946 || GET_CODE (insn) == JUMP_INSN)
4947 || !single_set (insn))
4948 continue;
4950 pattern = PATTERN (insn);
4952 if (GET_CODE (pattern) == PARALLEL)
4953 pattern = XVECEXP (pattern, 0, 0);
4954 if (GET_CODE (pattern) == SET
4955 && SET_DEST (pattern) == cc0_rtx
4956 && compare_diff_p (insn))
4958 if (GET_CODE (SET_SRC (pattern)) == COMPARE)
4960 /* Now we work under compare insn. */
4962 pattern = SET_SRC (pattern);
4963 if (true_regnum (XEXP (pattern,0)) >= 0
4964 && true_regnum (XEXP (pattern,1)) >= 0 )
4966 rtx x = XEXP (pattern,0);
4967 rtx next = next_real_insn (insn);
4968 rtx pat = PATTERN (next);
4969 rtx src = SET_SRC (pat);
4970 rtx t = XEXP (src,0);
4971 PUT_CODE (t, swap_condition (GET_CODE (t)));
4972 XEXP (pattern,0) = XEXP (pattern,1);
4973 XEXP (pattern,1) = x;
4974 INSN_CODE (next) = -1;
4976 else if (true_regnum (XEXP (pattern,0)) >= 0
4977 && GET_CODE (XEXP (pattern,1)) == CONST_INT)
4979 rtx x = XEXP (pattern,1);
4980 rtx next = next_real_insn (insn);
4981 rtx pat = PATTERN (next);
4982 rtx src = SET_SRC (pat);
4983 rtx t = XEXP (src,0);
4984 enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
4986 if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
4988 XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
4989 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
4990 INSN_CODE (next) = -1;
4991 INSN_CODE (insn) = -1;
4995 else if (true_regnum (SET_SRC (pattern)) >= 0)
4997 /* This is a tst insn */
4998 rtx next = next_real_insn (insn);
4999 rtx pat = PATTERN (next);
5000 rtx src = SET_SRC (pat);
5001 rtx t = XEXP (src,0);
5003 PUT_CODE (t, swap_condition (GET_CODE (t)));
5004 SET_SRC (pattern) = gen_rtx_NEG (GET_MODE (SET_SRC (pattern)),
5005 SET_SRC (pattern));
5006 INSN_CODE (next) = -1;
5007 INSN_CODE (insn) = -1;
5013 /* Returns register number for function return value.*/
5016 avr_ret_register (void)
5018 return 24;
5021 /* Ceate an RTX representing the place where a
5022 library function returns a value of mode MODE. */
5025 avr_libcall_value (enum machine_mode mode)
5027 int offs = GET_MODE_SIZE (mode);
5028 if (offs < 2)
5029 offs = 2;
5030 return gen_rtx_REG (mode, RET_REGISTER + 2 - offs);
5033 /* Create an RTX representing the place where a
5034 function returns a value of data type VALTYPE. */
5037 avr_function_value (tree type, tree func ATTRIBUTE_UNUSED)
5039 unsigned int offs;
5041 if (TYPE_MODE (type) != BLKmode)
5042 return avr_libcall_value (TYPE_MODE (type));
5044 offs = int_size_in_bytes (type);
5045 if (offs < 2)
5046 offs = 2;
5047 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
5048 offs = GET_MODE_SIZE (SImode);
5049 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
5050 offs = GET_MODE_SIZE (DImode);
5052 return gen_rtx_REG (BLKmode, RET_REGISTER + 2 - offs);
5055 /* Returns nonzero if the number MASK has only one bit set. */
5058 mask_one_bit_p (HOST_WIDE_INT mask)
5060 int i;
5061 unsigned HOST_WIDE_INT n=mask;
5062 for (i = 0; i < 32; ++i)
5064 if (n & 0x80000000L)
5066 if (n & 0x7fffffffL)
5067 return 0;
5068 else
5069 return 32-i;
5071 n<<=1;
5073 return 0;
5077 /* Places additional restrictions on the register class to
5078 use when it is necessary to copy value X into a register
5079 in class CLASS. */
5081 enum reg_class
5082 preferred_reload_class (rtx x ATTRIBUTE_UNUSED, enum reg_class class)
5084 return class;
5088 test_hard_reg_class (enum reg_class class, rtx x)
5090 int regno = true_regnum (x);
5091 if (regno < 0)
5092 return 0;
5094 if (TEST_HARD_REG_CLASS (class, regno))
5095 return 1;
5097 return 0;
5102 jump_over_one_insn_p (rtx insn, rtx dest)
5104 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
5105 ? XEXP (dest, 0)
5106 : dest);
5107 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
5108 int dest_addr = INSN_ADDRESSES (uid);
5109 return dest_addr - jump_addr == get_attr_length (insn) + 1;
5112 /* Returns 1 if a value of mode MODE can be stored starting with hard
5113 register number REGNO. On the enhanced core, anything larger than
5114 1 byte must start in even numbered register for "movw" to work
5115 (this way we don't have to check for odd registers everywhere). */
5118 avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
5120 /* Bug workaround: recog.c (peep2_find_free_register) and probably
5121 a few other places assume that the frame pointer is a single hard
5122 register, so r29 may be allocated and overwrite the high byte of
5123 the frame pointer. Do not allow any value to start in r29. */
5124 if (regno == REG_Y + 1)
5125 return 0;
5127 if (mode == QImode)
5128 return 1;
5129 /* if (regno < 24 && !AVR_ENHANCED)
5130 return 1;*/
5131 return !(regno & 1);
5134 /* Returns 1 if X is a valid address for an I/O register of size SIZE
5135 (1 or 2). Used for lds/sts -> in/out optimization. Add 0x20 to SIZE
5136 to check for the lower half of I/O space (for cbi/sbi/sbic/sbis). */
5139 avr_io_address_p (rtx x, int size)
5141 return (optimize > 0 && GET_CODE (x) == CONST_INT
5142 && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size);
5145 /* Returns nonzero (bit number + 1) if X, or -X, is a constant power of 2. */
5148 const_int_pow2_p (rtx x)
5150 if (GET_CODE (x) == CONST_INT)
5152 HOST_WIDE_INT d = INTVAL (x);
5153 HOST_WIDE_INT abs_d = (d >= 0) ? d : -d;
5154 return exact_log2 (abs_d) + 1;
5156 return 0;
5159 const char *
5160 output_reload_inhi (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
5162 int tmp;
5163 if (!len)
5164 len = &tmp;
5166 if (GET_CODE (operands[1]) == CONST_INT)
5168 int val = INTVAL (operands[1]);
5169 if ((val & 0xff) == 0)
5171 *len = 3;
5172 return (AS2 (mov,%A0,__zero_reg__) CR_TAB
5173 AS2 (ldi,%2,hi8(%1)) CR_TAB
5174 AS2 (mov,%B0,%2));
5176 else if ((val & 0xff00) == 0)
5178 *len = 3;
5179 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5180 AS2 (mov,%A0,%2) CR_TAB
5181 AS2 (mov,%B0,__zero_reg__));
5183 else if ((val & 0xff) == ((val & 0xff00) >> 8))
5185 *len = 3;
5186 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5187 AS2 (mov,%A0,%2) CR_TAB
5188 AS2 (mov,%B0,%2));
5191 *len = 4;
5192 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5193 AS2 (mov,%A0,%2) CR_TAB
5194 AS2 (ldi,%2,hi8(%1)) CR_TAB
5195 AS2 (mov,%B0,%2));
5199 const char *
5200 output_reload_insisf (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
5202 rtx src = operands[1];
5203 int cnst = (GET_CODE (src) == CONST_INT);
5205 if (len)
5207 if (cnst)
5208 *len = 4 + ((INTVAL (src) & 0xff) != 0)
5209 + ((INTVAL (src) & 0xff00) != 0)
5210 + ((INTVAL (src) & 0xff0000) != 0)
5211 + ((INTVAL (src) & 0xff000000) != 0);
5212 else
5213 *len = 8;
5215 return "";
5218 if (cnst && ((INTVAL (src) & 0xff) == 0))
5219 output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
5220 else
5222 output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
5223 output_asm_insn (AS2 (mov, %A0, %2), operands);
5225 if (cnst && ((INTVAL (src) & 0xff00) == 0))
5226 output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
5227 else
5229 output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
5230 output_asm_insn (AS2 (mov, %B0, %2), operands);
5232 if (cnst && ((INTVAL (src) & 0xff0000) == 0))
5233 output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
5234 else
5236 output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
5237 output_asm_insn (AS2 (mov, %C0, %2), operands);
5239 if (cnst && ((INTVAL (src) & 0xff000000) == 0))
5240 output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
5241 else
5243 output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
5244 output_asm_insn (AS2 (mov, %D0, %2), operands);
5246 return "";
5249 void
5250 avr_output_bld (rtx operands[], int bit_nr)
5252 static char s[] = "bld %A0,0";
5254 s[5] = 'A' + (bit_nr >> 3);
5255 s[8] = '0' + (bit_nr & 7);
5256 output_asm_insn (s, operands);
5259 void
5260 avr_output_addr_vec_elt (FILE *stream, int value)
5262 if (AVR_MEGA)
5263 fprintf (stream, "\t.word pm(.L%d)\n", value);
5264 else
5265 fprintf (stream, "\trjmp .L%d\n", value);
5267 jump_tables_size++;
5270 /* Returns 1 if SCRATCH are safe to be allocated as a scratch
5271 registers (for a define_peephole2) in the current function. */
5274 avr_peep2_scratch_safe (rtx scratch)
5276 if ((interrupt_function_p (current_function_decl)
5277 || signal_function_p (current_function_decl))
5278 && leaf_function_p ())
5280 int first_reg = true_regnum (scratch);
5281 int last_reg = first_reg + GET_MODE_SIZE (GET_MODE (scratch)) - 1;
5282 int reg;
5284 for (reg = first_reg; reg <= last_reg; reg++)
5286 if (!regs_ever_live[reg])
5287 return 0;
5290 return 1;
5293 /* Output a branch that tests a single bit of a register (QI, HI or SImode)
5294 or memory location in the I/O space (QImode only).
5296 Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
5297 Operand 1: register operand to test, or CONST_INT memory address.
5298 Operand 2: bit number (for QImode operand) or mask (HImode, SImode).
5299 Operand 3: label to jump to if the test is true. */
5301 const char *
5302 avr_out_sbxx_branch (rtx insn, rtx operands[])
5304 enum rtx_code comp = GET_CODE (operands[0]);
5305 int long_jump = (get_attr_length (insn) >= 4);
5306 int reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
5308 if (comp == GE)
5309 comp = EQ;
5310 else if (comp == LT)
5311 comp = NE;
5313 if (reverse)
5314 comp = reverse_condition (comp);
5316 if (GET_CODE (operands[1]) == CONST_INT)
5318 if (INTVAL (operands[1]) < 0x40)
5320 if (comp == EQ)
5321 output_asm_insn (AS2 (sbis,%1-0x20,%2), operands);
5322 else
5323 output_asm_insn (AS2 (sbic,%1-0x20,%2), operands);
5325 else
5327 output_asm_insn (AS2 (in,__tmp_reg__,%1-0x20), operands);
5328 if (comp == EQ)
5329 output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands);
5330 else
5331 output_asm_insn (AS2 (sbrc,__tmp_reg__,%2), operands);
5334 else /* GET_CODE (operands[1]) == REG */
5336 if (GET_MODE (operands[1]) == QImode)
5338 if (comp == EQ)
5339 output_asm_insn (AS2 (sbrs,%1,%2), operands);
5340 else
5341 output_asm_insn (AS2 (sbrc,%1,%2), operands);
5343 else /* HImode or SImode */
5345 static char buf[] = "sbrc %A1,0";
5346 int bit_nr = exact_log2 (INTVAL (operands[2])
5347 & GET_MODE_MASK (GET_MODE (operands[1])));
5349 buf[3] = (comp == EQ) ? 's' : 'c';
5350 buf[6] = 'A' + (bit_nr >> 3);
5351 buf[9] = '0' + (bit_nr & 7);
5352 output_asm_insn (buf, operands);
5356 if (long_jump)
5357 return (AS1 (rjmp,.+4) CR_TAB
5358 AS1 (jmp,%3));
5359 if (!reverse)
5360 return AS1 (rjmp,%3);
5361 return "";
5364 /* Worker function for TARGET_ASM_CONSTRUCTOR. */
5366 static void
5367 avr_asm_out_ctor (rtx symbol, int priority)
5369 fputs ("\t.global __do_global_ctors\n", asm_out_file);
5370 default_ctor_section_asm_out_constructor (symbol, priority);
5373 /* Worker function for TARGET_ASM_DESTRUCTOR. */
5375 static void
5376 avr_asm_out_dtor (rtx symbol, int priority)
5378 fputs ("\t.global __do_global_dtors\n", asm_out_file);
5379 default_dtor_section_asm_out_destructor (symbol, priority);
5382 /* Worker function for TARGET_RETURN_IN_MEMORY. */
5384 static bool
5385 avr_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
5387 return ((TYPE_MODE (type) == BLKmode)
5388 ? int_size_in_bytes (type) > 8
5389 : 0);
5392 #include "gt-avr.h"