* common.opt (-Wattributes): New. Default true.
[official-gcc.git] / gcc / config / avr / avr.c
blob45b51f24fb5b77b3752b75ebd074c06455486c95
1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005
3 Free Software Foundation, Inc.
4 Contributed by Denis Chertykov (denisc@overta.ru)
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 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 bool avr_handle_option (size_t, const char *, int);
52 static int avr_naked_function_p (tree);
53 static int interrupt_function_p (tree);
54 static int signal_function_p (tree);
55 static int avr_regs_to_save (HARD_REG_SET *);
56 static int sequent_regs_live (void);
57 static const char *ptrreg_to_str (int);
58 static const char *cond_string (enum rtx_code);
59 static int avr_num_arg_regs (enum machine_mode, tree);
60 static int out_adj_frame_ptr (FILE *, int);
61 static int out_set_stack_ptr (FILE *, int, int);
62 static RTX_CODE compare_condition (rtx insn);
63 static int compare_sign_p (rtx insn);
64 static tree avr_handle_progmem_attribute (tree *, tree, tree, int, bool *);
65 static tree avr_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
66 const struct attribute_spec avr_attribute_table[];
67 static bool avr_assemble_integer (rtx, unsigned int, int);
68 static void avr_file_start (void);
69 static void avr_file_end (void);
70 static void avr_output_function_prologue (FILE *, HOST_WIDE_INT);
71 static void avr_output_function_epilogue (FILE *, HOST_WIDE_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 avr_operand_rtx_cost (rtx, enum machine_mode, enum rtx_code);
79 static bool avr_rtx_costs (rtx, int, int, int *);
80 static int avr_address_cost (rtx);
81 static bool avr_return_in_memory (tree, tree);
83 /* Allocate registers from r25 to r8 for parameters for function calls. */
84 #define FIRST_CUM_REG 26
86 /* Temporary register RTX (gen_rtx_REG (QImode, TMP_REGNO)) */
87 static GTY(()) rtx tmp_reg_rtx;
89 /* Zeroed register RTX (gen_rtx_REG (QImode, ZERO_REGNO)) */
90 static GTY(()) rtx zero_reg_rtx;
92 /* AVR register names {"r0", "r1", ..., "r31"} */
93 static const char *const avr_regnames[] = REGISTER_NAMES;
95 /* This holds the last insn address. */
96 static int last_insn_address = 0;
98 /* Commands count in the compiled file */
99 static int commands_in_file;
101 /* Commands in the functions prologues in the compiled file */
102 static int commands_in_prologues;
104 /* Commands in the functions epilogues in the compiled file */
105 static int commands_in_epilogues;
107 /* Prologue/Epilogue size in words */
108 static int prologue_size;
109 static int epilogue_size;
111 /* Size of all jump tables in the current function, in words. */
112 static int jump_tables_size;
114 /* Initial stack value specified by the `-minit-stack=' option */
115 static const char *avr_init_stack = "__stack";
117 /* Default MCU name */
118 static 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 + MOVW, <= 8K. */
181 { "attiny13", 2, "__AVR_ATtiny13__" },
182 { "attiny2313", 2, "__AVR_ATtiny2313__" },
183 /* Classic, > 8K. */
184 { "avr3", 3, NULL },
185 { "atmega103", 3, "__AVR_ATmega103__" },
186 { "atmega603", 3, "__AVR_ATmega603__" },
187 { "at43usb320", 3, "__AVR_AT43USB320__" },
188 { "at43usb355", 3, "__AVR_AT43USB355__" },
189 { "at76c711", 3, "__AVR_AT76C711__" },
190 /* Enhanced, <= 8K. */
191 { "avr4", 4, NULL },
192 { "atmega8", 4, "__AVR_ATmega8__" },
193 { "atmega48", 4, "__AVR_ATmega48__" },
194 { "atmega88", 4, "__AVR_ATmega88__" },
195 { "atmega8515", 4, "__AVR_ATmega8515__" },
196 { "atmega8535", 4, "__AVR_ATmega8535__" },
197 /* Enhanced, > 8K. */
198 { "avr5", 5, NULL },
199 { "atmega16", 5, "__AVR_ATmega16__" },
200 { "atmega161", 5, "__AVR_ATmega161__" },
201 { "atmega162", 5, "__AVR_ATmega162__" },
202 { "atmega163", 5, "__AVR_ATmega163__" },
203 { "atmega165", 5, "__AVR_ATmega165__" },
204 { "atmega168", 5, "__AVR_ATmega168__" },
205 { "atmega169", 5, "__AVR_ATmega169__" },
206 { "atmega32", 5, "__AVR_ATmega32__" },
207 { "atmega323", 5, "__AVR_ATmega323__" },
208 { "atmega325", 5, "__AVR_ATmega325__" },
209 { "atmega3250", 5, "__AVR_ATmega3250__" },
210 { "atmega64", 5, "__AVR_ATmega64__" },
211 { "atmega645", 5, "__AVR_ATmega645__" },
212 { "atmega6450", 5, "__AVR_ATmega6450__" },
213 { "atmega128", 5, "__AVR_ATmega128__" },
214 { "at90can128", 5, "__AVR_AT90CAN128__" },
215 { "at94k", 5, "__AVR_AT94K__" },
216 /* Assembler only. */
217 { "avr1", 1, NULL },
218 { "at90s1200", 1, "__AVR_AT90S1200__" },
219 { "attiny11", 1, "__AVR_ATtiny11__" },
220 { "attiny12", 1, "__AVR_ATtiny12__" },
221 { "attiny15", 1, "__AVR_ATtiny15__" },
222 { "attiny28", 1, "__AVR_ATtiny28__" },
223 { NULL, 0, NULL }
226 int avr_case_values_threshold = 30000;
228 /* Initialize the GCC target structure. */
229 #undef TARGET_ASM_ALIGNED_HI_OP
230 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
231 #undef TARGET_ASM_INTEGER
232 #define TARGET_ASM_INTEGER avr_assemble_integer
233 #undef TARGET_ASM_FILE_START
234 #define TARGET_ASM_FILE_START avr_file_start
235 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
236 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
237 #undef TARGET_ASM_FILE_END
238 #define TARGET_ASM_FILE_END avr_file_end
240 #undef TARGET_ASM_FUNCTION_PROLOGUE
241 #define TARGET_ASM_FUNCTION_PROLOGUE avr_output_function_prologue
242 #undef TARGET_ASM_FUNCTION_EPILOGUE
243 #define TARGET_ASM_FUNCTION_EPILOGUE avr_output_function_epilogue
244 #undef TARGET_ATTRIBUTE_TABLE
245 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
246 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
247 #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
248 #undef TARGET_HANDLE_OPTION
249 #define TARGET_HANDLE_OPTION avr_handle_option
250 #undef TARGET_INSERT_ATTRIBUTES
251 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
252 #undef TARGET_SECTION_TYPE_FLAGS
253 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
254 #undef TARGET_RTX_COSTS
255 #define TARGET_RTX_COSTS avr_rtx_costs
256 #undef TARGET_ADDRESS_COST
257 #define TARGET_ADDRESS_COST avr_address_cost
258 #undef TARGET_MACHINE_DEPENDENT_REORG
259 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
261 #undef TARGET_RETURN_IN_MEMORY
262 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
264 #undef TARGET_STRICT_ARGUMENT_NAMING
265 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
267 struct gcc_target targetm = TARGET_INITIALIZER;
269 /* Implement TARGET_HANDLE_OPTION. */
271 static bool
272 avr_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
274 switch (code)
276 case OPT_minit_stack_:
277 avr_init_stack = arg;
278 return true;
280 case OPT_mmcu_:
281 avr_mcu_name = arg;
282 return true;
284 default:
285 return true;
289 void
290 avr_override_options (void)
292 const struct mcu_type_s *t;
293 const struct base_arch_s *base;
295 for (t = avr_mcu_types; t->name; t++)
296 if (strcmp (t->name, avr_mcu_name) == 0)
297 break;
299 if (!t->name)
301 fprintf (stderr, "unknown MCU `%s' specified\nKnown MCU names:\n",
302 avr_mcu_name);
303 for (t = avr_mcu_types; t->name; t++)
304 fprintf (stderr," %s\n", t->name);
307 base = &avr_arch_types[t->arch];
308 avr_asm_only_p = base->asm_only;
309 avr_enhanced_p = base->enhanced;
310 avr_mega_p = base->mega;
311 avr_base_arch_macro = base->macro;
312 avr_extra_arch_macro = t->macro;
314 if (optimize && !TARGET_NO_TABLEJUMP)
315 avr_case_values_threshold = (!AVR_MEGA || TARGET_CALL_PROLOGUES) ? 8 : 17;
317 tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO);
318 zero_reg_rtx = gen_rtx_REG (QImode, ZERO_REGNO);
321 /* return register class from register number. */
323 static const int reg_class_tab[]={
324 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
325 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
326 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
327 GENERAL_REGS, /* r0 - r15 */
328 LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
329 LD_REGS, /* r16 - 23 */
330 ADDW_REGS,ADDW_REGS, /* r24,r25 */
331 POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
332 POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
333 POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
334 STACK_REG,STACK_REG /* SPL,SPH */
337 /* Return register class for register R. */
339 enum reg_class
340 avr_regno_reg_class (int r)
342 if (r <= 33)
343 return reg_class_tab[r];
344 return ALL_REGS;
348 /* A C expression which defines the machine-dependent operand
349 constraint letters for register classes. If C is such a
350 letter, the value should be the register class corresponding to
351 it. Otherwise, the value should be `NO_REGS'. The register
352 letter `r', corresponding to class `GENERAL_REGS', will not be
353 passed to this macro; you do not need to handle it. */
355 enum reg_class
356 avr_reg_class_from_letter (int c)
358 switch (c)
360 case 't' : return R0_REG;
361 case 'b' : return BASE_POINTER_REGS;
362 case 'e' : return POINTER_REGS;
363 case 'w' : return ADDW_REGS;
364 case 'd' : return LD_REGS;
365 case 'l' : return NO_LD_REGS;
366 case 'a' : return SIMPLE_LD_REGS;
367 case 'x' : return POINTER_X_REGS;
368 case 'y' : return POINTER_Y_REGS;
369 case 'z' : return POINTER_Z_REGS;
370 case 'q' : return STACK_REG;
371 default: break;
373 return NO_REGS;
376 /* Return nonzero if FUNC is a naked function. */
378 static int
379 avr_naked_function_p (tree func)
381 tree a;
383 gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
385 a = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
386 return a != NULL_TREE;
389 /* Return nonzero if FUNC is an interrupt function as specified
390 by the "interrupt" attribute. */
392 static int
393 interrupt_function_p (tree func)
395 tree a;
397 if (TREE_CODE (func) != FUNCTION_DECL)
398 return 0;
400 a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
401 return a != NULL_TREE;
404 /* Return nonzero if FUNC is a signal function as specified
405 by the "signal" attribute. */
407 static int
408 signal_function_p (tree func)
410 tree a;
412 if (TREE_CODE (func) != FUNCTION_DECL)
413 return 0;
415 a = lookup_attribute ("signal", DECL_ATTRIBUTES (func));
416 return a != NULL_TREE;
419 /* Return the number of hard registers to push/pop in the prologue/epilogue
420 of the current function, and optionally store these registers in SET. */
422 static int
423 avr_regs_to_save (HARD_REG_SET *set)
425 int reg, count;
426 int int_or_sig_p = (interrupt_function_p (current_function_decl)
427 || signal_function_p (current_function_decl));
428 int leaf_func_p = leaf_function_p ();
430 if (set)
431 CLEAR_HARD_REG_SET (*set);
432 count = 0;
434 /* No need to save any registers if the function never returns. */
435 if (TREE_THIS_VOLATILE (current_function_decl))
436 return 0;
438 for (reg = 0; reg < 32; reg++)
440 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
441 any global register variables. */
442 if (fixed_regs[reg])
443 continue;
445 if ((int_or_sig_p && !leaf_func_p && call_used_regs[reg])
446 || (regs_ever_live[reg]
447 && (int_or_sig_p || !call_used_regs[reg])
448 && !(frame_pointer_needed
449 && (reg == REG_Y || reg == (REG_Y+1)))))
451 if (set)
452 SET_HARD_REG_BIT (*set, reg);
453 count++;
456 return count;
459 /* Compute offset between arg_pointer and frame_pointer. */
462 initial_elimination_offset (int from, int to)
464 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
465 return 0;
466 else
468 int offset = frame_pointer_needed ? 2 : 0;
470 offset += avr_regs_to_save (NULL);
471 return get_frame_size () + 2 + 1 + offset;
475 /* Return 1 if the function epilogue is just a single "ret". */
478 avr_simple_epilogue (void)
480 return (! frame_pointer_needed
481 && get_frame_size () == 0
482 && avr_regs_to_save (NULL) == 0
483 && ! interrupt_function_p (current_function_decl)
484 && ! signal_function_p (current_function_decl)
485 && ! avr_naked_function_p (current_function_decl)
486 && ! MAIN_NAME_P (DECL_NAME (current_function_decl))
487 && ! TREE_THIS_VOLATILE (current_function_decl));
490 /* This function checks sequence of live registers. */
492 static int
493 sequent_regs_live (void)
495 int reg;
496 int live_seq=0;
497 int cur_seq=0;
499 for (reg = 0; reg < 18; ++reg)
501 if (!call_used_regs[reg])
503 if (regs_ever_live[reg])
505 ++live_seq;
506 ++cur_seq;
508 else
509 cur_seq = 0;
513 if (!frame_pointer_needed)
515 if (regs_ever_live[REG_Y])
517 ++live_seq;
518 ++cur_seq;
520 else
521 cur_seq = 0;
523 if (regs_ever_live[REG_Y+1])
525 ++live_seq;
526 ++cur_seq;
528 else
529 cur_seq = 0;
531 else
533 cur_seq += 2;
534 live_seq += 2;
536 return (cur_seq == live_seq) ? live_seq : 0;
540 /* Output to FILE the asm instructions to adjust the frame pointer by
541 ADJ (r29:r28 -= ADJ;) which can be positive (prologue) or negative
542 (epilogue). Returns the number of instructions generated. */
544 static int
545 out_adj_frame_ptr (FILE *file, int adj)
547 int size = 0;
549 if (adj)
551 if (TARGET_TINY_STACK)
553 if (adj < -63 || adj > 63)
554 warning (0, "large frame pointer change (%d) with -mtiny-stack", adj);
556 /* The high byte (r29) doesn't change - prefer "subi" (1 cycle)
557 over "sbiw" (2 cycles, same size). */
559 fprintf (file, (AS2 (subi, r28, %d) CR_TAB), adj);
560 size++;
562 else if (adj < -63 || adj > 63)
564 fprintf (file, (AS2 (subi, r28, lo8(%d)) CR_TAB
565 AS2 (sbci, r29, hi8(%d)) CR_TAB),
566 adj, adj);
567 size += 2;
569 else if (adj < 0)
571 fprintf (file, (AS2 (adiw, r28, %d) CR_TAB), -adj);
572 size++;
574 else
576 fprintf (file, (AS2 (sbiw, r28, %d) CR_TAB), adj);
577 size++;
580 return size;
584 /* Output to FILE the asm instructions to copy r29:r28 to SPH:SPL,
585 handling various cases of interrupt enable flag state BEFORE and AFTER
586 (0=disabled, 1=enabled, -1=unknown/unchanged) and target_flags.
587 Returns the number of instructions generated. */
589 static int
590 out_set_stack_ptr (FILE *file, int before, int after)
592 int do_sph, do_cli, do_save, do_sei, lock_sph, size;
594 /* The logic here is so that -mno-interrupts actually means
595 "it is safe to write SPH in one instruction, then SPL in the
596 next instruction, without disabling interrupts first".
597 The after != -1 case (interrupt/signal) is not affected. */
599 do_sph = !TARGET_TINY_STACK;
600 lock_sph = do_sph && !TARGET_NO_INTERRUPTS;
601 do_cli = (before != 0 && (after == 0 || lock_sph));
602 do_save = (do_cli && before == -1 && after == -1);
603 do_sei = ((do_cli || before != 1) && after == 1);
604 size = 1;
606 if (do_save)
608 fprintf (file, AS2 (in, __tmp_reg__, __SREG__) CR_TAB);
609 size++;
612 if (do_cli)
614 fprintf (file, "cli" CR_TAB);
615 size++;
618 /* Do SPH first - maybe this will disable interrupts for one instruction
619 someday (a suggestion has been sent to avr@atmel.com for consideration
620 in future devices - that would make -mno-interrupts always safe). */
621 if (do_sph)
623 fprintf (file, AS2 (out, __SP_H__, r29) CR_TAB);
624 size++;
627 /* Set/restore the I flag now - interrupts will be really enabled only
628 after the next instruction. This is not clearly documented, but
629 believed to be true for all AVR devices. */
630 if (do_save)
632 fprintf (file, AS2 (out, __SREG__, __tmp_reg__) CR_TAB);
633 size++;
635 else if (do_sei)
637 fprintf (file, "sei" CR_TAB);
638 size++;
641 fprintf (file, AS2 (out, __SP_L__, r28) "\n");
643 return size;
647 /* Output function prologue. */
649 static void
650 avr_output_function_prologue (FILE *file, HOST_WIDE_INT size)
652 int reg;
653 int interrupt_func_p;
654 int signal_func_p;
655 int main_p;
656 int live_seq;
657 int minimize;
659 last_insn_address = 0;
660 jump_tables_size = 0;
661 prologue_size = 0;
662 fprintf (file, "/* prologue: frame size=" HOST_WIDE_INT_PRINT_DEC " */\n",
663 size);
665 if (avr_naked_function_p (current_function_decl))
667 fputs ("/* prologue: naked */\n", file);
668 goto out;
671 interrupt_func_p = interrupt_function_p (current_function_decl);
672 signal_func_p = signal_function_p (current_function_decl);
673 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
674 live_seq = sequent_regs_live ();
675 minimize = (TARGET_CALL_PROLOGUES
676 && !interrupt_func_p && !signal_func_p && live_seq);
678 if (interrupt_func_p)
680 fprintf (file,"\tsei\n");
681 ++prologue_size;
683 if (interrupt_func_p || signal_func_p)
685 fprintf (file, "\t"
686 AS1 (push,__zero_reg__) CR_TAB
687 AS1 (push,__tmp_reg__) CR_TAB
688 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
689 AS1 (push,__tmp_reg__) CR_TAB
690 AS1 (clr,__zero_reg__) "\n");
691 prologue_size += 5;
693 if (main_p)
695 fprintf (file, ("\t"
696 AS1 (ldi,r28) ",lo8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
697 AS1 (ldi,r29) ",hi8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
698 AS2 (out,__SP_H__,r29) CR_TAB
699 AS2 (out,__SP_L__,r28) "\n"),
700 avr_init_stack, size, avr_init_stack, size);
702 prologue_size += 4;
704 else if (minimize && (frame_pointer_needed || live_seq > 6))
706 fprintf (file, ("\t"
707 AS1 (ldi, r26) ",lo8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
708 AS1 (ldi, r27) ",hi8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB), size, size);
710 fputs ((AS2 (ldi,r30,pm_lo8(1f)) CR_TAB
711 AS2 (ldi,r31,pm_hi8(1f)) CR_TAB), file);
713 prologue_size += 4;
715 if (AVR_MEGA)
717 fprintf (file, AS1 (jmp,__prologue_saves__+%d) "\n",
718 (18 - live_seq) * 2);
719 prologue_size += 2;
721 else
723 fprintf (file, AS1 (rjmp,__prologue_saves__+%d) "\n",
724 (18 - live_seq) * 2);
725 ++prologue_size;
727 fputs ("1:\n", file);
729 else
731 HARD_REG_SET set;
733 prologue_size += avr_regs_to_save (&set);
734 for (reg = 0; reg < 32; ++reg)
736 if (TEST_HARD_REG_BIT (set, reg))
738 fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
741 if (frame_pointer_needed)
743 fprintf (file, "\t"
744 AS1 (push,r28) CR_TAB
745 AS1 (push,r29) CR_TAB
746 AS2 (in,r28,__SP_L__) CR_TAB
747 AS2 (in,r29,__SP_H__) "\n");
748 prologue_size += 4;
749 if (size)
751 fputs ("\t", file);
752 prologue_size += out_adj_frame_ptr (file, size);
754 if (interrupt_func_p)
756 prologue_size += out_set_stack_ptr (file, 1, 1);
758 else if (signal_func_p)
760 prologue_size += out_set_stack_ptr (file, 0, 0);
762 else
764 prologue_size += out_set_stack_ptr (file, -1, -1);
770 out:
771 fprintf (file, "/* prologue end (size=%d) */\n", prologue_size);
774 /* Output function epilogue. */
776 static void
777 avr_output_function_epilogue (FILE *file, HOST_WIDE_INT size)
779 int reg;
780 int interrupt_func_p;
781 int signal_func_p;
782 int main_p;
783 int function_size;
784 int live_seq;
785 int minimize;
786 rtx last = get_last_nonnote_insn ();
788 function_size = jump_tables_size;
789 if (last)
791 rtx first = get_first_nonnote_insn ();
792 function_size += (INSN_ADDRESSES (INSN_UID (last)) -
793 INSN_ADDRESSES (INSN_UID (first)));
794 function_size += get_attr_length (last);
797 fprintf (file, "/* epilogue: frame size=" HOST_WIDE_INT_PRINT_DEC " */\n", size);
798 epilogue_size = 0;
800 if (avr_naked_function_p (current_function_decl))
802 fputs ("/* epilogue: naked */\n", file);
803 goto out;
806 if (last && GET_CODE (last) == BARRIER)
808 fputs ("/* epilogue: noreturn */\n", file);
809 goto out;
812 interrupt_func_p = interrupt_function_p (current_function_decl);
813 signal_func_p = signal_function_p (current_function_decl);
814 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
815 live_seq = sequent_regs_live ();
816 minimize = (TARGET_CALL_PROLOGUES
817 && !interrupt_func_p && !signal_func_p && live_seq);
819 if (main_p)
821 /* Return value from main() is already in the correct registers
822 (r25:r24) as the exit() argument. */
823 if (AVR_MEGA)
825 fputs ("\t" AS1 (jmp,exit) "\n", file);
826 epilogue_size += 2;
828 else
830 fputs ("\t" AS1 (rjmp,exit) "\n", file);
831 ++epilogue_size;
834 else if (minimize && (frame_pointer_needed || live_seq > 4))
836 fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
837 ++epilogue_size;
838 if (frame_pointer_needed)
840 epilogue_size += out_adj_frame_ptr (file, -size);
842 else
844 fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
845 AS2 (in , r29, __SP_H__) CR_TAB));
846 epilogue_size += 2;
849 if (AVR_MEGA)
851 fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
852 (18 - live_seq) * 2);
853 epilogue_size += 2;
855 else
857 fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
858 (18 - live_seq) * 2);
859 ++epilogue_size;
862 else
864 HARD_REG_SET set;
866 if (frame_pointer_needed)
868 if (size)
870 fputs ("\t", file);
871 epilogue_size += out_adj_frame_ptr (file, -size);
873 if (interrupt_func_p || signal_func_p)
875 epilogue_size += out_set_stack_ptr (file, -1, 0);
877 else
879 epilogue_size += out_set_stack_ptr (file, -1, -1);
882 fprintf (file, "\t"
883 AS1 (pop,r29) CR_TAB
884 AS1 (pop,r28) "\n");
885 epilogue_size += 2;
888 epilogue_size += avr_regs_to_save (&set);
889 for (reg = 31; reg >= 0; --reg)
891 if (TEST_HARD_REG_BIT (set, reg))
893 fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
897 if (interrupt_func_p || signal_func_p)
899 fprintf (file, "\t"
900 AS1 (pop,__tmp_reg__) CR_TAB
901 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
902 AS1 (pop,__tmp_reg__) CR_TAB
903 AS1 (pop,__zero_reg__) "\n");
904 epilogue_size += 4;
905 fprintf (file, "\treti\n");
907 else
908 fprintf (file, "\tret\n");
909 ++epilogue_size;
912 out:
913 fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
914 fprintf (file, "/* function %s size %d (%d) */\n", current_function_name (),
915 prologue_size + function_size + epilogue_size, function_size);
916 commands_in_file += prologue_size + function_size + epilogue_size;
917 commands_in_prologues += prologue_size;
918 commands_in_epilogues += epilogue_size;
922 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
923 machine for a memory operand of mode MODE. */
926 legitimate_address_p (enum machine_mode mode, rtx x, int strict)
928 enum reg_class r = NO_REGS;
930 if (TARGET_ALL_DEBUG)
932 fprintf (stderr, "mode: (%s) %s %s %s %s:",
933 GET_MODE_NAME(mode),
934 strict ? "(strict)": "",
935 reload_completed ? "(reload_completed)": "",
936 reload_in_progress ? "(reload_in_progress)": "",
937 reg_renumber ? "(reg_renumber)" : "");
938 if (GET_CODE (x) == PLUS
939 && REG_P (XEXP (x, 0))
940 && GET_CODE (XEXP (x, 1)) == CONST_INT
941 && INTVAL (XEXP (x, 1)) >= 0
942 && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
943 && reg_renumber
945 fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
946 true_regnum (XEXP (x, 0)));
947 debug_rtx (x);
949 if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
950 : REG_OK_FOR_BASE_NOSTRICT_P (x)))
951 r = POINTER_REGS;
952 else if (CONSTANT_ADDRESS_P (x))
953 r = ALL_REGS;
954 else if (GET_CODE (x) == PLUS
955 && REG_P (XEXP (x, 0))
956 && GET_CODE (XEXP (x, 1)) == CONST_INT
957 && INTVAL (XEXP (x, 1)) >= 0)
959 int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
960 if (fit)
962 if (! strict
963 || REGNO (XEXP (x,0)) == REG_Y
964 || REGNO (XEXP (x,0)) == REG_Z)
965 r = BASE_POINTER_REGS;
966 if (XEXP (x,0) == frame_pointer_rtx
967 || XEXP (x,0) == arg_pointer_rtx)
968 r = BASE_POINTER_REGS;
970 else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
971 r = POINTER_Y_REGS;
973 else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
974 && REG_P (XEXP (x, 0))
975 && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
976 : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
978 r = POINTER_REGS;
980 if (TARGET_ALL_DEBUG)
982 fprintf (stderr, " ret = %c\n", r);
984 return r == NO_REGS ? 0 : (int)r;
987 /* Attempts to replace X with a valid
988 memory address for an operand of mode MODE */
991 legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
993 x = oldx;
994 if (TARGET_ALL_DEBUG)
996 fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
997 debug_rtx (oldx);
1000 if (GET_CODE (oldx) == PLUS
1001 && REG_P (XEXP (oldx,0)))
1003 if (REG_P (XEXP (oldx,1)))
1004 x = force_reg (GET_MODE (oldx), oldx);
1005 else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
1007 int offs = INTVAL (XEXP (oldx,1));
1008 if (frame_pointer_rtx != XEXP (oldx,0))
1009 if (offs > MAX_LD_OFFSET (mode))
1011 if (TARGET_ALL_DEBUG)
1012 fprintf (stderr, "force_reg (big offset)\n");
1013 x = force_reg (GET_MODE (oldx), oldx);
1017 return x;
1021 /* Return a pointer register name as a string. */
1023 static const char *
1024 ptrreg_to_str (int regno)
1026 switch (regno)
1028 case REG_X: return "X";
1029 case REG_Y: return "Y";
1030 case REG_Z: return "Z";
1031 default:
1032 gcc_unreachable ();
1034 return NULL;
1037 /* Return the condition name as a string.
1038 Used in conditional jump constructing */
1040 static const char *
1041 cond_string (enum rtx_code code)
1043 switch (code)
1045 case NE:
1046 return "ne";
1047 case EQ:
1048 return "eq";
1049 case GE:
1050 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1051 return "pl";
1052 else
1053 return "ge";
1054 case LT:
1055 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1056 return "mi";
1057 else
1058 return "lt";
1059 case GEU:
1060 return "sh";
1061 case LTU:
1062 return "lo";
1063 default:
1064 gcc_unreachable ();
1068 /* Output ADDR to FILE as address. */
1070 void
1071 print_operand_address (FILE *file, rtx addr)
1073 switch (GET_CODE (addr))
1075 case REG:
1076 fprintf (file, ptrreg_to_str (REGNO (addr)));
1077 break;
1079 case PRE_DEC:
1080 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1081 break;
1083 case POST_INC:
1084 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1085 break;
1087 default:
1088 if (CONSTANT_ADDRESS_P (addr)
1089 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (addr))
1090 || GET_CODE (addr) == LABEL_REF))
1092 fprintf (file, "pm(");
1093 output_addr_const (file,addr);
1094 fprintf (file ,")");
1096 else
1097 output_addr_const (file, addr);
1102 /* Output X as assembler operand to file FILE. */
1104 void
1105 print_operand (FILE *file, rtx x, int code)
1107 int abcd = 0;
1109 if (code >= 'A' && code <= 'D')
1110 abcd = code - 'A';
1112 if (code == '~')
1114 if (!AVR_MEGA)
1115 fputc ('r', file);
1117 else if (REG_P (x))
1119 if (x == zero_reg_rtx)
1120 fprintf (file, "__zero_reg__");
1121 else
1122 fprintf (file, reg_names[true_regnum (x) + abcd]);
1124 else if (GET_CODE (x) == CONST_INT)
1125 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd);
1126 else if (GET_CODE (x) == MEM)
1128 rtx addr = XEXP (x,0);
1130 if (CONSTANT_P (addr) && abcd)
1132 fputc ('(', file);
1133 output_address (addr);
1134 fprintf (file, ")+%d", abcd);
1136 else if (code == 'o')
1138 if (GET_CODE (addr) != PLUS)
1139 fatal_insn ("bad address, not (reg+disp):", addr);
1141 print_operand (file, XEXP (addr, 1), 0);
1143 else if (code == 'p' || code == 'r')
1145 if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
1146 fatal_insn ("bad address, not post_inc or pre_dec:", addr);
1148 if (code == 'p')
1149 print_operand_address (file, XEXP (addr, 0)); /* X, Y, Z */
1150 else
1151 print_operand (file, XEXP (addr, 0), 0); /* r26, r28, r30 */
1153 else if (GET_CODE (addr) == PLUS)
1155 print_operand_address (file, XEXP (addr,0));
1156 if (REGNO (XEXP (addr, 0)) == REG_X)
1157 fatal_insn ("internal compiler error. Bad address:"
1158 ,addr);
1159 fputc ('+', file);
1160 print_operand (file, XEXP (addr,1), code);
1162 else
1163 print_operand_address (file, addr);
1165 else if (GET_CODE (x) == CONST_DOUBLE)
1167 long val;
1168 REAL_VALUE_TYPE rv;
1169 if (GET_MODE (x) != SFmode)
1170 fatal_insn ("internal compiler error. Unknown mode:", x);
1171 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1172 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1173 fprintf (file, "0x%lx", val);
1175 else if (code == 'j')
1176 fputs (cond_string (GET_CODE (x)), file);
1177 else if (code == 'k')
1178 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
1179 else
1180 print_operand_address (file, x);
1183 /* Recognize operand OP of mode MODE used in call instructions. */
1186 call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1188 if (GET_CODE (op) == MEM)
1190 rtx inside = XEXP (op, 0);
1191 if (register_operand (inside, Pmode))
1192 return 1;
1193 if (CONSTANT_ADDRESS_P (inside))
1194 return 1;
1196 return 0;
1199 /* Update the condition code in the INSN. */
1201 void
1202 notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
1204 rtx set;
1206 switch (get_attr_cc (insn))
1208 case CC_NONE:
1209 /* Insn does not affect CC at all. */
1210 break;
1212 case CC_SET_N:
1213 CC_STATUS_INIT;
1214 break;
1216 case CC_SET_ZN:
1217 set = single_set (insn);
1218 CC_STATUS_INIT;
1219 if (set)
1221 cc_status.flags |= CC_NO_OVERFLOW;
1222 cc_status.value1 = SET_DEST (set);
1224 break;
1226 case CC_SET_CZN:
1227 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1228 The V flag may or may not be known but that's ok because
1229 alter_cond will change tests to use EQ/NE. */
1230 set = single_set (insn);
1231 CC_STATUS_INIT;
1232 if (set)
1234 cc_status.value1 = SET_DEST (set);
1235 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1237 break;
1239 case CC_COMPARE:
1240 set = single_set (insn);
1241 CC_STATUS_INIT;
1242 if (set)
1243 cc_status.value1 = SET_SRC (set);
1244 break;
1246 case CC_CLOBBER:
1247 /* Insn doesn't leave CC in a usable state. */
1248 CC_STATUS_INIT;
1250 /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1251 set = single_set (insn);
1252 if (set)
1254 rtx src = SET_SRC (set);
1256 if (GET_CODE (src) == ASHIFTRT
1257 && GET_MODE (src) == QImode)
1259 rtx x = XEXP (src, 1);
1261 if (GET_CODE (x) == CONST_INT
1262 && INTVAL (x) > 0
1263 && INTVAL (x) != 6)
1265 cc_status.value1 = SET_DEST (set);
1266 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1270 break;
1274 /* Return maximum number of consecutive registers of
1275 class CLASS needed to hold a value of mode MODE. */
1278 class_max_nregs (enum reg_class class ATTRIBUTE_UNUSED,enum machine_mode mode)
1280 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1283 /* Choose mode for jump insn:
1284 1 - relative jump in range -63 <= x <= 62 ;
1285 2 - relative jump in range -2046 <= x <= 2045 ;
1286 3 - absolute jump (only for ATmega[16]03). */
1289 avr_jump_mode (rtx x, rtx insn)
1291 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1292 ? XEXP (x, 0) : x));
1293 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1294 int jump_distance = cur_addr - dest_addr;
1296 if (-63 <= jump_distance && jump_distance <= 62)
1297 return 1;
1298 else if (-2046 <= jump_distance && jump_distance <= 2045)
1299 return 2;
1300 else if (AVR_MEGA)
1301 return 3;
1303 return 2;
1306 /* return an AVR condition jump commands.
1307 X is a comparison RTX.
1308 LEN is a number returned by avr_jump_mode function.
1309 if REVERSE nonzero then condition code in X must be reversed. */
1311 const char *
1312 ret_cond_branch (rtx x, int len, int reverse)
1314 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1316 switch (cond)
1318 case GT:
1319 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1320 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1321 AS1 (brpl,%0)) :
1322 len == 2 ? (AS1 (breq,.+4) CR_TAB
1323 AS1 (brmi,.+2) CR_TAB
1324 AS1 (rjmp,%0)) :
1325 (AS1 (breq,.+6) CR_TAB
1326 AS1 (brmi,.+4) CR_TAB
1327 AS1 (jmp,%0)));
1329 else
1330 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1331 AS1 (brge,%0)) :
1332 len == 2 ? (AS1 (breq,.+4) CR_TAB
1333 AS1 (brlt,.+2) CR_TAB
1334 AS1 (rjmp,%0)) :
1335 (AS1 (breq,.+6) CR_TAB
1336 AS1 (brlt,.+4) CR_TAB
1337 AS1 (jmp,%0)));
1338 case GTU:
1339 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1340 AS1 (brsh,%0)) :
1341 len == 2 ? (AS1 (breq,.+4) CR_TAB
1342 AS1 (brlo,.+2) CR_TAB
1343 AS1 (rjmp,%0)) :
1344 (AS1 (breq,.+6) CR_TAB
1345 AS1 (brlo,.+4) CR_TAB
1346 AS1 (jmp,%0)));
1347 case LE:
1348 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1349 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1350 AS1 (brmi,%0)) :
1351 len == 2 ? (AS1 (breq,.+2) CR_TAB
1352 AS1 (brpl,.+2) CR_TAB
1353 AS1 (rjmp,%0)) :
1354 (AS1 (breq,.+2) CR_TAB
1355 AS1 (brpl,.+4) CR_TAB
1356 AS1 (jmp,%0)));
1357 else
1358 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1359 AS1 (brlt,%0)) :
1360 len == 2 ? (AS1 (breq,.+2) CR_TAB
1361 AS1 (brge,.+2) CR_TAB
1362 AS1 (rjmp,%0)) :
1363 (AS1 (breq,.+2) CR_TAB
1364 AS1 (brge,.+4) CR_TAB
1365 AS1 (jmp,%0)));
1366 case LEU:
1367 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1368 AS1 (brlo,%0)) :
1369 len == 2 ? (AS1 (breq,.+2) CR_TAB
1370 AS1 (brsh,.+2) CR_TAB
1371 AS1 (rjmp,%0)) :
1372 (AS1 (breq,.+2) CR_TAB
1373 AS1 (brsh,.+4) CR_TAB
1374 AS1 (jmp,%0)));
1375 default:
1376 if (reverse)
1378 switch (len)
1380 case 1:
1381 return AS1 (br%k1,%0);
1382 case 2:
1383 return (AS1 (br%j1,.+2) CR_TAB
1384 AS1 (rjmp,%0));
1385 default:
1386 return (AS1 (br%j1,.+4) CR_TAB
1387 AS1 (jmp,%0));
1390 else
1392 switch (len)
1394 case 1:
1395 return AS1 (br%j1,%0);
1396 case 2:
1397 return (AS1 (br%k1,.+2) CR_TAB
1398 AS1 (rjmp,%0));
1399 default:
1400 return (AS1 (br%k1,.+4) CR_TAB
1401 AS1 (jmp,%0));
1405 return "";
1408 /* Predicate function for immediate operand which fits to byte (8bit) */
1411 byte_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1413 return (GET_CODE (op) == CONST_INT
1414 && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1417 /* Output all insn addresses and their sizes into the assembly language
1418 output file. This is helpful for debugging whether the length attributes
1419 in the md file are correct.
1420 Output insn cost for next insn. */
1422 void
1423 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
1424 int num_operands ATTRIBUTE_UNUSED)
1426 int uid = INSN_UID (insn);
1428 if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1430 fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1431 INSN_ADDRESSES (uid),
1432 INSN_ADDRESSES (uid) - last_insn_address,
1433 rtx_cost (PATTERN (insn), INSN));
1435 last_insn_address = INSN_ADDRESSES (uid);
1438 /* Return 0 if undefined, 1 if always true or always false. */
1441 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE operator, rtx x)
1443 unsigned int max = (mode == QImode ? 0xff :
1444 mode == HImode ? 0xffff :
1445 mode == SImode ? 0xffffffff : 0);
1446 if (max && operator && GET_CODE (x) == CONST_INT)
1448 if (unsigned_condition (operator) != operator)
1449 max >>= 1;
1451 if (max != (INTVAL (x) & max)
1452 && INTVAL (x) != 0xff)
1453 return 1;
1455 return 0;
1459 /* Returns nonzero if REGNO is the number of a hard
1460 register in which function arguments are sometimes passed. */
1463 function_arg_regno_p(int r)
1465 return (r >= 8 && r <= 25);
1468 /* Initializing the variable cum for the state at the beginning
1469 of the argument list. */
1471 void
1472 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
1473 tree fndecl ATTRIBUTE_UNUSED)
1475 cum->nregs = 18;
1476 cum->regno = FIRST_CUM_REG;
1477 if (!libname && fntype)
1479 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1480 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1481 != void_type_node));
1482 if (stdarg)
1483 cum->nregs = 0;
1487 /* Returns the number of registers to allocate for a function argument. */
1489 static int
1490 avr_num_arg_regs (enum machine_mode mode, tree type)
1492 int size;
1494 if (mode == BLKmode)
1495 size = int_size_in_bytes (type);
1496 else
1497 size = GET_MODE_SIZE (mode);
1499 /* Align all function arguments to start in even-numbered registers.
1500 Odd-sized arguments leave holes above them. */
1502 return (size + 1) & ~1;
1505 /* Controls whether a function argument is passed
1506 in a register, and which register. */
1509 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1510 int named ATTRIBUTE_UNUSED)
1512 int bytes = avr_num_arg_regs (mode, type);
1514 if (cum->nregs && bytes <= cum->nregs)
1515 return gen_rtx_REG (mode, cum->regno - bytes);
1517 return NULL_RTX;
1520 /* Update the summarizer variable CUM to advance past an argument
1521 in the argument list. */
1523 void
1524 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1525 int named ATTRIBUTE_UNUSED)
1527 int bytes = avr_num_arg_regs (mode, type);
1529 cum->nregs -= bytes;
1530 cum->regno -= bytes;
1532 if (cum->nregs <= 0)
1534 cum->nregs = 0;
1535 cum->regno = FIRST_CUM_REG;
1539 /***********************************************************************
1540 Functions for outputting various mov's for a various modes
1541 ************************************************************************/
1542 const char *
1543 output_movqi (rtx insn, rtx operands[], int *l)
1545 int dummy;
1546 rtx dest = operands[0];
1547 rtx src = operands[1];
1548 int *real_l = l;
1550 if (!l)
1551 l = &dummy;
1553 *l = 1;
1555 if (register_operand (dest, QImode))
1557 if (register_operand (src, QImode)) /* mov r,r */
1559 if (test_hard_reg_class (STACK_REG, dest))
1560 return AS2 (out,%0,%1);
1561 else if (test_hard_reg_class (STACK_REG, src))
1562 return AS2 (in,%0,%1);
1564 return AS2 (mov,%0,%1);
1566 else if (CONSTANT_P (src))
1568 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1569 return AS2 (ldi,%0,lo8(%1));
1571 if (GET_CODE (src) == CONST_INT)
1573 if (src == const0_rtx) /* mov r,L */
1574 return AS1 (clr,%0);
1575 else if (src == const1_rtx)
1577 *l = 2;
1578 return (AS1 (clr,%0) CR_TAB
1579 AS1 (inc,%0));
1581 else if (src == constm1_rtx)
1583 /* Immediate constants -1 to any register */
1584 *l = 2;
1585 return (AS1 (clr,%0) CR_TAB
1586 AS1 (dec,%0));
1588 else
1590 int bit_nr = exact_log2 (INTVAL (src));
1592 if (bit_nr >= 0)
1594 *l = 3;
1595 if (!real_l)
1596 output_asm_insn ((AS1 (clr,%0) CR_TAB
1597 "set"), operands);
1598 if (!real_l)
1599 avr_output_bld (operands, bit_nr);
1601 return "";
1606 /* Last resort, larger than loading from memory. */
1607 *l = 4;
1608 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1609 AS2 (ldi,r31,lo8(%1)) CR_TAB
1610 AS2 (mov,%0,r31) CR_TAB
1611 AS2 (mov,r31,__tmp_reg__));
1613 else if (GET_CODE (src) == MEM)
1614 return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1616 else if (GET_CODE (dest) == MEM)
1618 const char *template;
1620 if (src == const0_rtx)
1621 operands[1] = zero_reg_rtx;
1623 template = out_movqi_mr_r (insn, operands, real_l);
1625 if (!real_l)
1626 output_asm_insn (template, operands);
1628 operands[1] = src;
1630 return "";
1634 const char *
1635 output_movhi (rtx insn, rtx operands[], int *l)
1637 int dummy;
1638 rtx dest = operands[0];
1639 rtx src = operands[1];
1640 int *real_l = l;
1642 if (!l)
1643 l = &dummy;
1645 if (register_operand (dest, HImode))
1647 if (register_operand (src, HImode)) /* mov r,r */
1649 if (test_hard_reg_class (STACK_REG, dest))
1651 if (TARGET_TINY_STACK)
1653 *l = 1;
1654 return AS2 (out,__SP_L__,%A1);
1656 else if (TARGET_NO_INTERRUPTS)
1658 *l = 2;
1659 return (AS2 (out,__SP_H__,%B1) CR_TAB
1660 AS2 (out,__SP_L__,%A1));
1663 *l = 5;
1664 return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB
1665 "cli" CR_TAB
1666 AS2 (out,__SP_H__,%B1) CR_TAB
1667 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1668 AS2 (out,__SP_L__,%A1));
1670 else if (test_hard_reg_class (STACK_REG, src))
1672 *l = 2;
1673 return (AS2 (in,%A0,__SP_L__) CR_TAB
1674 AS2 (in,%B0,__SP_H__));
1677 if (AVR_ENHANCED)
1679 *l = 1;
1680 return (AS2 (movw,%0,%1));
1683 if (true_regnum (dest) > true_regnum (src))
1685 *l = 2;
1686 return (AS2 (mov,%B0,%B1) CR_TAB
1687 AS2 (mov,%A0,%A1));
1689 else
1691 *l = 2;
1692 return (AS2 (mov,%A0,%A1) CR_TAB
1693 AS2 (mov,%B0,%B1));
1696 else if (CONSTANT_P (src))
1698 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1700 *l = 2;
1701 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1702 AS2 (ldi,%B0,hi8(%1)));
1705 if (GET_CODE (src) == CONST_INT)
1707 if (src == const0_rtx) /* mov r,L */
1709 *l = 2;
1710 return (AS1 (clr,%A0) CR_TAB
1711 AS1 (clr,%B0));
1713 else if (src == const1_rtx)
1715 *l = 3;
1716 return (AS1 (clr,%A0) CR_TAB
1717 AS1 (clr,%B0) CR_TAB
1718 AS1 (inc,%A0));
1720 else if (src == constm1_rtx)
1722 /* Immediate constants -1 to any register */
1723 *l = 3;
1724 return (AS1 (clr,%0) CR_TAB
1725 AS1 (dec,%A0) CR_TAB
1726 AS2 (mov,%B0,%A0));
1728 else
1730 int bit_nr = exact_log2 (INTVAL (src));
1732 if (bit_nr >= 0)
1734 *l = 4;
1735 if (!real_l)
1736 output_asm_insn ((AS1 (clr,%A0) CR_TAB
1737 AS1 (clr,%B0) CR_TAB
1738 "set"), operands);
1739 if (!real_l)
1740 avr_output_bld (operands, bit_nr);
1742 return "";
1746 if ((INTVAL (src) & 0xff) == 0)
1748 *l = 5;
1749 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1750 AS1 (clr,%A0) CR_TAB
1751 AS2 (ldi,r31,hi8(%1)) CR_TAB
1752 AS2 (mov,%B0,r31) CR_TAB
1753 AS2 (mov,r31,__tmp_reg__));
1755 else if ((INTVAL (src) & 0xff00) == 0)
1757 *l = 5;
1758 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1759 AS2 (ldi,r31,lo8(%1)) CR_TAB
1760 AS2 (mov,%A0,r31) CR_TAB
1761 AS1 (clr,%B0) CR_TAB
1762 AS2 (mov,r31,__tmp_reg__));
1766 /* Last resort, equal to loading from memory. */
1767 *l = 6;
1768 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1769 AS2 (ldi,r31,lo8(%1)) CR_TAB
1770 AS2 (mov,%A0,r31) CR_TAB
1771 AS2 (ldi,r31,hi8(%1)) CR_TAB
1772 AS2 (mov,%B0,r31) CR_TAB
1773 AS2 (mov,r31,__tmp_reg__));
1775 else if (GET_CODE (src) == MEM)
1776 return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1778 else if (GET_CODE (dest) == MEM)
1780 const char *template;
1782 if (src == const0_rtx)
1783 operands[1] = zero_reg_rtx;
1785 template = out_movhi_mr_r (insn, operands, real_l);
1787 if (!real_l)
1788 output_asm_insn (template, operands);
1790 operands[1] = src;
1791 return "";
1793 fatal_insn ("invalid insn:", insn);
1794 return "";
1797 const char *
1798 out_movqi_r_mr (rtx insn, rtx op[], int *l)
1800 rtx dest = op[0];
1801 rtx src = op[1];
1802 rtx x = XEXP (src, 0);
1803 int dummy;
1805 if (!l)
1806 l = &dummy;
1808 if (CONSTANT_ADDRESS_P (x))
1810 if (avr_io_address_p (x, 1))
1812 *l = 1;
1813 return AS2 (in,%0,%1-0x20);
1815 *l = 2;
1816 return AS2 (lds,%0,%1);
1818 /* memory access by reg+disp */
1819 else if (GET_CODE (x) == PLUS
1820 && REG_P (XEXP (x,0))
1821 && GET_CODE (XEXP (x,1)) == CONST_INT)
1823 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1825 int disp = INTVAL (XEXP (x,1));
1826 if (REGNO (XEXP (x,0)) != REG_Y)
1827 fatal_insn ("incorrect insn:",insn);
1829 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1830 return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
1831 AS2 (ldd,%0,Y+63) CR_TAB
1832 AS2 (sbiw,r28,%o1-63));
1834 return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1835 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1836 AS2 (ld,%0,Y) CR_TAB
1837 AS2 (subi,r28,lo8(%o1)) CR_TAB
1838 AS2 (sbci,r29,hi8(%o1)));
1840 else if (REGNO (XEXP (x,0)) == REG_X)
1842 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1843 it but I have this situation with extremal optimizing options. */
1844 if (reg_overlap_mentioned_p (dest, XEXP (x,0))
1845 || reg_unused_after (insn, XEXP (x,0)))
1846 return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
1847 AS2 (ld,%0,X));
1849 return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
1850 AS2 (ld,%0,X) CR_TAB
1851 AS2 (sbiw,r26,%o1));
1853 *l = 1;
1854 return AS2 (ldd,%0,%1);
1856 *l = 1;
1857 return AS2 (ld,%0,%1);
1860 const char *
1861 out_movhi_r_mr (rtx insn, rtx op[], int *l)
1863 rtx dest = op[0];
1864 rtx src = op[1];
1865 rtx base = XEXP (src, 0);
1866 int reg_dest = true_regnum (dest);
1867 int reg_base = true_regnum (base);
1868 /* "volatile" forces reading low byte first, even if less efficient,
1869 for correct operation with 16-bit I/O registers. */
1870 int mem_volatile_p = MEM_VOLATILE_P (src);
1871 int tmp;
1873 if (!l)
1874 l = &tmp;
1876 if (reg_base > 0)
1878 if (reg_dest == reg_base) /* R = (R) */
1880 *l = 3;
1881 return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1882 AS2 (ld,%B0,%1) CR_TAB
1883 AS2 (mov,%A0,__tmp_reg__));
1885 else if (reg_base == REG_X) /* (R26) */
1887 if (reg_unused_after (insn, base))
1889 *l = 2;
1890 return (AS2 (ld,%A0,X+) CR_TAB
1891 AS2 (ld,%B0,X));
1893 *l = 3;
1894 return (AS2 (ld,%A0,X+) CR_TAB
1895 AS2 (ld,%B0,X) CR_TAB
1896 AS2 (sbiw,r26,1));
1898 else /* (R) */
1900 *l = 2;
1901 return (AS2 (ld,%A0,%1) CR_TAB
1902 AS2 (ldd,%B0,%1+1));
1905 else if (GET_CODE (base) == PLUS) /* (R + i) */
1907 int disp = INTVAL (XEXP (base, 1));
1908 int reg_base = true_regnum (XEXP (base, 0));
1910 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
1912 if (REGNO (XEXP (base, 0)) != REG_Y)
1913 fatal_insn ("incorrect insn:",insn);
1915 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1916 return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
1917 AS2 (ldd,%A0,Y+62) CR_TAB
1918 AS2 (ldd,%B0,Y+63) CR_TAB
1919 AS2 (sbiw,r28,%o1-62));
1921 return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1922 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1923 AS2 (ld,%A0,Y) CR_TAB
1924 AS2 (ldd,%B0,Y+1) CR_TAB
1925 AS2 (subi,r28,lo8(%o1)) CR_TAB
1926 AS2 (sbci,r29,hi8(%o1)));
1928 if (reg_base == REG_X)
1930 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1931 it but I have this situation with extremal
1932 optimization options. */
1934 *l = 4;
1935 if (reg_base == reg_dest)
1936 return (AS2 (adiw,r26,%o1) CR_TAB
1937 AS2 (ld,__tmp_reg__,X+) CR_TAB
1938 AS2 (ld,%B0,X) CR_TAB
1939 AS2 (mov,%A0,__tmp_reg__));
1941 return (AS2 (adiw,r26,%o1) CR_TAB
1942 AS2 (ld,%A0,X+) CR_TAB
1943 AS2 (ld,%B0,X) CR_TAB
1944 AS2 (sbiw,r26,%o1+1));
1947 if (reg_base == reg_dest)
1949 *l = 3;
1950 return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
1951 AS2 (ldd,%B0,%B1) CR_TAB
1952 AS2 (mov,%A0,__tmp_reg__));
1955 *l = 2;
1956 return (AS2 (ldd,%A0,%A1) CR_TAB
1957 AS2 (ldd,%B0,%B1));
1959 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
1961 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1962 fatal_insn ("incorrect insn:", insn);
1964 if (mem_volatile_p)
1966 if (REGNO (XEXP (base, 0)) == REG_X)
1968 *l = 4;
1969 return (AS2 (sbiw,r26,2) CR_TAB
1970 AS2 (ld,%A0,X+) CR_TAB
1971 AS2 (ld,%B0,X) CR_TAB
1972 AS2 (sbiw,r26,1));
1974 else
1976 *l = 3;
1977 return (AS2 (sbiw,%r1,2) CR_TAB
1978 AS2 (ld,%A0,%p1) CR_TAB
1979 AS2 (ldd,%B0,%p1+1));
1983 *l = 2;
1984 return (AS2 (ld,%B0,%1) CR_TAB
1985 AS2 (ld,%A0,%1));
1987 else if (GET_CODE (base) == POST_INC) /* (R++) */
1989 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1990 fatal_insn ("incorrect insn:", insn);
1992 *l = 2;
1993 return (AS2 (ld,%A0,%1) CR_TAB
1994 AS2 (ld,%B0,%1));
1996 else if (CONSTANT_ADDRESS_P (base))
1998 if (avr_io_address_p (base, 2))
2000 *l = 2;
2001 return (AS2 (in,%A0,%A1-0x20) CR_TAB
2002 AS2 (in,%B0,%B1-0x20));
2004 *l = 4;
2005 return (AS2 (lds,%A0,%A1) CR_TAB
2006 AS2 (lds,%B0,%B1));
2009 fatal_insn ("unknown move insn:",insn);
2010 return "";
2013 const char *
2014 out_movsi_r_mr (rtx insn, rtx op[], int *l)
2016 rtx dest = op[0];
2017 rtx src = op[1];
2018 rtx base = XEXP (src, 0);
2019 int reg_dest = true_regnum (dest);
2020 int reg_base = true_regnum (base);
2021 int tmp;
2023 if (!l)
2024 l = &tmp;
2026 if (reg_base > 0)
2028 if (reg_base == REG_X) /* (R26) */
2030 if (reg_dest == REG_X)
2031 /* "ld r26,-X" is undefined */
2032 return *l=7, (AS2 (adiw,r26,3) CR_TAB
2033 AS2 (ld,r29,X) CR_TAB
2034 AS2 (ld,r28,-X) CR_TAB
2035 AS2 (ld,__tmp_reg__,-X) CR_TAB
2036 AS2 (sbiw,r26,1) CR_TAB
2037 AS2 (ld,r26,X) CR_TAB
2038 AS2 (mov,r27,__tmp_reg__));
2039 else if (reg_dest == REG_X - 2)
2040 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2041 AS2 (ld,%B0,X+) CR_TAB
2042 AS2 (ld,__tmp_reg__,X+) CR_TAB
2043 AS2 (ld,%D0,X) CR_TAB
2044 AS2 (mov,%C0,__tmp_reg__));
2045 else if (reg_unused_after (insn, base))
2046 return *l=4, (AS2 (ld,%A0,X+) CR_TAB
2047 AS2 (ld,%B0,X+) CR_TAB
2048 AS2 (ld,%C0,X+) CR_TAB
2049 AS2 (ld,%D0,X));
2050 else
2051 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2052 AS2 (ld,%B0,X+) CR_TAB
2053 AS2 (ld,%C0,X+) CR_TAB
2054 AS2 (ld,%D0,X) CR_TAB
2055 AS2 (sbiw,r26,3));
2057 else
2059 if (reg_dest == reg_base)
2060 return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
2061 AS2 (ldd,%C0,%1+2) CR_TAB
2062 AS2 (ldd,__tmp_reg__,%1+1) CR_TAB
2063 AS2 (ld,%A0,%1) CR_TAB
2064 AS2 (mov,%B0,__tmp_reg__));
2065 else if (reg_base == reg_dest + 2)
2066 return *l=5, (AS2 (ld ,%A0,%1) CR_TAB
2067 AS2 (ldd,%B0,%1+1) CR_TAB
2068 AS2 (ldd,__tmp_reg__,%1+2) CR_TAB
2069 AS2 (ldd,%D0,%1+3) CR_TAB
2070 AS2 (mov,%C0,__tmp_reg__));
2071 else
2072 return *l=4, (AS2 (ld ,%A0,%1) CR_TAB
2073 AS2 (ldd,%B0,%1+1) CR_TAB
2074 AS2 (ldd,%C0,%1+2) CR_TAB
2075 AS2 (ldd,%D0,%1+3));
2078 else if (GET_CODE (base) == PLUS) /* (R + i) */
2080 int disp = INTVAL (XEXP (base, 1));
2082 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2084 if (REGNO (XEXP (base, 0)) != REG_Y)
2085 fatal_insn ("incorrect insn:",insn);
2087 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2088 return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2089 AS2 (ldd,%A0,Y+60) CR_TAB
2090 AS2 (ldd,%B0,Y+61) CR_TAB
2091 AS2 (ldd,%C0,Y+62) CR_TAB
2092 AS2 (ldd,%D0,Y+63) CR_TAB
2093 AS2 (sbiw,r28,%o1-60));
2095 return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2096 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2097 AS2 (ld,%A0,Y) CR_TAB
2098 AS2 (ldd,%B0,Y+1) CR_TAB
2099 AS2 (ldd,%C0,Y+2) CR_TAB
2100 AS2 (ldd,%D0,Y+3) CR_TAB
2101 AS2 (subi,r28,lo8(%o1)) CR_TAB
2102 AS2 (sbci,r29,hi8(%o1)));
2105 reg_base = true_regnum (XEXP (base, 0));
2106 if (reg_base == REG_X)
2108 /* R = (X + d) */
2109 if (reg_dest == REG_X)
2111 *l = 7;
2112 /* "ld r26,-X" is undefined */
2113 return (AS2 (adiw,r26,%o1+3) CR_TAB
2114 AS2 (ld,r29,X) CR_TAB
2115 AS2 (ld,r28,-X) CR_TAB
2116 AS2 (ld,__tmp_reg__,-X) CR_TAB
2117 AS2 (sbiw,r26,1) CR_TAB
2118 AS2 (ld,r26,X) CR_TAB
2119 AS2 (mov,r27,__tmp_reg__));
2121 *l = 6;
2122 if (reg_dest == REG_X - 2)
2123 return (AS2 (adiw,r26,%o1) CR_TAB
2124 AS2 (ld,r24,X+) CR_TAB
2125 AS2 (ld,r25,X+) CR_TAB
2126 AS2 (ld,__tmp_reg__,X+) CR_TAB
2127 AS2 (ld,r27,X) CR_TAB
2128 AS2 (mov,r26,__tmp_reg__));
2130 return (AS2 (adiw,r26,%o1) CR_TAB
2131 AS2 (ld,%A0,X+) CR_TAB
2132 AS2 (ld,%B0,X+) CR_TAB
2133 AS2 (ld,%C0,X+) CR_TAB
2134 AS2 (ld,%D0,X) CR_TAB
2135 AS2 (sbiw,r26,%o1+3));
2137 if (reg_dest == reg_base)
2138 return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2139 AS2 (ldd,%C0,%C1) CR_TAB
2140 AS2 (ldd,__tmp_reg__,%B1) CR_TAB
2141 AS2 (ldd,%A0,%A1) CR_TAB
2142 AS2 (mov,%B0,__tmp_reg__));
2143 else if (reg_dest == reg_base - 2)
2144 return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2145 AS2 (ldd,%B0,%B1) CR_TAB
2146 AS2 (ldd,__tmp_reg__,%C1) CR_TAB
2147 AS2 (ldd,%D0,%D1) CR_TAB
2148 AS2 (mov,%C0,__tmp_reg__));
2149 return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2150 AS2 (ldd,%B0,%B1) CR_TAB
2151 AS2 (ldd,%C0,%C1) CR_TAB
2152 AS2 (ldd,%D0,%D1));
2154 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2155 return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2156 AS2 (ld,%C0,%1) CR_TAB
2157 AS2 (ld,%B0,%1) CR_TAB
2158 AS2 (ld,%A0,%1));
2159 else if (GET_CODE (base) == POST_INC) /* (R++) */
2160 return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2161 AS2 (ld,%B0,%1) CR_TAB
2162 AS2 (ld,%C0,%1) CR_TAB
2163 AS2 (ld,%D0,%1));
2164 else if (CONSTANT_ADDRESS_P (base))
2165 return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2166 AS2 (lds,%B0,%B1) CR_TAB
2167 AS2 (lds,%C0,%C1) CR_TAB
2168 AS2 (lds,%D0,%D1));
2170 fatal_insn ("unknown move insn:",insn);
2171 return "";
2174 const char *
2175 out_movsi_mr_r (rtx insn, rtx op[], int *l)
2177 rtx dest = op[0];
2178 rtx src = op[1];
2179 rtx base = XEXP (dest, 0);
2180 int reg_base = true_regnum (base);
2181 int reg_src = true_regnum (src);
2182 int tmp;
2184 if (!l)
2185 l = &tmp;
2187 if (CONSTANT_ADDRESS_P (base))
2188 return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2189 AS2 (sts,%B0,%B1) CR_TAB
2190 AS2 (sts,%C0,%C1) CR_TAB
2191 AS2 (sts,%D0,%D1));
2192 if (reg_base > 0) /* (r) */
2194 if (reg_base == REG_X) /* (R26) */
2196 if (reg_src == REG_X)
2198 /* "st X+,r26" is undefined */
2199 if (reg_unused_after (insn, base))
2200 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2201 AS2 (st,X,r26) CR_TAB
2202 AS2 (adiw,r26,1) CR_TAB
2203 AS2 (st,X+,__tmp_reg__) CR_TAB
2204 AS2 (st,X+,r28) CR_TAB
2205 AS2 (st,X,r29));
2206 else
2207 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2208 AS2 (st,X,r26) CR_TAB
2209 AS2 (adiw,r26,1) CR_TAB
2210 AS2 (st,X+,__tmp_reg__) CR_TAB
2211 AS2 (st,X+,r28) CR_TAB
2212 AS2 (st,X,r29) CR_TAB
2213 AS2 (sbiw,r26,3));
2215 else if (reg_base == reg_src + 2)
2217 if (reg_unused_after (insn, base))
2218 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2219 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2220 AS2 (st,%0+,%A1) CR_TAB
2221 AS2 (st,%0+,%B1) CR_TAB
2222 AS2 (st,%0+,__zero_reg__) CR_TAB
2223 AS2 (st,%0,__tmp_reg__) CR_TAB
2224 AS1 (clr,__zero_reg__));
2225 else
2226 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2227 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2228 AS2 (st,%0+,%A1) CR_TAB
2229 AS2 (st,%0+,%B1) CR_TAB
2230 AS2 (st,%0+,__zero_reg__) CR_TAB
2231 AS2 (st,%0,__tmp_reg__) CR_TAB
2232 AS1 (clr,__zero_reg__) CR_TAB
2233 AS2 (sbiw,r26,3));
2235 return *l=5, (AS2 (st,%0+,%A1) CR_TAB
2236 AS2 (st,%0+,%B1) CR_TAB
2237 AS2 (st,%0+,%C1) CR_TAB
2238 AS2 (st,%0,%D1) CR_TAB
2239 AS2 (sbiw,r26,3));
2241 else
2242 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2243 AS2 (std,%0+1,%B1) CR_TAB
2244 AS2 (std,%0+2,%C1) CR_TAB
2245 AS2 (std,%0+3,%D1));
2247 else if (GET_CODE (base) == PLUS) /* (R + i) */
2249 int disp = INTVAL (XEXP (base, 1));
2250 reg_base = REGNO (XEXP (base, 0));
2251 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2253 if (reg_base != REG_Y)
2254 fatal_insn ("incorrect insn:",insn);
2256 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2257 return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2258 AS2 (std,Y+60,%A1) CR_TAB
2259 AS2 (std,Y+61,%B1) CR_TAB
2260 AS2 (std,Y+62,%C1) CR_TAB
2261 AS2 (std,Y+63,%D1) CR_TAB
2262 AS2 (sbiw,r28,%o0-60));
2264 return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2265 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2266 AS2 (st,Y,%A1) CR_TAB
2267 AS2 (std,Y+1,%B1) CR_TAB
2268 AS2 (std,Y+2,%C1) CR_TAB
2269 AS2 (std,Y+3,%D1) CR_TAB
2270 AS2 (subi,r28,lo8(%o0)) CR_TAB
2271 AS2 (sbci,r29,hi8(%o0)));
2273 if (reg_base == REG_X)
2275 /* (X + d) = R */
2276 if (reg_src == REG_X)
2278 *l = 9;
2279 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2280 AS2 (mov,__zero_reg__,r27) CR_TAB
2281 AS2 (adiw,r26,%o0) CR_TAB
2282 AS2 (st,X+,__tmp_reg__) CR_TAB
2283 AS2 (st,X+,__zero_reg__) CR_TAB
2284 AS2 (st,X+,r28) CR_TAB
2285 AS2 (st,X,r29) CR_TAB
2286 AS1 (clr,__zero_reg__) CR_TAB
2287 AS2 (sbiw,r26,%o0+3));
2289 else if (reg_src == REG_X - 2)
2291 *l = 9;
2292 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2293 AS2 (mov,__zero_reg__,r27) CR_TAB
2294 AS2 (adiw,r26,%o0) CR_TAB
2295 AS2 (st,X+,r24) CR_TAB
2296 AS2 (st,X+,r25) CR_TAB
2297 AS2 (st,X+,__tmp_reg__) CR_TAB
2298 AS2 (st,X,__zero_reg__) CR_TAB
2299 AS1 (clr,__zero_reg__) CR_TAB
2300 AS2 (sbiw,r26,%o0+3));
2302 *l = 6;
2303 return (AS2 (adiw,r26,%o0) CR_TAB
2304 AS2 (st,X+,%A1) CR_TAB
2305 AS2 (st,X+,%B1) CR_TAB
2306 AS2 (st,X+,%C1) CR_TAB
2307 AS2 (st,X,%D1) CR_TAB
2308 AS2 (sbiw,r26,%o0+3));
2310 return *l=4, (AS2 (std,%A0,%A1) CR_TAB
2311 AS2 (std,%B0,%B1) CR_TAB
2312 AS2 (std,%C0,%C1) CR_TAB
2313 AS2 (std,%D0,%D1));
2315 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2316 return *l=4, (AS2 (st,%0,%D1) CR_TAB
2317 AS2 (st,%0,%C1) CR_TAB
2318 AS2 (st,%0,%B1) CR_TAB
2319 AS2 (st,%0,%A1));
2320 else if (GET_CODE (base) == POST_INC) /* (R++) */
2321 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2322 AS2 (st,%0,%B1) CR_TAB
2323 AS2 (st,%0,%C1) CR_TAB
2324 AS2 (st,%0,%D1));
2325 fatal_insn ("unknown move insn:",insn);
2326 return "";
2329 const char *
2330 output_movsisf(rtx insn, rtx operands[], int *l)
2332 int dummy;
2333 rtx dest = operands[0];
2334 rtx src = operands[1];
2335 int *real_l = l;
2337 if (!l)
2338 l = &dummy;
2340 if (register_operand (dest, VOIDmode))
2342 if (register_operand (src, VOIDmode)) /* mov r,r */
2344 if (true_regnum (dest) > true_regnum (src))
2346 if (AVR_ENHANCED)
2348 *l = 2;
2349 return (AS2 (movw,%C0,%C1) CR_TAB
2350 AS2 (movw,%A0,%A1));
2352 *l = 4;
2353 return (AS2 (mov,%D0,%D1) CR_TAB
2354 AS2 (mov,%C0,%C1) CR_TAB
2355 AS2 (mov,%B0,%B1) CR_TAB
2356 AS2 (mov,%A0,%A1));
2358 else
2360 if (AVR_ENHANCED)
2362 *l = 2;
2363 return (AS2 (movw,%A0,%A1) CR_TAB
2364 AS2 (movw,%C0,%C1));
2366 *l = 4;
2367 return (AS2 (mov,%A0,%A1) CR_TAB
2368 AS2 (mov,%B0,%B1) CR_TAB
2369 AS2 (mov,%C0,%C1) CR_TAB
2370 AS2 (mov,%D0,%D1));
2373 else if (CONSTANT_P (src))
2375 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2377 *l = 4;
2378 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
2379 AS2 (ldi,%B0,hi8(%1)) CR_TAB
2380 AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2381 AS2 (ldi,%D0,hhi8(%1)));
2384 if (GET_CODE (src) == CONST_INT)
2386 const char *const clr_op0 =
2387 AVR_ENHANCED ? (AS1 (clr,%A0) CR_TAB
2388 AS1 (clr,%B0) CR_TAB
2389 AS2 (movw,%C0,%A0))
2390 : (AS1 (clr,%A0) CR_TAB
2391 AS1 (clr,%B0) CR_TAB
2392 AS1 (clr,%C0) CR_TAB
2393 AS1 (clr,%D0));
2395 if (src == const0_rtx) /* mov r,L */
2397 *l = AVR_ENHANCED ? 3 : 4;
2398 return clr_op0;
2400 else if (src == const1_rtx)
2402 if (!real_l)
2403 output_asm_insn (clr_op0, operands);
2404 *l = AVR_ENHANCED ? 4 : 5;
2405 return AS1 (inc,%A0);
2407 else if (src == constm1_rtx)
2409 /* Immediate constants -1 to any register */
2410 if (AVR_ENHANCED)
2412 *l = 4;
2413 return (AS1 (clr,%A0) CR_TAB
2414 AS1 (dec,%A0) CR_TAB
2415 AS2 (mov,%B0,%A0) CR_TAB
2416 AS2 (movw,%C0,%A0));
2418 *l = 5;
2419 return (AS1 (clr,%A0) CR_TAB
2420 AS1 (dec,%A0) CR_TAB
2421 AS2 (mov,%B0,%A0) CR_TAB
2422 AS2 (mov,%C0,%A0) CR_TAB
2423 AS2 (mov,%D0,%A0));
2425 else
2427 int bit_nr = exact_log2 (INTVAL (src));
2429 if (bit_nr >= 0)
2431 *l = AVR_ENHANCED ? 5 : 6;
2432 if (!real_l)
2434 output_asm_insn (clr_op0, operands);
2435 output_asm_insn ("set", operands);
2437 if (!real_l)
2438 avr_output_bld (operands, bit_nr);
2440 return "";
2445 /* Last resort, better than loading from memory. */
2446 *l = 10;
2447 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2448 AS2 (ldi,r31,lo8(%1)) CR_TAB
2449 AS2 (mov,%A0,r31) CR_TAB
2450 AS2 (ldi,r31,hi8(%1)) CR_TAB
2451 AS2 (mov,%B0,r31) CR_TAB
2452 AS2 (ldi,r31,hlo8(%1)) CR_TAB
2453 AS2 (mov,%C0,r31) CR_TAB
2454 AS2 (ldi,r31,hhi8(%1)) CR_TAB
2455 AS2 (mov,%D0,r31) CR_TAB
2456 AS2 (mov,r31,__tmp_reg__));
2458 else if (GET_CODE (src) == MEM)
2459 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2461 else if (GET_CODE (dest) == MEM)
2463 const char *template;
2465 if (src == const0_rtx)
2466 operands[1] = zero_reg_rtx;
2468 template = out_movsi_mr_r (insn, operands, real_l);
2470 if (!real_l)
2471 output_asm_insn (template, operands);
2473 operands[1] = src;
2474 return "";
2476 fatal_insn ("invalid insn:", insn);
2477 return "";
2480 const char *
2481 out_movqi_mr_r (rtx insn, rtx op[], int *l)
2483 rtx dest = op[0];
2484 rtx src = op[1];
2485 rtx x = XEXP (dest, 0);
2486 int dummy;
2488 if (!l)
2489 l = &dummy;
2491 if (CONSTANT_ADDRESS_P (x))
2493 if (avr_io_address_p (x, 1))
2495 *l = 1;
2496 return AS2 (out,%0-0x20,%1);
2498 *l = 2;
2499 return AS2 (sts,%0,%1);
2501 /* memory access by reg+disp */
2502 else if (GET_CODE (x) == PLUS
2503 && REG_P (XEXP (x,0))
2504 && GET_CODE (XEXP (x,1)) == CONST_INT)
2506 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2508 int disp = INTVAL (XEXP (x,1));
2509 if (REGNO (XEXP (x,0)) != REG_Y)
2510 fatal_insn ("incorrect insn:",insn);
2512 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2513 return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2514 AS2 (std,Y+63,%1) CR_TAB
2515 AS2 (sbiw,r28,%o0-63));
2517 return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2518 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2519 AS2 (st,Y,%1) CR_TAB
2520 AS2 (subi,r28,lo8(%o0)) CR_TAB
2521 AS2 (sbci,r29,hi8(%o0)));
2523 else if (REGNO (XEXP (x,0)) == REG_X)
2525 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2527 if (reg_unused_after (insn, XEXP (x,0)))
2528 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2529 AS2 (adiw,r26,%o0) CR_TAB
2530 AS2 (st,X,__tmp_reg__));
2532 return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2533 AS2 (adiw,r26,%o0) CR_TAB
2534 AS2 (st,X,__tmp_reg__) CR_TAB
2535 AS2 (sbiw,r26,%o0));
2537 else
2539 if (reg_unused_after (insn, XEXP (x,0)))
2540 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2541 AS2 (st,X,%1));
2543 return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2544 AS2 (st,X,%1) CR_TAB
2545 AS2 (sbiw,r26,%o0));
2548 *l = 1;
2549 return AS2 (std,%0,%1);
2551 *l = 1;
2552 return AS2 (st,%0,%1);
2555 const char *
2556 out_movhi_mr_r (rtx insn, rtx op[], int *l)
2558 rtx dest = op[0];
2559 rtx src = op[1];
2560 rtx base = XEXP (dest, 0);
2561 int reg_base = true_regnum (base);
2562 int reg_src = true_regnum (src);
2563 /* "volatile" forces writing high byte first, even if less efficient,
2564 for correct operation with 16-bit I/O registers. */
2565 int mem_volatile_p = MEM_VOLATILE_P (dest);
2566 int tmp;
2568 if (!l)
2569 l = &tmp;
2570 if (CONSTANT_ADDRESS_P (base))
2572 if (avr_io_address_p (base, 2))
2574 *l = 2;
2575 return (AS2 (out,%B0-0x20,%B1) CR_TAB
2576 AS2 (out,%A0-0x20,%A1));
2578 return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2579 AS2 (sts,%A0,%A1));
2581 if (reg_base > 0)
2583 if (reg_base == REG_X)
2585 if (reg_src == REG_X)
2587 /* "st X+,r26" and "st -X,r26" are undefined. */
2588 if (!mem_volatile_p && reg_unused_after (insn, src))
2589 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2590 AS2 (st,X,r26) CR_TAB
2591 AS2 (adiw,r26,1) CR_TAB
2592 AS2 (st,X,__tmp_reg__));
2593 else
2594 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2595 AS2 (adiw,r26,1) CR_TAB
2596 AS2 (st,X,__tmp_reg__) CR_TAB
2597 AS2 (sbiw,r26,1) CR_TAB
2598 AS2 (st,X,r26));
2600 else
2602 if (!mem_volatile_p && reg_unused_after (insn, base))
2603 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2604 AS2 (st,X,%B1));
2605 else
2606 return *l=3, (AS2 (adiw,r26,1) CR_TAB
2607 AS2 (st,X,%B1) CR_TAB
2608 AS2 (st,-X,%A1));
2611 else
2612 return *l=2, (AS2 (std,%0+1,%B1) CR_TAB
2613 AS2 (st,%0,%A1));
2615 else if (GET_CODE (base) == PLUS)
2617 int disp = INTVAL (XEXP (base, 1));
2618 reg_base = REGNO (XEXP (base, 0));
2619 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2621 if (reg_base != REG_Y)
2622 fatal_insn ("incorrect insn:",insn);
2624 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2625 return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2626 AS2 (std,Y+63,%B1) CR_TAB
2627 AS2 (std,Y+62,%A1) CR_TAB
2628 AS2 (sbiw,r28,%o0-62));
2630 return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2631 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2632 AS2 (std,Y+1,%B1) CR_TAB
2633 AS2 (st,Y,%A1) CR_TAB
2634 AS2 (subi,r28,lo8(%o0)) CR_TAB
2635 AS2 (sbci,r29,hi8(%o0)));
2637 if (reg_base == REG_X)
2639 /* (X + d) = R */
2640 if (reg_src == REG_X)
2642 *l = 7;
2643 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2644 AS2 (mov,__zero_reg__,r27) CR_TAB
2645 AS2 (adiw,r26,%o0+1) CR_TAB
2646 AS2 (st,X,__zero_reg__) CR_TAB
2647 AS2 (st,-X,__tmp_reg__) CR_TAB
2648 AS1 (clr,__zero_reg__) CR_TAB
2649 AS2 (sbiw,r26,%o0));
2651 *l = 4;
2652 return (AS2 (adiw,r26,%o0+1) CR_TAB
2653 AS2 (st,X,%B1) CR_TAB
2654 AS2 (st,-X,%A1) CR_TAB
2655 AS2 (sbiw,r26,%o0));
2657 return *l=2, (AS2 (std,%B0,%B1) CR_TAB
2658 AS2 (std,%A0,%A1));
2660 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2661 return *l=2, (AS2 (st,%0,%B1) CR_TAB
2662 AS2 (st,%0,%A1));
2663 else if (GET_CODE (base) == POST_INC) /* (R++) */
2665 if (mem_volatile_p)
2667 if (REGNO (XEXP (base, 0)) == REG_X)
2669 *l = 4;
2670 return (AS2 (adiw,r26,1) CR_TAB
2671 AS2 (st,X,%B1) CR_TAB
2672 AS2 (st,-X,%A1) CR_TAB
2673 AS2 (adiw,r26,2));
2675 else
2677 *l = 3;
2678 return (AS2 (std,%p0+1,%B1) CR_TAB
2679 AS2 (st,%p0,%A1) CR_TAB
2680 AS2 (adiw,%r0,2));
2684 *l = 2;
2685 return (AS2 (st,%0,%A1) CR_TAB
2686 AS2 (st,%0,%B1));
2688 fatal_insn ("unknown move insn:",insn);
2689 return "";
2692 /* Return 1 if frame pointer for current function required. */
2695 frame_pointer_required_p (void)
2697 return (current_function_calls_alloca
2698 || current_function_args_info.nregs == 0
2699 || get_frame_size () > 0);
2702 /* Returns the condition of compare insn INSN, or UNKNOWN. */
2704 static RTX_CODE
2705 compare_condition (rtx insn)
2707 rtx next = next_real_insn (insn);
2708 RTX_CODE cond = UNKNOWN;
2709 if (next && GET_CODE (next) == JUMP_INSN)
2711 rtx pat = PATTERN (next);
2712 rtx src = SET_SRC (pat);
2713 rtx t = XEXP (src, 0);
2714 cond = GET_CODE (t);
2716 return cond;
2719 /* Returns nonzero if INSN is a tst insn that only tests the sign. */
2721 static int
2722 compare_sign_p (rtx insn)
2724 RTX_CODE cond = compare_condition (insn);
2725 return (cond == GE || cond == LT);
2728 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
2729 that needs to be swapped (GT, GTU, LE, LEU). */
2732 compare_diff_p (rtx insn)
2734 RTX_CODE cond = compare_condition (insn);
2735 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2738 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition. */
2741 compare_eq_p (rtx insn)
2743 RTX_CODE cond = compare_condition (insn);
2744 return (cond == EQ || cond == NE);
2748 /* Output test instruction for HImode. */
2750 const char *
2751 out_tsthi (rtx insn, int *l)
2753 if (compare_sign_p (insn))
2755 if (l) *l = 1;
2756 return AS1 (tst,%B0);
2758 if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
2759 && compare_eq_p (insn))
2761 /* Faster than sbiw if we can clobber the operand. */
2762 if (l) *l = 1;
2763 return AS2 (or,%A0,%B0);
2765 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2767 if (l) *l = 1;
2768 return AS2 (sbiw,%0,0);
2770 if (l) *l = 2;
2771 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2772 AS2 (cpc,%B0,__zero_reg__));
2776 /* Output test instruction for SImode. */
2778 const char *
2779 out_tstsi (rtx insn, int *l)
2781 if (compare_sign_p (insn))
2783 if (l) *l = 1;
2784 return AS1 (tst,%D0);
2786 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2788 if (l) *l = 3;
2789 return (AS2 (sbiw,%A0,0) CR_TAB
2790 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2791 AS2 (cpc,%D0,__zero_reg__));
2793 if (l) *l = 4;
2794 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2795 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2796 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2797 AS2 (cpc,%D0,__zero_reg__));
2801 /* Generate asm equivalent for various shifts.
2802 Shift count is a CONST_INT, MEM or REG.
2803 This only handles cases that are not already
2804 carefully hand-optimized in ?sh??i3_out. */
2806 void
2807 out_shift_with_cnt (const char *template, rtx insn, rtx operands[],
2808 int *len, int t_len)
2810 rtx op[10];
2811 char str[500];
2812 int second_label = 1;
2813 int saved_in_tmp = 0;
2814 int use_zero_reg = 0;
2816 op[0] = operands[0];
2817 op[1] = operands[1];
2818 op[2] = operands[2];
2819 op[3] = operands[3];
2820 str[0] = 0;
2822 if (len)
2823 *len = 1;
2825 if (GET_CODE (operands[2]) == CONST_INT)
2827 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2828 int count = INTVAL (operands[2]);
2829 int max_len = 10; /* If larger than this, always use a loop. */
2831 if (count <= 0)
2833 if (len)
2834 *len = 0;
2835 return;
2838 if (count < 8 && !scratch)
2839 use_zero_reg = 1;
2841 if (optimize_size)
2842 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
2844 if (t_len * count <= max_len)
2846 /* Output shifts inline with no loop - faster. */
2847 if (len)
2848 *len = t_len * count;
2849 else
2851 while (count-- > 0)
2852 output_asm_insn (template, op);
2855 return;
2858 if (scratch)
2860 if (!len)
2861 strcat (str, AS2 (ldi,%3,%2));
2863 else if (use_zero_reg)
2865 /* Hack to save one word: use __zero_reg__ as loop counter.
2866 Set one bit, then shift in a loop until it is 0 again. */
2868 op[3] = zero_reg_rtx;
2869 if (len)
2870 *len = 2;
2871 else
2872 strcat (str, ("set" CR_TAB
2873 AS2 (bld,%3,%2-1)));
2875 else
2877 /* No scratch register available, use one from LD_REGS (saved in
2878 __tmp_reg__) that doesn't overlap with registers to shift. */
2880 op[3] = gen_rtx_REG (QImode,
2881 ((true_regnum (operands[0]) - 1) & 15) + 16);
2882 op[4] = tmp_reg_rtx;
2883 saved_in_tmp = 1;
2885 if (len)
2886 *len = 3; /* Includes "mov %3,%4" after the loop. */
2887 else
2888 strcat (str, (AS2 (mov,%4,%3) CR_TAB
2889 AS2 (ldi,%3,%2)));
2892 second_label = 0;
2894 else if (GET_CODE (operands[2]) == MEM)
2896 rtx op_mov[10];
2898 op[3] = op_mov[0] = tmp_reg_rtx;
2899 op_mov[1] = op[2];
2901 if (len)
2902 out_movqi_r_mr (insn, op_mov, len);
2903 else
2904 output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2906 else if (register_operand (operands[2], QImode))
2908 if (reg_unused_after (insn, operands[2]))
2909 op[3] = op[2];
2910 else
2912 op[3] = tmp_reg_rtx;
2913 if (!len)
2914 strcat (str, (AS2 (mov,%3,%2) CR_TAB));
2917 else
2918 fatal_insn ("bad shift insn:", insn);
2920 if (second_label)
2922 if (len)
2923 ++*len;
2924 else
2925 strcat (str, AS1 (rjmp,2f));
2928 if (len)
2929 *len += t_len + 2; /* template + dec + brXX */
2930 else
2932 strcat (str, "\n1:\t");
2933 strcat (str, template);
2934 strcat (str, second_label ? "\n2:\t" : "\n\t");
2935 strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
2936 strcat (str, CR_TAB);
2937 strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
2938 if (saved_in_tmp)
2939 strcat (str, (CR_TAB AS2 (mov,%3,%4)));
2940 output_asm_insn (str, op);
2945 /* 8bit shift left ((char)x << i) */
2947 const char *
2948 ashlqi3_out (rtx insn, rtx operands[], int *len)
2950 if (GET_CODE (operands[2]) == CONST_INT)
2952 int k;
2954 if (!len)
2955 len = &k;
2957 switch (INTVAL (operands[2]))
2959 default:
2960 if (INTVAL (operands[2]) < 8)
2961 break;
2963 *len = 1;
2964 return AS1 (clr,%0);
2966 case 1:
2967 *len = 1;
2968 return AS1 (lsl,%0);
2970 case 2:
2971 *len = 2;
2972 return (AS1 (lsl,%0) CR_TAB
2973 AS1 (lsl,%0));
2975 case 3:
2976 *len = 3;
2977 return (AS1 (lsl,%0) CR_TAB
2978 AS1 (lsl,%0) CR_TAB
2979 AS1 (lsl,%0));
2981 case 4:
2982 if (test_hard_reg_class (LD_REGS, operands[0]))
2984 *len = 2;
2985 return (AS1 (swap,%0) CR_TAB
2986 AS2 (andi,%0,0xf0));
2988 *len = 4;
2989 return (AS1 (lsl,%0) CR_TAB
2990 AS1 (lsl,%0) CR_TAB
2991 AS1 (lsl,%0) CR_TAB
2992 AS1 (lsl,%0));
2994 case 5:
2995 if (test_hard_reg_class (LD_REGS, operands[0]))
2997 *len = 3;
2998 return (AS1 (swap,%0) CR_TAB
2999 AS1 (lsl,%0) CR_TAB
3000 AS2 (andi,%0,0xe0));
3002 *len = 5;
3003 return (AS1 (lsl,%0) CR_TAB
3004 AS1 (lsl,%0) CR_TAB
3005 AS1 (lsl,%0) CR_TAB
3006 AS1 (lsl,%0) CR_TAB
3007 AS1 (lsl,%0));
3009 case 6:
3010 if (test_hard_reg_class (LD_REGS, operands[0]))
3012 *len = 4;
3013 return (AS1 (swap,%0) CR_TAB
3014 AS1 (lsl,%0) CR_TAB
3015 AS1 (lsl,%0) CR_TAB
3016 AS2 (andi,%0,0xc0));
3018 *len = 6;
3019 return (AS1 (lsl,%0) CR_TAB
3020 AS1 (lsl,%0) CR_TAB
3021 AS1 (lsl,%0) CR_TAB
3022 AS1 (lsl,%0) CR_TAB
3023 AS1 (lsl,%0) CR_TAB
3024 AS1 (lsl,%0));
3026 case 7:
3027 *len = 3;
3028 return (AS1 (ror,%0) CR_TAB
3029 AS1 (clr,%0) CR_TAB
3030 AS1 (ror,%0));
3033 else if (CONSTANT_P (operands[2]))
3034 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3036 out_shift_with_cnt (AS1 (lsl,%0),
3037 insn, operands, len, 1);
3038 return "";
3042 /* 16bit shift left ((short)x << i) */
3044 const char *
3045 ashlhi3_out (rtx insn, rtx operands[], int *len)
3047 if (GET_CODE (operands[2]) == CONST_INT)
3049 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3050 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3051 int k;
3052 int *t = len;
3054 if (!len)
3055 len = &k;
3057 switch (INTVAL (operands[2]))
3059 default:
3060 if (INTVAL (operands[2]) < 16)
3061 break;
3063 *len = 2;
3064 return (AS1 (clr,%B0) CR_TAB
3065 AS1 (clr,%A0));
3067 case 4:
3068 if (optimize_size && scratch)
3069 break; /* 5 */
3070 if (ldi_ok)
3072 *len = 6;
3073 return (AS1 (swap,%A0) CR_TAB
3074 AS1 (swap,%B0) CR_TAB
3075 AS2 (andi,%B0,0xf0) CR_TAB
3076 AS2 (eor,%B0,%A0) CR_TAB
3077 AS2 (andi,%A0,0xf0) CR_TAB
3078 AS2 (eor,%B0,%A0));
3080 if (scratch)
3082 *len = 7;
3083 return (AS1 (swap,%A0) CR_TAB
3084 AS1 (swap,%B0) CR_TAB
3085 AS2 (ldi,%3,0xf0) CR_TAB
3086 AS2 (and,%B0,%3) CR_TAB
3087 AS2 (eor,%B0,%A0) CR_TAB
3088 AS2 (and,%A0,%3) CR_TAB
3089 AS2 (eor,%B0,%A0));
3091 break; /* optimize_size ? 6 : 8 */
3093 case 5:
3094 if (optimize_size)
3095 break; /* scratch ? 5 : 6 */
3096 if (ldi_ok)
3098 *len = 8;
3099 return (AS1 (lsl,%A0) CR_TAB
3100 AS1 (rol,%B0) CR_TAB
3101 AS1 (swap,%A0) CR_TAB
3102 AS1 (swap,%B0) CR_TAB
3103 AS2 (andi,%B0,0xf0) CR_TAB
3104 AS2 (eor,%B0,%A0) CR_TAB
3105 AS2 (andi,%A0,0xf0) CR_TAB
3106 AS2 (eor,%B0,%A0));
3108 if (scratch)
3110 *len = 9;
3111 return (AS1 (lsl,%A0) CR_TAB
3112 AS1 (rol,%B0) CR_TAB
3113 AS1 (swap,%A0) CR_TAB
3114 AS1 (swap,%B0) CR_TAB
3115 AS2 (ldi,%3,0xf0) CR_TAB
3116 AS2 (and,%B0,%3) CR_TAB
3117 AS2 (eor,%B0,%A0) CR_TAB
3118 AS2 (and,%A0,%3) CR_TAB
3119 AS2 (eor,%B0,%A0));
3121 break; /* 10 */
3123 case 6:
3124 if (optimize_size)
3125 break; /* scratch ? 5 : 6 */
3126 *len = 9;
3127 return (AS1 (clr,__tmp_reg__) CR_TAB
3128 AS1 (lsr,%B0) CR_TAB
3129 AS1 (ror,%A0) CR_TAB
3130 AS1 (ror,__tmp_reg__) CR_TAB
3131 AS1 (lsr,%B0) CR_TAB
3132 AS1 (ror,%A0) CR_TAB
3133 AS1 (ror,__tmp_reg__) CR_TAB
3134 AS2 (mov,%B0,%A0) CR_TAB
3135 AS2 (mov,%A0,__tmp_reg__));
3137 case 7:
3138 *len = 5;
3139 return (AS1 (lsr,%B0) CR_TAB
3140 AS2 (mov,%B0,%A0) CR_TAB
3141 AS1 (clr,%A0) CR_TAB
3142 AS1 (ror,%B0) CR_TAB
3143 AS1 (ror,%A0));
3145 case 8:
3146 if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
3147 return *len = 1, AS1 (clr,%A0);
3148 else
3149 return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3150 AS1 (clr,%A0));
3152 case 9:
3153 *len = 3;
3154 return (AS2 (mov,%B0,%A0) CR_TAB
3155 AS1 (clr,%A0) CR_TAB
3156 AS1 (lsl,%B0));
3158 case 10:
3159 *len = 4;
3160 return (AS2 (mov,%B0,%A0) CR_TAB
3161 AS1 (clr,%A0) CR_TAB
3162 AS1 (lsl,%B0) CR_TAB
3163 AS1 (lsl,%B0));
3165 case 11:
3166 *len = 5;
3167 return (AS2 (mov,%B0,%A0) CR_TAB
3168 AS1 (clr,%A0) CR_TAB
3169 AS1 (lsl,%B0) CR_TAB
3170 AS1 (lsl,%B0) CR_TAB
3171 AS1 (lsl,%B0));
3173 case 12:
3174 if (ldi_ok)
3176 *len = 4;
3177 return (AS2 (mov,%B0,%A0) CR_TAB
3178 AS1 (clr,%A0) CR_TAB
3179 AS1 (swap,%B0) CR_TAB
3180 AS2 (andi,%B0,0xf0));
3182 if (scratch)
3184 *len = 5;
3185 return (AS2 (mov,%B0,%A0) CR_TAB
3186 AS1 (clr,%A0) CR_TAB
3187 AS1 (swap,%B0) CR_TAB
3188 AS2 (ldi,%3,0xf0) CR_TAB
3189 AS2 (and,%B0,%3));
3191 *len = 6;
3192 return (AS2 (mov,%B0,%A0) CR_TAB
3193 AS1 (clr,%A0) CR_TAB
3194 AS1 (lsl,%B0) CR_TAB
3195 AS1 (lsl,%B0) CR_TAB
3196 AS1 (lsl,%B0) CR_TAB
3197 AS1 (lsl,%B0));
3199 case 13:
3200 if (ldi_ok)
3202 *len = 5;
3203 return (AS2 (mov,%B0,%A0) CR_TAB
3204 AS1 (clr,%A0) CR_TAB
3205 AS1 (swap,%B0) CR_TAB
3206 AS1 (lsl,%B0) CR_TAB
3207 AS2 (andi,%B0,0xe0));
3209 if (AVR_ENHANCED && scratch)
3211 *len = 5;
3212 return (AS2 (ldi,%3,0x20) CR_TAB
3213 AS2 (mul,%A0,%3) CR_TAB
3214 AS2 (mov,%B0,r0) CR_TAB
3215 AS1 (clr,%A0) CR_TAB
3216 AS1 (clr,__zero_reg__));
3218 if (optimize_size && scratch)
3219 break; /* 5 */
3220 if (scratch)
3222 *len = 6;
3223 return (AS2 (mov,%B0,%A0) CR_TAB
3224 AS1 (clr,%A0) CR_TAB
3225 AS1 (swap,%B0) CR_TAB
3226 AS1 (lsl,%B0) CR_TAB
3227 AS2 (ldi,%3,0xe0) CR_TAB
3228 AS2 (and,%B0,%3));
3230 if (AVR_ENHANCED)
3232 *len = 6;
3233 return ("set" CR_TAB
3234 AS2 (bld,r1,5) CR_TAB
3235 AS2 (mul,%A0,r1) CR_TAB
3236 AS2 (mov,%B0,r0) CR_TAB
3237 AS1 (clr,%A0) CR_TAB
3238 AS1 (clr,__zero_reg__));
3240 *len = 7;
3241 return (AS2 (mov,%B0,%A0) CR_TAB
3242 AS1 (clr,%A0) CR_TAB
3243 AS1 (lsl,%B0) CR_TAB
3244 AS1 (lsl,%B0) CR_TAB
3245 AS1 (lsl,%B0) CR_TAB
3246 AS1 (lsl,%B0) CR_TAB
3247 AS1 (lsl,%B0));
3249 case 14:
3250 if (AVR_ENHANCED && ldi_ok)
3252 *len = 5;
3253 return (AS2 (ldi,%B0,0x40) CR_TAB
3254 AS2 (mul,%A0,%B0) CR_TAB
3255 AS2 (mov,%B0,r0) CR_TAB
3256 AS1 (clr,%A0) CR_TAB
3257 AS1 (clr,__zero_reg__));
3259 if (AVR_ENHANCED && scratch)
3261 *len = 5;
3262 return (AS2 (ldi,%3,0x40) CR_TAB
3263 AS2 (mul,%A0,%3) CR_TAB
3264 AS2 (mov,%B0,r0) CR_TAB
3265 AS1 (clr,%A0) CR_TAB
3266 AS1 (clr,__zero_reg__));
3268 if (optimize_size && ldi_ok)
3270 *len = 5;
3271 return (AS2 (mov,%B0,%A0) CR_TAB
3272 AS2 (ldi,%A0,6) "\n1:\t"
3273 AS1 (lsl,%B0) CR_TAB
3274 AS1 (dec,%A0) CR_TAB
3275 AS1 (brne,1b));
3277 if (optimize_size && scratch)
3278 break; /* 5 */
3279 *len = 6;
3280 return (AS1 (clr,%B0) CR_TAB
3281 AS1 (lsr,%A0) CR_TAB
3282 AS1 (ror,%B0) CR_TAB
3283 AS1 (lsr,%A0) CR_TAB
3284 AS1 (ror,%B0) CR_TAB
3285 AS1 (clr,%A0));
3287 case 15:
3288 *len = 4;
3289 return (AS1 (clr,%B0) CR_TAB
3290 AS1 (lsr,%A0) CR_TAB
3291 AS1 (ror,%B0) CR_TAB
3292 AS1 (clr,%A0));
3294 len = t;
3296 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3297 AS1 (rol,%B0)),
3298 insn, operands, len, 2);
3299 return "";
3303 /* 32bit shift left ((long)x << i) */
3305 const char *
3306 ashlsi3_out (rtx insn, rtx operands[], int *len)
3308 if (GET_CODE (operands[2]) == CONST_INT)
3310 int k;
3311 int *t = len;
3313 if (!len)
3314 len = &k;
3316 switch (INTVAL (operands[2]))
3318 default:
3319 if (INTVAL (operands[2]) < 32)
3320 break;
3322 if (AVR_ENHANCED)
3323 return *len = 3, (AS1 (clr,%D0) CR_TAB
3324 AS1 (clr,%C0) CR_TAB
3325 AS2 (movw,%A0,%C0));
3326 *len = 4;
3327 return (AS1 (clr,%D0) CR_TAB
3328 AS1 (clr,%C0) CR_TAB
3329 AS1 (clr,%B0) CR_TAB
3330 AS1 (clr,%A0));
3332 case 8:
3334 int reg0 = true_regnum (operands[0]);
3335 int reg1 = true_regnum (operands[1]);
3336 *len = 4;
3337 if (reg0 >= reg1)
3338 return (AS2 (mov,%D0,%C1) CR_TAB
3339 AS2 (mov,%C0,%B1) CR_TAB
3340 AS2 (mov,%B0,%A1) CR_TAB
3341 AS1 (clr,%A0));
3342 else if (reg0 + 1 == reg1)
3344 *len = 1;
3345 return AS1 (clr,%A0);
3347 else
3348 return (AS1 (clr,%A0) CR_TAB
3349 AS2 (mov,%B0,%A1) CR_TAB
3350 AS2 (mov,%C0,%B1) CR_TAB
3351 AS2 (mov,%D0,%C1));
3354 case 16:
3356 int reg0 = true_regnum (operands[0]);
3357 int reg1 = true_regnum (operands[1]);
3358 *len = 4;
3359 if (AVR_ENHANCED && (reg0 + 2 != reg1))
3361 *len = 3;
3362 return (AS2 (movw,%C0,%A1) CR_TAB
3363 AS1 (clr,%B0) CR_TAB
3364 AS1 (clr,%A0));
3366 if (reg0 + 1 >= reg1)
3367 return (AS2 (mov,%D0,%B1) CR_TAB
3368 AS2 (mov,%C0,%A1) CR_TAB
3369 AS1 (clr,%B0) CR_TAB
3370 AS1 (clr,%A0));
3371 if (reg0 + 2 == reg1)
3373 *len = 2;
3374 return (AS1 (clr,%B0) CR_TAB
3375 AS1 (clr,%A0));
3377 else
3378 return (AS2 (mov,%C0,%A1) CR_TAB
3379 AS2 (mov,%D0,%B1) CR_TAB
3380 AS1 (clr,%B0) CR_TAB
3381 AS1 (clr,%A0));
3384 case 24:
3385 *len = 4;
3386 if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
3387 return (AS2 (mov,%D0,%A1) CR_TAB
3388 AS1 (clr,%C0) CR_TAB
3389 AS1 (clr,%B0) CR_TAB
3390 AS1 (clr,%A0));
3391 else
3393 *len = 3;
3394 return (AS1 (clr,%C0) CR_TAB
3395 AS1 (clr,%B0) CR_TAB
3396 AS1 (clr,%A0));
3399 case 31:
3400 *len = 6;
3401 return (AS1 (clr,%D0) CR_TAB
3402 AS1 (lsr,%A0) CR_TAB
3403 AS1 (ror,%D0) CR_TAB
3404 AS1 (clr,%C0) CR_TAB
3405 AS1 (clr,%B0) CR_TAB
3406 AS1 (clr,%A0));
3408 len = t;
3410 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3411 AS1 (rol,%B0) CR_TAB
3412 AS1 (rol,%C0) CR_TAB
3413 AS1 (rol,%D0)),
3414 insn, operands, len, 4);
3415 return "";
3418 /* 8bit arithmetic shift right ((signed char)x >> i) */
3420 const char *
3421 ashrqi3_out (rtx insn, rtx operands[], int *len)
3423 if (GET_CODE (operands[2]) == CONST_INT)
3425 int k;
3427 if (!len)
3428 len = &k;
3430 switch (INTVAL (operands[2]))
3432 case 1:
3433 *len = 1;
3434 return AS1 (asr,%0);
3436 case 2:
3437 *len = 2;
3438 return (AS1 (asr,%0) CR_TAB
3439 AS1 (asr,%0));
3441 case 3:
3442 *len = 3;
3443 return (AS1 (asr,%0) CR_TAB
3444 AS1 (asr,%0) CR_TAB
3445 AS1 (asr,%0));
3447 case 4:
3448 *len = 4;
3449 return (AS1 (asr,%0) CR_TAB
3450 AS1 (asr,%0) CR_TAB
3451 AS1 (asr,%0) CR_TAB
3452 AS1 (asr,%0));
3454 case 5:
3455 *len = 5;
3456 return (AS1 (asr,%0) CR_TAB
3457 AS1 (asr,%0) CR_TAB
3458 AS1 (asr,%0) CR_TAB
3459 AS1 (asr,%0) CR_TAB
3460 AS1 (asr,%0));
3462 case 6:
3463 *len = 4;
3464 return (AS2 (bst,%0,6) CR_TAB
3465 AS1 (lsl,%0) CR_TAB
3466 AS2 (sbc,%0,%0) CR_TAB
3467 AS2 (bld,%0,0));
3469 default:
3470 if (INTVAL (operands[2]) < 8)
3471 break;
3473 /* fall through */
3475 case 7:
3476 *len = 2;
3477 return (AS1 (lsl,%0) CR_TAB
3478 AS2 (sbc,%0,%0));
3481 else if (CONSTANT_P (operands[2]))
3482 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3484 out_shift_with_cnt (AS1 (asr,%0),
3485 insn, operands, len, 1);
3486 return "";
3490 /* 16bit arithmetic shift right ((signed short)x >> i) */
3492 const char *
3493 ashrhi3_out (rtx insn, rtx operands[], int *len)
3495 if (GET_CODE (operands[2]) == CONST_INT)
3497 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3498 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3499 int k;
3500 int *t = len;
3502 if (!len)
3503 len = &k;
3505 switch (INTVAL (operands[2]))
3507 case 4:
3508 case 5:
3509 /* XXX try to optimize this too? */
3510 break;
3512 case 6:
3513 if (optimize_size)
3514 break; /* scratch ? 5 : 6 */
3515 *len = 8;
3516 return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3517 AS2 (mov,%A0,%B0) CR_TAB
3518 AS1 (lsl,__tmp_reg__) CR_TAB
3519 AS1 (rol,%A0) CR_TAB
3520 AS2 (sbc,%B0,%B0) CR_TAB
3521 AS1 (lsl,__tmp_reg__) CR_TAB
3522 AS1 (rol,%A0) CR_TAB
3523 AS1 (rol,%B0));
3525 case 7:
3526 *len = 4;
3527 return (AS1 (lsl,%A0) CR_TAB
3528 AS2 (mov,%A0,%B0) CR_TAB
3529 AS1 (rol,%A0) CR_TAB
3530 AS2 (sbc,%B0,%B0));
3532 case 8:
3534 int reg0 = true_regnum (operands[0]);
3535 int reg1 = true_regnum (operands[1]);
3537 if (reg0 == reg1)
3538 return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3539 AS1 (lsl,%B0) CR_TAB
3540 AS2 (sbc,%B0,%B0));
3541 else if (reg0 == reg1 + 1)
3542 return *len = 3, (AS1 (clr,%B0) CR_TAB
3543 AS2 (sbrc,%A0,7) CR_TAB
3544 AS1 (dec,%B0));
3546 return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3547 AS1 (clr,%B0) CR_TAB
3548 AS2 (sbrc,%A0,7) CR_TAB
3549 AS1 (dec,%B0));
3552 case 9:
3553 *len = 4;
3554 return (AS2 (mov,%A0,%B0) CR_TAB
3555 AS1 (lsl,%B0) CR_TAB
3556 AS2 (sbc,%B0,%B0) CR_TAB
3557 AS1 (asr,%A0));
3559 case 10:
3560 *len = 5;
3561 return (AS2 (mov,%A0,%B0) CR_TAB
3562 AS1 (lsl,%B0) CR_TAB
3563 AS2 (sbc,%B0,%B0) CR_TAB
3564 AS1 (asr,%A0) CR_TAB
3565 AS1 (asr,%A0));
3567 case 11:
3568 if (AVR_ENHANCED && ldi_ok)
3570 *len = 5;
3571 return (AS2 (ldi,%A0,0x20) CR_TAB
3572 AS2 (muls,%B0,%A0) CR_TAB
3573 AS2 (mov,%A0,r1) CR_TAB
3574 AS2 (sbc,%B0,%B0) CR_TAB
3575 AS1 (clr,__zero_reg__));
3577 if (optimize_size && scratch)
3578 break; /* 5 */
3579 *len = 6;
3580 return (AS2 (mov,%A0,%B0) CR_TAB
3581 AS1 (lsl,%B0) CR_TAB
3582 AS2 (sbc,%B0,%B0) CR_TAB
3583 AS1 (asr,%A0) CR_TAB
3584 AS1 (asr,%A0) CR_TAB
3585 AS1 (asr,%A0));
3587 case 12:
3588 if (AVR_ENHANCED && ldi_ok)
3590 *len = 5;
3591 return (AS2 (ldi,%A0,0x10) CR_TAB
3592 AS2 (muls,%B0,%A0) CR_TAB
3593 AS2 (mov,%A0,r1) CR_TAB
3594 AS2 (sbc,%B0,%B0) CR_TAB
3595 AS1 (clr,__zero_reg__));
3597 if (optimize_size && scratch)
3598 break; /* 5 */
3599 *len = 7;
3600 return (AS2 (mov,%A0,%B0) CR_TAB
3601 AS1 (lsl,%B0) CR_TAB
3602 AS2 (sbc,%B0,%B0) CR_TAB
3603 AS1 (asr,%A0) CR_TAB
3604 AS1 (asr,%A0) CR_TAB
3605 AS1 (asr,%A0) CR_TAB
3606 AS1 (asr,%A0));
3608 case 13:
3609 if (AVR_ENHANCED && ldi_ok)
3611 *len = 5;
3612 return (AS2 (ldi,%A0,0x08) CR_TAB
3613 AS2 (muls,%B0,%A0) CR_TAB
3614 AS2 (mov,%A0,r1) CR_TAB
3615 AS2 (sbc,%B0,%B0) CR_TAB
3616 AS1 (clr,__zero_reg__));
3618 if (optimize_size)
3619 break; /* scratch ? 5 : 7 */
3620 *len = 8;
3621 return (AS2 (mov,%A0,%B0) CR_TAB
3622 AS1 (lsl,%B0) CR_TAB
3623 AS2 (sbc,%B0,%B0) CR_TAB
3624 AS1 (asr,%A0) CR_TAB
3625 AS1 (asr,%A0) CR_TAB
3626 AS1 (asr,%A0) CR_TAB
3627 AS1 (asr,%A0) CR_TAB
3628 AS1 (asr,%A0));
3630 case 14:
3631 *len = 5;
3632 return (AS1 (lsl,%B0) CR_TAB
3633 AS2 (sbc,%A0,%A0) CR_TAB
3634 AS1 (lsl,%B0) CR_TAB
3635 AS2 (mov,%B0,%A0) CR_TAB
3636 AS1 (rol,%A0));
3638 default:
3639 if (INTVAL (operands[2]) < 16)
3640 break;
3642 /* fall through */
3644 case 15:
3645 return *len = 3, (AS1 (lsl,%B0) CR_TAB
3646 AS2 (sbc,%A0,%A0) CR_TAB
3647 AS2 (mov,%B0,%A0));
3649 len = t;
3651 out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3652 AS1 (ror,%A0)),
3653 insn, operands, len, 2);
3654 return "";
3658 /* 32bit arithmetic shift right ((signed long)x >> i) */
3660 const char *
3661 ashrsi3_out (rtx insn, rtx operands[], int *len)
3663 if (GET_CODE (operands[2]) == CONST_INT)
3665 int k;
3666 int *t = len;
3668 if (!len)
3669 len = &k;
3671 switch (INTVAL (operands[2]))
3673 case 8:
3675 int reg0 = true_regnum (operands[0]);
3676 int reg1 = true_regnum (operands[1]);
3677 *len=6;
3678 if (reg0 <= reg1)
3679 return (AS2 (mov,%A0,%B1) CR_TAB
3680 AS2 (mov,%B0,%C1) CR_TAB
3681 AS2 (mov,%C0,%D1) CR_TAB
3682 AS1 (clr,%D0) CR_TAB
3683 AS2 (sbrc,%C0,7) CR_TAB
3684 AS1 (dec,%D0));
3685 else if (reg0 == reg1 + 1)
3687 *len = 3;
3688 return (AS1 (clr,%D0) CR_TAB
3689 AS2 (sbrc,%C0,7) CR_TAB
3690 AS1 (dec,%D0));
3692 else
3693 return (AS1 (clr,%D0) CR_TAB
3694 AS2 (sbrc,%D1,7) CR_TAB
3695 AS1 (dec,%D0) CR_TAB
3696 AS2 (mov,%C0,%D1) CR_TAB
3697 AS2 (mov,%B0,%C1) CR_TAB
3698 AS2 (mov,%A0,%B1));
3701 case 16:
3703 int reg0 = true_regnum (operands[0]);
3704 int reg1 = true_regnum (operands[1]);
3705 *len=6;
3706 if (AVR_ENHANCED && (reg0 != reg1 + 2))
3708 *len = 5;
3709 return (AS2 (movw,%A0,%C1) CR_TAB
3710 AS1 (clr,%D0) CR_TAB
3711 AS2 (sbrc,%B0,7) CR_TAB
3712 AS1 (com,%D0) CR_TAB
3713 AS2 (mov,%C0,%D0));
3715 if (reg0 <= reg1 + 1)
3716 return (AS2 (mov,%A0,%C1) CR_TAB
3717 AS2 (mov,%B0,%D1) CR_TAB
3718 AS1 (clr,%D0) CR_TAB
3719 AS2 (sbrc,%B0,7) CR_TAB
3720 AS1 (com,%D0) CR_TAB
3721 AS2 (mov,%C0,%D0));
3722 else if (reg0 == reg1 + 2)
3723 return *len = 4, (AS1 (clr,%D0) CR_TAB
3724 AS2 (sbrc,%B0,7) CR_TAB
3725 AS1 (com,%D0) CR_TAB
3726 AS2 (mov,%C0,%D0));
3727 else
3728 return (AS2 (mov,%B0,%D1) CR_TAB
3729 AS2 (mov,%A0,%C1) CR_TAB
3730 AS1 (clr,%D0) CR_TAB
3731 AS2 (sbrc,%B0,7) CR_TAB
3732 AS1 (com,%D0) CR_TAB
3733 AS2 (mov,%C0,%D0));
3736 case 24:
3737 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3738 return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3739 AS1 (clr,%D0) CR_TAB
3740 AS2 (sbrc,%A0,7) CR_TAB
3741 AS1 (com,%D0) CR_TAB
3742 AS2 (mov,%B0,%D0) CR_TAB
3743 AS2 (mov,%C0,%D0));
3744 else
3745 return *len = 5, (AS1 (clr,%D0) CR_TAB
3746 AS2 (sbrc,%A0,7) CR_TAB
3747 AS1 (com,%D0) CR_TAB
3748 AS2 (mov,%B0,%D0) CR_TAB
3749 AS2 (mov,%C0,%D0));
3751 default:
3752 if (INTVAL (operands[2]) < 32)
3753 break;
3755 /* fall through */
3757 case 31:
3758 if (AVR_ENHANCED)
3759 return *len = 4, (AS1 (lsl,%D0) CR_TAB
3760 AS2 (sbc,%A0,%A0) CR_TAB
3761 AS2 (mov,%B0,%A0) CR_TAB
3762 AS2 (movw,%C0,%A0));
3763 else
3764 return *len = 5, (AS1 (lsl,%D0) CR_TAB
3765 AS2 (sbc,%A0,%A0) CR_TAB
3766 AS2 (mov,%B0,%A0) CR_TAB
3767 AS2 (mov,%C0,%A0) CR_TAB
3768 AS2 (mov,%D0,%A0));
3770 len = t;
3772 out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
3773 AS1 (ror,%C0) CR_TAB
3774 AS1 (ror,%B0) CR_TAB
3775 AS1 (ror,%A0)),
3776 insn, operands, len, 4);
3777 return "";
3780 /* 8bit logic shift right ((unsigned char)x >> i) */
3782 const char *
3783 lshrqi3_out (rtx insn, rtx operands[], int *len)
3785 if (GET_CODE (operands[2]) == CONST_INT)
3787 int k;
3789 if (!len)
3790 len = &k;
3792 switch (INTVAL (operands[2]))
3794 default:
3795 if (INTVAL (operands[2]) < 8)
3796 break;
3798 *len = 1;
3799 return AS1 (clr,%0);
3801 case 1:
3802 *len = 1;
3803 return AS1 (lsr,%0);
3805 case 2:
3806 *len = 2;
3807 return (AS1 (lsr,%0) CR_TAB
3808 AS1 (lsr,%0));
3809 case 3:
3810 *len = 3;
3811 return (AS1 (lsr,%0) CR_TAB
3812 AS1 (lsr,%0) CR_TAB
3813 AS1 (lsr,%0));
3815 case 4:
3816 if (test_hard_reg_class (LD_REGS, operands[0]))
3818 *len=2;
3819 return (AS1 (swap,%0) CR_TAB
3820 AS2 (andi,%0,0x0f));
3822 *len = 4;
3823 return (AS1 (lsr,%0) CR_TAB
3824 AS1 (lsr,%0) CR_TAB
3825 AS1 (lsr,%0) CR_TAB
3826 AS1 (lsr,%0));
3828 case 5:
3829 if (test_hard_reg_class (LD_REGS, operands[0]))
3831 *len = 3;
3832 return (AS1 (swap,%0) CR_TAB
3833 AS1 (lsr,%0) CR_TAB
3834 AS2 (andi,%0,0x7));
3836 *len = 5;
3837 return (AS1 (lsr,%0) CR_TAB
3838 AS1 (lsr,%0) CR_TAB
3839 AS1 (lsr,%0) CR_TAB
3840 AS1 (lsr,%0) CR_TAB
3841 AS1 (lsr,%0));
3843 case 6:
3844 if (test_hard_reg_class (LD_REGS, operands[0]))
3846 *len = 4;
3847 return (AS1 (swap,%0) CR_TAB
3848 AS1 (lsr,%0) CR_TAB
3849 AS1 (lsr,%0) CR_TAB
3850 AS2 (andi,%0,0x3));
3852 *len = 6;
3853 return (AS1 (lsr,%0) CR_TAB
3854 AS1 (lsr,%0) CR_TAB
3855 AS1 (lsr,%0) CR_TAB
3856 AS1 (lsr,%0) CR_TAB
3857 AS1 (lsr,%0) CR_TAB
3858 AS1 (lsr,%0));
3860 case 7:
3861 *len = 3;
3862 return (AS1 (rol,%0) CR_TAB
3863 AS1 (clr,%0) CR_TAB
3864 AS1 (rol,%0));
3867 else if (CONSTANT_P (operands[2]))
3868 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3870 out_shift_with_cnt (AS1 (lsr,%0),
3871 insn, operands, len, 1);
3872 return "";
3875 /* 16bit logic shift right ((unsigned short)x >> i) */
3877 const char *
3878 lshrhi3_out (rtx insn, rtx operands[], int *len)
3880 if (GET_CODE (operands[2]) == CONST_INT)
3882 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3883 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3884 int k;
3885 int *t = len;
3887 if (!len)
3888 len = &k;
3890 switch (INTVAL (operands[2]))
3892 default:
3893 if (INTVAL (operands[2]) < 16)
3894 break;
3896 *len = 2;
3897 return (AS1 (clr,%B0) CR_TAB
3898 AS1 (clr,%A0));
3900 case 4:
3901 if (optimize_size && scratch)
3902 break; /* 5 */
3903 if (ldi_ok)
3905 *len = 6;
3906 return (AS1 (swap,%B0) CR_TAB
3907 AS1 (swap,%A0) CR_TAB
3908 AS2 (andi,%A0,0x0f) CR_TAB
3909 AS2 (eor,%A0,%B0) CR_TAB
3910 AS2 (andi,%B0,0x0f) CR_TAB
3911 AS2 (eor,%A0,%B0));
3913 if (scratch)
3915 *len = 7;
3916 return (AS1 (swap,%B0) CR_TAB
3917 AS1 (swap,%A0) CR_TAB
3918 AS2 (ldi,%3,0x0f) CR_TAB
3919 AS2 (and,%A0,%3) CR_TAB
3920 AS2 (eor,%A0,%B0) CR_TAB
3921 AS2 (and,%B0,%3) CR_TAB
3922 AS2 (eor,%A0,%B0));
3924 break; /* optimize_size ? 6 : 8 */
3926 case 5:
3927 if (optimize_size)
3928 break; /* scratch ? 5 : 6 */
3929 if (ldi_ok)
3931 *len = 8;
3932 return (AS1 (lsr,%B0) CR_TAB
3933 AS1 (ror,%A0) CR_TAB
3934 AS1 (swap,%B0) CR_TAB
3935 AS1 (swap,%A0) CR_TAB
3936 AS2 (andi,%A0,0x0f) CR_TAB
3937 AS2 (eor,%A0,%B0) CR_TAB
3938 AS2 (andi,%B0,0x0f) CR_TAB
3939 AS2 (eor,%A0,%B0));
3941 if (scratch)
3943 *len = 9;
3944 return (AS1 (lsr,%B0) CR_TAB
3945 AS1 (ror,%A0) CR_TAB
3946 AS1 (swap,%B0) CR_TAB
3947 AS1 (swap,%A0) CR_TAB
3948 AS2 (ldi,%3,0x0f) CR_TAB
3949 AS2 (and,%A0,%3) CR_TAB
3950 AS2 (eor,%A0,%B0) CR_TAB
3951 AS2 (and,%B0,%3) CR_TAB
3952 AS2 (eor,%A0,%B0));
3954 break; /* 10 */
3956 case 6:
3957 if (optimize_size)
3958 break; /* scratch ? 5 : 6 */
3959 *len = 9;
3960 return (AS1 (clr,__tmp_reg__) CR_TAB
3961 AS1 (lsl,%A0) CR_TAB
3962 AS1 (rol,%B0) CR_TAB
3963 AS1 (rol,__tmp_reg__) CR_TAB
3964 AS1 (lsl,%A0) CR_TAB
3965 AS1 (rol,%B0) CR_TAB
3966 AS1 (rol,__tmp_reg__) CR_TAB
3967 AS2 (mov,%A0,%B0) CR_TAB
3968 AS2 (mov,%B0,__tmp_reg__));
3970 case 7:
3971 *len = 5;
3972 return (AS1 (lsl,%A0) CR_TAB
3973 AS2 (mov,%A0,%B0) CR_TAB
3974 AS1 (rol,%A0) CR_TAB
3975 AS2 (sbc,%B0,%B0) CR_TAB
3976 AS1 (neg,%B0));
3978 case 8:
3979 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
3980 return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
3981 AS1 (clr,%B0));
3982 else
3983 return *len = 1, AS1 (clr,%B0);
3985 case 9:
3986 *len = 3;
3987 return (AS2 (mov,%A0,%B0) CR_TAB
3988 AS1 (clr,%B0) CR_TAB
3989 AS1 (lsr,%A0));
3991 case 10:
3992 *len = 4;
3993 return (AS2 (mov,%A0,%B0) CR_TAB
3994 AS1 (clr,%B0) CR_TAB
3995 AS1 (lsr,%A0) CR_TAB
3996 AS1 (lsr,%A0));
3998 case 11:
3999 *len = 5;
4000 return (AS2 (mov,%A0,%B0) CR_TAB
4001 AS1 (clr,%B0) CR_TAB
4002 AS1 (lsr,%A0) CR_TAB
4003 AS1 (lsr,%A0) CR_TAB
4004 AS1 (lsr,%A0));
4006 case 12:
4007 if (ldi_ok)
4009 *len = 4;
4010 return (AS2 (mov,%A0,%B0) CR_TAB
4011 AS1 (clr,%B0) CR_TAB
4012 AS1 (swap,%A0) CR_TAB
4013 AS2 (andi,%A0,0x0f));
4015 if (scratch)
4017 *len = 5;
4018 return (AS2 (mov,%A0,%B0) CR_TAB
4019 AS1 (clr,%B0) CR_TAB
4020 AS1 (swap,%A0) CR_TAB
4021 AS2 (ldi,%3,0x0f) CR_TAB
4022 AS2 (and,%A0,%3));
4024 *len = 6;
4025 return (AS2 (mov,%A0,%B0) CR_TAB
4026 AS1 (clr,%B0) CR_TAB
4027 AS1 (lsr,%A0) CR_TAB
4028 AS1 (lsr,%A0) CR_TAB
4029 AS1 (lsr,%A0) CR_TAB
4030 AS1 (lsr,%A0));
4032 case 13:
4033 if (ldi_ok)
4035 *len = 5;
4036 return (AS2 (mov,%A0,%B0) CR_TAB
4037 AS1 (clr,%B0) CR_TAB
4038 AS1 (swap,%A0) CR_TAB
4039 AS1 (lsr,%A0) CR_TAB
4040 AS2 (andi,%A0,0x07));
4042 if (AVR_ENHANCED && scratch)
4044 *len = 5;
4045 return (AS2 (ldi,%3,0x08) CR_TAB
4046 AS2 (mul,%B0,%3) CR_TAB
4047 AS2 (mov,%A0,r1) CR_TAB
4048 AS1 (clr,%B0) CR_TAB
4049 AS1 (clr,__zero_reg__));
4051 if (optimize_size && scratch)
4052 break; /* 5 */
4053 if (scratch)
4055 *len = 6;
4056 return (AS2 (mov,%A0,%B0) CR_TAB
4057 AS1 (clr,%B0) CR_TAB
4058 AS1 (swap,%A0) CR_TAB
4059 AS1 (lsr,%A0) CR_TAB
4060 AS2 (ldi,%3,0x07) CR_TAB
4061 AS2 (and,%A0,%3));
4063 if (AVR_ENHANCED)
4065 *len = 6;
4066 return ("set" CR_TAB
4067 AS2 (bld,r1,3) CR_TAB
4068 AS2 (mul,%B0,r1) CR_TAB
4069 AS2 (mov,%A0,r1) CR_TAB
4070 AS1 (clr,%B0) CR_TAB
4071 AS1 (clr,__zero_reg__));
4073 *len = 7;
4074 return (AS2 (mov,%A0,%B0) CR_TAB
4075 AS1 (clr,%B0) CR_TAB
4076 AS1 (lsr,%A0) CR_TAB
4077 AS1 (lsr,%A0) CR_TAB
4078 AS1 (lsr,%A0) CR_TAB
4079 AS1 (lsr,%A0) CR_TAB
4080 AS1 (lsr,%A0));
4082 case 14:
4083 if (AVR_ENHANCED && ldi_ok)
4085 *len = 5;
4086 return (AS2 (ldi,%A0,0x04) CR_TAB
4087 AS2 (mul,%B0,%A0) CR_TAB
4088 AS2 (mov,%A0,r1) CR_TAB
4089 AS1 (clr,%B0) CR_TAB
4090 AS1 (clr,__zero_reg__));
4092 if (AVR_ENHANCED && scratch)
4094 *len = 5;
4095 return (AS2 (ldi,%3,0x04) CR_TAB
4096 AS2 (mul,%B0,%3) CR_TAB
4097 AS2 (mov,%A0,r1) CR_TAB
4098 AS1 (clr,%B0) CR_TAB
4099 AS1 (clr,__zero_reg__));
4101 if (optimize_size && ldi_ok)
4103 *len = 5;
4104 return (AS2 (mov,%A0,%B0) CR_TAB
4105 AS2 (ldi,%B0,6) "\n1:\t"
4106 AS1 (lsr,%A0) CR_TAB
4107 AS1 (dec,%B0) CR_TAB
4108 AS1 (brne,1b));
4110 if (optimize_size && scratch)
4111 break; /* 5 */
4112 *len = 6;
4113 return (AS1 (clr,%A0) CR_TAB
4114 AS1 (lsl,%B0) CR_TAB
4115 AS1 (rol,%A0) CR_TAB
4116 AS1 (lsl,%B0) CR_TAB
4117 AS1 (rol,%A0) CR_TAB
4118 AS1 (clr,%B0));
4120 case 15:
4121 *len = 4;
4122 return (AS1 (clr,%A0) CR_TAB
4123 AS1 (lsl,%B0) CR_TAB
4124 AS1 (rol,%A0) CR_TAB
4125 AS1 (clr,%B0));
4127 len = t;
4129 out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
4130 AS1 (ror,%A0)),
4131 insn, operands, len, 2);
4132 return "";
4135 /* 32bit logic shift right ((unsigned int)x >> i) */
4137 const char *
4138 lshrsi3_out (rtx insn, rtx operands[], int *len)
4140 if (GET_CODE (operands[2]) == CONST_INT)
4142 int k;
4143 int *t = len;
4145 if (!len)
4146 len = &k;
4148 switch (INTVAL (operands[2]))
4150 default:
4151 if (INTVAL (operands[2]) < 32)
4152 break;
4154 if (AVR_ENHANCED)
4155 return *len = 3, (AS1 (clr,%D0) CR_TAB
4156 AS1 (clr,%C0) CR_TAB
4157 AS2 (movw,%A0,%C0));
4158 *len = 4;
4159 return (AS1 (clr,%D0) CR_TAB
4160 AS1 (clr,%C0) CR_TAB
4161 AS1 (clr,%B0) CR_TAB
4162 AS1 (clr,%A0));
4164 case 8:
4166 int reg0 = true_regnum (operands[0]);
4167 int reg1 = true_regnum (operands[1]);
4168 *len = 4;
4169 if (reg0 <= reg1)
4170 return (AS2 (mov,%A0,%B1) CR_TAB
4171 AS2 (mov,%B0,%C1) CR_TAB
4172 AS2 (mov,%C0,%D1) CR_TAB
4173 AS1 (clr,%D0));
4174 else if (reg0 == reg1 + 1)
4175 return *len = 1, AS1 (clr,%D0);
4176 else
4177 return (AS1 (clr,%D0) CR_TAB
4178 AS2 (mov,%C0,%D1) CR_TAB
4179 AS2 (mov,%B0,%C1) CR_TAB
4180 AS2 (mov,%A0,%B1));
4183 case 16:
4185 int reg0 = true_regnum (operands[0]);
4186 int reg1 = true_regnum (operands[1]);
4187 *len = 4;
4188 if (AVR_ENHANCED && (reg0 != reg1 + 2))
4190 *len = 3;
4191 return (AS2 (movw,%A0,%C1) CR_TAB
4192 AS1 (clr,%C0) CR_TAB
4193 AS1 (clr,%D0));
4195 if (reg0 <= reg1 + 1)
4196 return (AS2 (mov,%A0,%C1) CR_TAB
4197 AS2 (mov,%B0,%D1) CR_TAB
4198 AS1 (clr,%C0) CR_TAB
4199 AS1 (clr,%D0));
4200 else if (reg0 == reg1 + 2)
4201 return *len = 2, (AS1 (clr,%C0) CR_TAB
4202 AS1 (clr,%D0));
4203 else
4204 return (AS2 (mov,%B0,%D1) CR_TAB
4205 AS2 (mov,%A0,%C1) CR_TAB
4206 AS1 (clr,%C0) CR_TAB
4207 AS1 (clr,%D0));
4210 case 24:
4211 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
4212 return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4213 AS1 (clr,%B0) CR_TAB
4214 AS1 (clr,%C0) CR_TAB
4215 AS1 (clr,%D0));
4216 else
4217 return *len = 3, (AS1 (clr,%B0) CR_TAB
4218 AS1 (clr,%C0) CR_TAB
4219 AS1 (clr,%D0));
4221 case 31:
4222 *len = 6;
4223 return (AS1 (clr,%A0) CR_TAB
4224 AS2 (sbrc,%D0,7) CR_TAB
4225 AS1 (inc,%A0) CR_TAB
4226 AS1 (clr,%B0) CR_TAB
4227 AS1 (clr,%C0) CR_TAB
4228 AS1 (clr,%D0));
4230 len = t;
4232 out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4233 AS1 (ror,%C0) CR_TAB
4234 AS1 (ror,%B0) CR_TAB
4235 AS1 (ror,%A0)),
4236 insn, operands, len, 4);
4237 return "";
4240 /* Modifies the length assigned to instruction INSN
4241 LEN is the initially computed length of the insn. */
4244 adjust_insn_length (rtx insn, int len)
4246 rtx patt = PATTERN (insn);
4247 rtx set;
4249 if (GET_CODE (patt) == SET)
4251 rtx op[10];
4252 op[1] = SET_SRC (patt);
4253 op[0] = SET_DEST (patt);
4254 if (general_operand (op[1], VOIDmode)
4255 && general_operand (op[0], VOIDmode))
4257 switch (GET_MODE (op[0]))
4259 case QImode:
4260 output_movqi (insn, op, &len);
4261 break;
4262 case HImode:
4263 output_movhi (insn, op, &len);
4264 break;
4265 case SImode:
4266 case SFmode:
4267 output_movsisf (insn, op, &len);
4268 break;
4269 default:
4270 break;
4273 else if (op[0] == cc0_rtx && REG_P (op[1]))
4275 switch (GET_MODE (op[1]))
4277 case HImode: out_tsthi (insn,&len); break;
4278 case SImode: out_tstsi (insn,&len); break;
4279 default: break;
4282 else if (GET_CODE (op[1]) == AND)
4284 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4286 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4287 if (GET_MODE (op[1]) == SImode)
4288 len = (((mask & 0xff) != 0xff)
4289 + ((mask & 0xff00) != 0xff00)
4290 + ((mask & 0xff0000L) != 0xff0000L)
4291 + ((mask & 0xff000000L) != 0xff000000L));
4292 else if (GET_MODE (op[1]) == HImode)
4293 len = (((mask & 0xff) != 0xff)
4294 + ((mask & 0xff00) != 0xff00));
4297 else if (GET_CODE (op[1]) == IOR)
4299 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4301 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4302 if (GET_MODE (op[1]) == SImode)
4303 len = (((mask & 0xff) != 0)
4304 + ((mask & 0xff00) != 0)
4305 + ((mask & 0xff0000L) != 0)
4306 + ((mask & 0xff000000L) != 0));
4307 else if (GET_MODE (op[1]) == HImode)
4308 len = (((mask & 0xff) != 0)
4309 + ((mask & 0xff00) != 0));
4313 set = single_set (insn);
4314 if (set)
4316 rtx op[10];
4318 op[1] = SET_SRC (set);
4319 op[0] = SET_DEST (set);
4321 if (GET_CODE (patt) == PARALLEL
4322 && general_operand (op[1], VOIDmode)
4323 && general_operand (op[0], VOIDmode))
4325 if (XVECLEN (patt, 0) == 2)
4326 op[2] = XVECEXP (patt, 0, 1);
4328 switch (GET_MODE (op[0]))
4330 case QImode:
4331 len = 2;
4332 break;
4333 case HImode:
4334 output_reload_inhi (insn, op, &len);
4335 break;
4336 case SImode:
4337 case SFmode:
4338 output_reload_insisf (insn, op, &len);
4339 break;
4340 default:
4341 break;
4344 else if (GET_CODE (op[1]) == ASHIFT
4345 || GET_CODE (op[1]) == ASHIFTRT
4346 || GET_CODE (op[1]) == LSHIFTRT)
4348 rtx ops[10];
4349 ops[0] = op[0];
4350 ops[1] = XEXP (op[1],0);
4351 ops[2] = XEXP (op[1],1);
4352 switch (GET_CODE (op[1]))
4354 case ASHIFT:
4355 switch (GET_MODE (op[0]))
4357 case QImode: ashlqi3_out (insn,ops,&len); break;
4358 case HImode: ashlhi3_out (insn,ops,&len); break;
4359 case SImode: ashlsi3_out (insn,ops,&len); break;
4360 default: break;
4362 break;
4363 case ASHIFTRT:
4364 switch (GET_MODE (op[0]))
4366 case QImode: ashrqi3_out (insn,ops,&len); break;
4367 case HImode: ashrhi3_out (insn,ops,&len); break;
4368 case SImode: ashrsi3_out (insn,ops,&len); break;
4369 default: break;
4371 break;
4372 case LSHIFTRT:
4373 switch (GET_MODE (op[0]))
4375 case QImode: lshrqi3_out (insn,ops,&len); break;
4376 case HImode: lshrhi3_out (insn,ops,&len); break;
4377 case SImode: lshrsi3_out (insn,ops,&len); break;
4378 default: break;
4380 break;
4381 default:
4382 break;
4386 return len;
4389 /* Return nonzero if register REG dead after INSN. */
4392 reg_unused_after (rtx insn, rtx reg)
4394 return (dead_or_set_p (insn, reg)
4395 || (REG_P(reg) && _reg_unused_after (insn, reg)));
4398 /* Return nonzero if REG is not used after INSN.
4399 We assume REG is a reload reg, and therefore does
4400 not live past labels. It may live past calls or jumps though. */
4403 _reg_unused_after (rtx insn, rtx reg)
4405 enum rtx_code code;
4406 rtx set;
4408 /* If the reg is set by this instruction, then it is safe for our
4409 case. Disregard the case where this is a store to memory, since
4410 we are checking a register used in the store address. */
4411 set = single_set (insn);
4412 if (set && GET_CODE (SET_DEST (set)) != MEM
4413 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4414 return 1;
4416 while ((insn = NEXT_INSN (insn)))
4418 rtx set;
4419 code = GET_CODE (insn);
4421 #if 0
4422 /* If this is a label that existed before reload, then the register
4423 if dead here. However, if this is a label added by reorg, then
4424 the register may still be live here. We can't tell the difference,
4425 so we just ignore labels completely. */
4426 if (code == CODE_LABEL)
4427 return 1;
4428 /* else */
4429 #endif
4431 if (!INSN_P (insn))
4432 continue;
4434 if (code == JUMP_INSN)
4435 return 0;
4437 /* If this is a sequence, we must handle them all at once.
4438 We could have for instance a call that sets the target register,
4439 and an insn in a delay slot that uses the register. In this case,
4440 we must return 0. */
4441 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
4443 int i;
4444 int retval = 0;
4446 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
4448 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
4449 rtx set = single_set (this_insn);
4451 if (GET_CODE (this_insn) == CALL_INSN)
4452 code = CALL_INSN;
4453 else if (GET_CODE (this_insn) == JUMP_INSN)
4455 if (INSN_ANNULLED_BRANCH_P (this_insn))
4456 return 0;
4457 code = JUMP_INSN;
4460 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4461 return 0;
4462 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4464 if (GET_CODE (SET_DEST (set)) != MEM)
4465 retval = 1;
4466 else
4467 return 0;
4469 if (set == 0
4470 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
4471 return 0;
4473 if (retval == 1)
4474 return 1;
4475 else if (code == JUMP_INSN)
4476 return 0;
4479 if (code == CALL_INSN)
4481 rtx tem;
4482 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4483 if (GET_CODE (XEXP (tem, 0)) == USE
4484 && REG_P (XEXP (XEXP (tem, 0), 0))
4485 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
4486 return 0;
4487 if (call_used_regs[REGNO (reg)])
4488 return 1;
4491 set = single_set (insn);
4493 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4494 return 0;
4495 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4496 return GET_CODE (SET_DEST (set)) != MEM;
4497 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
4498 return 0;
4500 return 1;
4503 /* Target hook for assembling integer objects. The AVR version needs
4504 special handling for references to certain labels. */
4506 static bool
4507 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
4509 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
4510 && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x))
4511 || GET_CODE (x) == LABEL_REF))
4513 fputs ("\t.word\tpm(", asm_out_file);
4514 output_addr_const (asm_out_file, x);
4515 fputs (")\n", asm_out_file);
4516 return true;
4518 return default_assemble_integer (x, size, aligned_p);
4521 /* The routine used to output NUL terminated strings. We use a special
4522 version of this for most svr4 targets because doing so makes the
4523 generated assembly code more compact (and thus faster to assemble)
4524 as well as more readable, especially for targets like the i386
4525 (where the only alternative is to output character sequences as
4526 comma separated lists of numbers). */
4528 void
4529 gas_output_limited_string(FILE *file, const char *str)
4531 const unsigned char *_limited_str = (unsigned char *) str;
4532 unsigned ch;
4533 fprintf (file, "%s\"", STRING_ASM_OP);
4534 for (; (ch = *_limited_str); _limited_str++)
4536 int escape;
4537 switch (escape = ESCAPES[ch])
4539 case 0:
4540 putc (ch, file);
4541 break;
4542 case 1:
4543 fprintf (file, "\\%03o", ch);
4544 break;
4545 default:
4546 putc ('\\', file);
4547 putc (escape, file);
4548 break;
4551 fprintf (file, "\"\n");
4554 /* The routine used to output sequences of byte values. We use a special
4555 version of this for most svr4 targets because doing so makes the
4556 generated assembly code more compact (and thus faster to assemble)
4557 as well as more readable. Note that if we find subparts of the
4558 character sequence which end with NUL (and which are shorter than
4559 STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
4561 void
4562 gas_output_ascii(FILE *file, const char *str, size_t length)
4564 const unsigned char *_ascii_bytes = (const unsigned char *) str;
4565 const unsigned char *limit = _ascii_bytes + length;
4566 unsigned bytes_in_chunk = 0;
4567 for (; _ascii_bytes < limit; _ascii_bytes++)
4569 const unsigned char *p;
4570 if (bytes_in_chunk >= 60)
4572 fprintf (file, "\"\n");
4573 bytes_in_chunk = 0;
4575 for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
4576 continue;
4577 if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
4579 if (bytes_in_chunk > 0)
4581 fprintf (file, "\"\n");
4582 bytes_in_chunk = 0;
4584 gas_output_limited_string (file, (char*)_ascii_bytes);
4585 _ascii_bytes = p;
4587 else
4589 int escape;
4590 unsigned ch;
4591 if (bytes_in_chunk == 0)
4592 fprintf (file, "\t.ascii\t\"");
4593 switch (escape = ESCAPES[ch = *_ascii_bytes])
4595 case 0:
4596 putc (ch, file);
4597 bytes_in_chunk++;
4598 break;
4599 case 1:
4600 fprintf (file, "\\%03o", ch);
4601 bytes_in_chunk += 4;
4602 break;
4603 default:
4604 putc ('\\', file);
4605 putc (escape, file);
4606 bytes_in_chunk += 2;
4607 break;
4611 if (bytes_in_chunk > 0)
4612 fprintf (file, "\"\n");
4615 /* Return value is nonzero if pseudos that have been
4616 assigned to registers of class CLASS would likely be spilled
4617 because registers of CLASS are needed for spill registers. */
4619 enum reg_class
4620 class_likely_spilled_p (int c)
4622 return (c != ALL_REGS && c != ADDW_REGS);
4625 /* Valid attributes:
4626 progmem - put data to program memory;
4627 signal - make a function to be hardware interrupt. After function
4628 prologue interrupts are disabled;
4629 interrupt - make a function to be hardware interrupt. After function
4630 prologue interrupts are enabled;
4631 naked - don't generate function prologue/epilogue and `ret' command.
4633 Only `progmem' attribute valid for type. */
4635 const struct attribute_spec avr_attribute_table[] =
4637 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
4638 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute },
4639 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4640 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4641 { "naked", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4642 { NULL, 0, 0, false, false, false, NULL }
4645 /* Handle a "progmem" attribute; arguments as in
4646 struct attribute_spec.handler. */
4647 static tree
4648 avr_handle_progmem_attribute (tree *node, tree name,
4649 tree args ATTRIBUTE_UNUSED,
4650 int flags ATTRIBUTE_UNUSED,
4651 bool *no_add_attrs)
4653 if (DECL_P (*node))
4655 if (TREE_CODE (*node) == TYPE_DECL)
4657 /* This is really a decl attribute, not a type attribute,
4658 but try to handle it for GCC 3.0 backwards compatibility. */
4660 tree type = TREE_TYPE (*node);
4661 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
4662 tree newtype = build_type_attribute_variant (type, attr);
4664 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
4665 TREE_TYPE (*node) = newtype;
4666 *no_add_attrs = true;
4668 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
4670 if (DECL_INITIAL (*node) == NULL_TREE && !DECL_EXTERNAL (*node))
4672 warning (0, "only initialized variables can be placed into "
4673 "program memory area");
4674 *no_add_attrs = true;
4677 else
4679 warning (OPT_Wattributes, "%qs attribute ignored",
4680 IDENTIFIER_POINTER (name));
4681 *no_add_attrs = true;
4685 return NULL_TREE;
4688 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
4689 struct attribute_spec.handler. */
4691 static tree
4692 avr_handle_fndecl_attribute (tree *node, tree name,
4693 tree args ATTRIBUTE_UNUSED,
4694 int flags ATTRIBUTE_UNUSED,
4695 bool *no_add_attrs)
4697 if (TREE_CODE (*node) != FUNCTION_DECL)
4699 warning (OPT_Wattributes, "%qs attribute only applies to functions",
4700 IDENTIFIER_POINTER (name));
4701 *no_add_attrs = true;
4703 else
4705 const char *func_name = IDENTIFIER_POINTER (DECL_NAME (*node));
4706 const char *attr = IDENTIFIER_POINTER (name);
4708 /* If the function has the 'signal' or 'interrupt' attribute, test to
4709 make sure that the name of the function is "__vector_NN" so as to
4710 catch when the user misspells the interrupt vector name. */
4712 if (strncmp (attr, "interrupt", strlen ("interrupt")) == 0)
4714 if (strncmp (func_name, "__vector", strlen ("__vector")) != 0)
4716 warning (0, "`%s' appears to be a misspelled interrupt handler",
4717 func_name);
4720 else if (strncmp (attr, "signal", strlen ("signal")) == 0)
4722 if (strncmp (func_name, "__vector", strlen ("__vector")) != 0)
4724 warning (0, "`%s' appears to be a misspelled signal handler",
4725 func_name);
4730 return NULL_TREE;
4733 /* Look for attribute `progmem' in DECL
4734 if found return 1, otherwise 0. */
4737 avr_progmem_p (tree decl, tree attributes)
4739 tree a;
4741 if (TREE_CODE (decl) != VAR_DECL)
4742 return 0;
4744 if (NULL_TREE
4745 != lookup_attribute ("progmem", attributes))
4746 return 1;
4748 a=decl;
4750 a = TREE_TYPE(a);
4751 while (TREE_CODE (a) == ARRAY_TYPE);
4753 if (a == error_mark_node)
4754 return 0;
4756 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
4757 return 1;
4759 return 0;
4762 /* Add the section attribute if the variable is in progmem. */
4764 static void
4765 avr_insert_attributes (tree node, tree *attributes)
4767 if (TREE_CODE (node) == VAR_DECL
4768 && (TREE_STATIC (node) || DECL_EXTERNAL (node))
4769 && avr_progmem_p (node, *attributes))
4771 static const char dsec[] = ".progmem.data";
4772 *attributes = tree_cons (get_identifier ("section"),
4773 build_tree_list (NULL, build_string (strlen (dsec), dsec)),
4774 *attributes);
4776 /* ??? This seems sketchy. Why can't the user declare the
4777 thing const in the first place? */
4778 TREE_READONLY (node) = 1;
4782 static unsigned int
4783 avr_section_type_flags (tree decl, const char *name, int reloc)
4785 unsigned int flags = default_section_type_flags (decl, name, reloc);
4787 if (strncmp (name, ".noinit", 7) == 0)
4789 if (decl && TREE_CODE (decl) == VAR_DECL
4790 && DECL_INITIAL (decl) == NULL_TREE)
4791 flags |= SECTION_BSS; /* @nobits */
4792 else
4793 warning (0, "only uninitialized variables can be placed in the "
4794 ".noinit section");
4797 return flags;
4800 /* Outputs some appropriate text to go at the start of an assembler
4801 file. */
4803 static void
4804 avr_file_start (void)
4806 if (avr_asm_only_p)
4807 error ("MCU %qs supported for assembler only", avr_mcu_name);
4809 default_file_start ();
4811 fprintf (asm_out_file, "\t.arch %s\n", avr_mcu_name);
4812 fputs ("__SREG__ = 0x3f\n"
4813 "__SP_H__ = 0x3e\n"
4814 "__SP_L__ = 0x3d\n", asm_out_file);
4816 fputs ("__tmp_reg__ = 0\n"
4817 "__zero_reg__ = 1\n", asm_out_file);
4819 /* FIXME: output these only if there is anything in the .data / .bss
4820 sections - some code size could be saved by not linking in the
4821 initialization code from libgcc if one or both sections are empty. */
4822 fputs ("\t.global __do_copy_data\n", asm_out_file);
4823 fputs ("\t.global __do_clear_bss\n", asm_out_file);
4825 commands_in_file = 0;
4826 commands_in_prologues = 0;
4827 commands_in_epilogues = 0;
4830 /* Outputs to the stdio stream FILE some
4831 appropriate text to go at the end of an assembler file. */
4833 static void
4834 avr_file_end (void)
4836 fputs ("/* File ", asm_out_file);
4837 output_quoted_string (asm_out_file, main_input_filename);
4838 fprintf (asm_out_file,
4839 ": code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
4840 commands_in_file,
4841 commands_in_file,
4842 commands_in_file - commands_in_prologues - commands_in_epilogues,
4843 commands_in_prologues, commands_in_epilogues);
4846 /* Choose the order in which to allocate hard registers for
4847 pseudo-registers local to a basic block.
4849 Store the desired register order in the array `reg_alloc_order'.
4850 Element 0 should be the register to allocate first; element 1, the
4851 next register; and so on. */
4853 void
4854 order_regs_for_local_alloc (void)
4856 unsigned int i;
4857 static const int order_0[] = {
4858 24,25,
4859 18,19,
4860 20,21,
4861 22,23,
4862 30,31,
4863 26,27,
4864 28,29,
4865 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4866 0,1,
4867 32,33,34,35
4869 static const int order_1[] = {
4870 18,19,
4871 20,21,
4872 22,23,
4873 24,25,
4874 30,31,
4875 26,27,
4876 28,29,
4877 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4878 0,1,
4879 32,33,34,35
4881 static const int order_2[] = {
4882 25,24,
4883 23,22,
4884 21,20,
4885 19,18,
4886 30,31,
4887 26,27,
4888 28,29,
4889 17,16,
4890 15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4891 1,0,
4892 32,33,34,35
4895 const int *order = (TARGET_ORDER_1 ? order_1 :
4896 TARGET_ORDER_2 ? order_2 :
4897 order_0);
4898 for (i=0; i < ARRAY_SIZE (order_0); ++i)
4899 reg_alloc_order[i] = order[i];
4903 /* Mutually recursive subroutine of avr_rtx_cost for calculating the
4904 cost of an RTX operand given its context. X is the rtx of the
4905 operand, MODE is its mode, and OUTER is the rtx_code of this
4906 operand's parent operator. */
4908 static int
4909 avr_operand_rtx_cost (rtx x, enum machine_mode mode, enum rtx_code outer)
4911 enum rtx_code code = GET_CODE (x);
4912 int total;
4914 switch (code)
4916 case REG:
4917 case SUBREG:
4918 return 0;
4920 case CONST_INT:
4921 case CONST_DOUBLE:
4922 return COSTS_N_INSNS (GET_MODE_SIZE (mode));
4924 default:
4925 break;
4928 total = 0;
4929 avr_rtx_costs (x, code, outer, &total);
4930 return total;
4933 /* The AVR backend's rtx_cost function. X is rtx expression whose cost
4934 is to be calculated. Return true if the complete cost has been
4935 computed, and false if subexpressions should be scanned. In either
4936 case, *TOTAL contains the cost result. */
4938 static bool
4939 avr_rtx_costs (rtx x, int code, int outer_code, int *total)
4941 enum machine_mode mode = GET_MODE (x);
4942 HOST_WIDE_INT val;
4944 switch (code)
4946 case CONST_INT:
4947 case CONST_DOUBLE:
4948 /* Immediate constants are as cheap as registers. */
4949 *total = 0;
4950 return true;
4952 case MEM:
4953 case CONST:
4954 case LABEL_REF:
4955 case SYMBOL_REF:
4956 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
4957 return true;
4959 case NEG:
4960 switch (mode)
4962 case QImode:
4963 case SFmode:
4964 *total = COSTS_N_INSNS (1);
4965 break;
4967 case HImode:
4968 *total = COSTS_N_INSNS (3);
4969 break;
4971 case SImode:
4972 *total = COSTS_N_INSNS (7);
4973 break;
4975 default:
4976 return false;
4978 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
4979 return true;
4981 case ABS:
4982 switch (mode)
4984 case QImode:
4985 case SFmode:
4986 *total = COSTS_N_INSNS (1);
4987 break;
4989 default:
4990 return false;
4992 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
4993 return true;
4995 case NOT:
4996 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
4997 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
4998 return true;
5000 case ZERO_EXTEND:
5001 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
5002 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
5003 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5004 return true;
5006 case SIGN_EXTEND:
5007 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
5008 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
5009 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5010 return true;
5012 case PLUS:
5013 switch (mode)
5015 case QImode:
5016 *total = COSTS_N_INSNS (1);
5017 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5018 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5019 break;
5021 case HImode:
5022 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5024 *total = COSTS_N_INSNS (2);
5025 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5027 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
5028 *total = COSTS_N_INSNS (1);
5029 else
5030 *total = COSTS_N_INSNS (2);
5031 break;
5033 case SImode:
5034 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5036 *total = COSTS_N_INSNS (4);
5037 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5039 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
5040 *total = COSTS_N_INSNS (1);
5041 else
5042 *total = COSTS_N_INSNS (4);
5043 break;
5045 default:
5046 return false;
5048 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5049 return true;
5051 case MINUS:
5052 case AND:
5053 case IOR:
5054 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5055 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5056 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5057 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5058 return true;
5060 case XOR:
5061 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5062 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5063 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5064 return true;
5066 case MULT:
5067 switch (mode)
5069 case QImode:
5070 if (AVR_ENHANCED)
5071 *total = COSTS_N_INSNS (optimize_size ? 3 : 4);
5072 else if (optimize_size)
5073 *total = COSTS_N_INSNS (AVR_MEGA ? 2 : 1);
5074 else
5075 return false;
5077 case HImode:
5078 if (AVR_ENHANCED)
5079 *total = COSTS_N_INSNS (optimize_size ? 7 : 10);
5080 else if (optimize_size)
5081 *total = COSTS_N_INSNS (AVR_MEGA ? 2 : 1);
5082 else
5083 return false;
5085 default:
5086 return false;
5088 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5089 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5090 return true;
5092 case DIV:
5093 case MOD:
5094 case UDIV:
5095 case UMOD:
5096 if (optimize_size)
5097 *total = COSTS_N_INSNS (AVR_MEGA ? 2 : 1);
5098 else
5099 return false;
5100 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5101 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5102 return true;
5104 case ASHIFT:
5105 switch (mode)
5107 case QImode:
5108 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5110 *total = COSTS_N_INSNS (optimize_size ? 4 : 17);
5111 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5113 else
5115 val = INTVAL (XEXP (x, 1));
5116 if (val == 7)
5117 *total = COSTS_N_INSNS (3);
5118 else if (val >= 0 && val <= 7)
5119 *total = COSTS_N_INSNS (val);
5120 else
5121 *total = COSTS_N_INSNS (1);
5123 break;
5125 case HImode:
5126 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5128 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5129 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5131 else
5132 switch (INTVAL (XEXP (x, 1)))
5134 case 0:
5135 *total = 0;
5136 break;
5137 case 1:
5138 case 8:
5139 *total = COSTS_N_INSNS (2);
5140 break;
5141 case 9:
5142 *total = COSTS_N_INSNS (3);
5143 break;
5144 case 2:
5145 case 3:
5146 case 10:
5147 case 15:
5148 *total = COSTS_N_INSNS (4);
5149 break;
5150 case 7:
5151 case 11:
5152 case 12:
5153 *total = COSTS_N_INSNS (5);
5154 break;
5155 case 4:
5156 *total = COSTS_N_INSNS (optimize_size ? 5 : 8);
5157 break;
5158 case 6:
5159 *total = COSTS_N_INSNS (optimize_size ? 5 : 9);
5160 break;
5161 case 5:
5162 *total = COSTS_N_INSNS (optimize_size ? 5 : 10);
5163 break;
5164 default:
5165 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5166 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5168 break;
5170 case SImode:
5171 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5173 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5174 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5176 else
5177 switch (INTVAL (XEXP (x, 1)))
5179 case 0:
5180 *total = 0;
5181 break;
5182 case 24:
5183 *total = COSTS_N_INSNS (3);
5184 break;
5185 case 1:
5186 case 8:
5187 case 16:
5188 *total = COSTS_N_INSNS (4);
5189 break;
5190 case 31:
5191 *total = COSTS_N_INSNS (6);
5192 break;
5193 case 2:
5194 *total = COSTS_N_INSNS (optimize_size ? 7 : 8);
5195 break;
5196 default:
5197 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5198 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5200 break;
5202 default:
5203 return false;
5205 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5206 return true;
5208 case ASHIFTRT:
5209 switch (mode)
5211 case QImode:
5212 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5214 *total = COSTS_N_INSNS (optimize_size ? 4 : 17);
5215 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5217 else
5219 val = INTVAL (XEXP (x, 1));
5220 if (val == 6)
5221 *total = COSTS_N_INSNS (4);
5222 else if (val == 7)
5223 *total = COSTS_N_INSNS (2);
5224 else if (val >= 0 && val <= 7)
5225 *total = COSTS_N_INSNS (val);
5226 else
5227 *total = COSTS_N_INSNS (1);
5229 break;
5231 case HImode:
5232 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5234 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5235 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5237 else
5238 switch (INTVAL (XEXP (x, 1)))
5240 case 0:
5241 *total = 0;
5242 break;
5243 case 1:
5244 *total = COSTS_N_INSNS (2);
5245 break;
5246 case 15:
5247 *total = COSTS_N_INSNS (3);
5248 break;
5249 case 2:
5250 case 7:
5251 case 8:
5252 case 9:
5253 *total = COSTS_N_INSNS (4);
5254 break;
5255 case 10:
5256 case 14:
5257 *total = COSTS_N_INSNS (5);
5258 break;
5259 case 11:
5260 *total = COSTS_N_INSNS (optimize_size ? 5 : 6);
5261 break;
5262 case 12:
5263 *total = COSTS_N_INSNS (optimize_size ? 5 : 7);
5264 break;
5265 case 6:
5266 case 13:
5267 *total = COSTS_N_INSNS (optimize_size ? 5 : 8);
5268 break;
5269 default:
5270 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5271 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5273 break;
5275 case SImode:
5276 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5278 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5279 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5281 else
5282 switch (INTVAL (XEXP (x, 1)))
5284 case 0:
5285 *total = 0;
5286 break;
5287 case 1:
5288 *total = COSTS_N_INSNS (4);
5289 break;
5290 case 8:
5291 case 16:
5292 case 24:
5293 *total = COSTS_N_INSNS (6);
5294 break;
5295 case 2:
5296 *total = COSTS_N_INSNS (optimize_size ? 7 : 8);
5297 break;
5298 case 31:
5299 *total = COSTS_N_INSNS (AVR_ENHANCED ? 4 : 5);
5300 break;
5301 default:
5302 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5303 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5305 break;
5307 default:
5308 return false;
5310 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5311 return true;
5313 case LSHIFTRT:
5314 switch (mode)
5316 case QImode:
5317 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5319 *total = COSTS_N_INSNS (optimize_size ? 4 : 17);
5320 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5322 else
5324 val = INTVAL (XEXP (x, 1));
5325 if (val == 7)
5326 *total = COSTS_N_INSNS (3);
5327 else if (val >= 0 && val <= 7)
5328 *total = COSTS_N_INSNS (val);
5329 else
5330 *total = COSTS_N_INSNS (1);
5332 break;
5334 case HImode:
5335 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5337 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5338 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5340 else
5341 switch (INTVAL (XEXP (x, 1)))
5343 case 0:
5344 *total = 0;
5345 break;
5346 case 1:
5347 case 8:
5348 *total = COSTS_N_INSNS (2);
5349 break;
5350 case 9:
5351 *total = COSTS_N_INSNS (3);
5352 break;
5353 case 2:
5354 case 10:
5355 case 15:
5356 *total = COSTS_N_INSNS (4);
5357 break;
5358 case 7:
5359 case 11:
5360 *total = COSTS_N_INSNS (5);
5361 break;
5362 case 3:
5363 case 12:
5364 case 13:
5365 case 14:
5366 *total = COSTS_N_INSNS (optimize_size ? 5 : 6);
5367 break;
5368 case 4:
5369 *total = COSTS_N_INSNS (optimize_size ? 5 : 7);
5370 break;
5371 case 5:
5372 case 6:
5373 *total = COSTS_N_INSNS (optimize_size ? 5 : 9);
5374 break;
5375 default:
5376 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5377 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5379 break;
5381 case SImode:
5382 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5384 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5385 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5387 else
5388 switch (INTVAL (XEXP (x, 1)))
5390 case 0:
5391 *total = 0;
5392 break;
5393 case 1:
5394 *total = COSTS_N_INSNS (4);
5395 break;
5396 case 2:
5397 *total = COSTS_N_INSNS (optimize_size ? 7 : 8);
5398 break;
5399 case 8:
5400 case 16:
5401 case 24:
5402 *total = COSTS_N_INSNS (4);
5403 break;
5404 case 31:
5405 *total = COSTS_N_INSNS (6);
5406 break;
5407 default:
5408 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5409 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5411 break;
5413 default:
5414 return false;
5416 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5417 return true;
5419 case COMPARE:
5420 switch (GET_MODE (XEXP (x, 0)))
5422 case QImode:
5423 *total = COSTS_N_INSNS (1);
5424 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5425 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5426 break;
5428 case HImode:
5429 *total = COSTS_N_INSNS (2);
5430 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5431 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5432 else if (INTVAL (XEXP (x, 1)) != 0)
5433 *total += COSTS_N_INSNS (1);
5434 break;
5436 case SImode:
5437 *total = COSTS_N_INSNS (4);
5438 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5439 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5440 else if (INTVAL (XEXP (x, 1)) != 0)
5441 *total += COSTS_N_INSNS (3);
5442 break;
5444 default:
5445 return false;
5447 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5448 return true;
5450 default:
5451 break;
5453 return false;
5456 /* Calculate the cost of a memory address. */
5458 static int
5459 avr_address_cost (rtx x)
5461 if (GET_CODE (x) == PLUS
5462 && GET_CODE (XEXP (x,1)) == CONST_INT
5463 && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
5464 && INTVAL (XEXP (x,1)) >= 61)
5465 return 18;
5466 if (CONSTANT_ADDRESS_P (x))
5468 if (avr_io_address_p (x, 1))
5469 return 2;
5470 return 4;
5472 return 4;
5475 /* EXTRA_CONSTRAINT helper */
5478 extra_constraint (rtx x, int c)
5480 if (c == 'Q'
5481 && GET_CODE (x) == MEM
5482 && GET_CODE (XEXP (x,0)) == PLUS)
5484 if (TARGET_ALL_DEBUG)
5486 fprintf (stderr, ("extra_constraint:\n"
5487 "reload_completed: %d\n"
5488 "reload_in_progress: %d\n"),
5489 reload_completed, reload_in_progress);
5490 debug_rtx (x);
5492 if (GET_CODE (x) == MEM
5493 && GET_CODE (XEXP (x,0)) == PLUS
5494 && REG_P (XEXP (XEXP (x,0), 0))
5495 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
5496 && (INTVAL (XEXP (XEXP (x,0), 1))
5497 <= MAX_LD_OFFSET (GET_MODE (x))))
5499 rtx xx = XEXP (XEXP (x,0), 0);
5500 int regno = REGNO (xx);
5501 if (TARGET_ALL_DEBUG)
5503 fprintf (stderr, ("extra_constraint:\n"
5504 "reload_completed: %d\n"
5505 "reload_in_progress: %d\n"),
5506 reload_completed, reload_in_progress);
5507 debug_rtx (x);
5509 if (regno >= FIRST_PSEUDO_REGISTER)
5510 return 1; /* allocate pseudos */
5511 else if (regno == REG_Z || regno == REG_Y)
5512 return 1; /* strictly check */
5513 else if (xx == frame_pointer_rtx
5514 || xx == arg_pointer_rtx)
5515 return 1; /* XXX frame & arg pointer checks */
5518 return 0;
5521 /* Convert condition code CONDITION to the valid AVR condition code. */
5523 RTX_CODE
5524 avr_normalize_condition (RTX_CODE condition)
5526 switch (condition)
5528 case GT:
5529 return GE;
5530 case GTU:
5531 return GEU;
5532 case LE:
5533 return LT;
5534 case LEU:
5535 return LTU;
5536 default:
5537 gcc_unreachable ();
5541 /* This function optimizes conditional jumps. */
5543 static void
5544 avr_reorg (void)
5546 rtx insn, pattern;
5548 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5550 if (! (GET_CODE (insn) == INSN
5551 || GET_CODE (insn) == CALL_INSN
5552 || GET_CODE (insn) == JUMP_INSN)
5553 || !single_set (insn))
5554 continue;
5556 pattern = PATTERN (insn);
5558 if (GET_CODE (pattern) == PARALLEL)
5559 pattern = XVECEXP (pattern, 0, 0);
5560 if (GET_CODE (pattern) == SET
5561 && SET_DEST (pattern) == cc0_rtx
5562 && compare_diff_p (insn))
5564 if (GET_CODE (SET_SRC (pattern)) == COMPARE)
5566 /* Now we work under compare insn. */
5568 pattern = SET_SRC (pattern);
5569 if (true_regnum (XEXP (pattern,0)) >= 0
5570 && true_regnum (XEXP (pattern,1)) >= 0 )
5572 rtx x = XEXP (pattern,0);
5573 rtx next = next_real_insn (insn);
5574 rtx pat = PATTERN (next);
5575 rtx src = SET_SRC (pat);
5576 rtx t = XEXP (src,0);
5577 PUT_CODE (t, swap_condition (GET_CODE (t)));
5578 XEXP (pattern,0) = XEXP (pattern,1);
5579 XEXP (pattern,1) = x;
5580 INSN_CODE (next) = -1;
5582 else if (true_regnum (XEXP (pattern,0)) >= 0
5583 && GET_CODE (XEXP (pattern,1)) == CONST_INT)
5585 rtx x = XEXP (pattern,1);
5586 rtx next = next_real_insn (insn);
5587 rtx pat = PATTERN (next);
5588 rtx src = SET_SRC (pat);
5589 rtx t = XEXP (src,0);
5590 enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
5592 if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
5594 XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
5595 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
5596 INSN_CODE (next) = -1;
5597 INSN_CODE (insn) = -1;
5601 else if (true_regnum (SET_SRC (pattern)) >= 0)
5603 /* This is a tst insn */
5604 rtx next = next_real_insn (insn);
5605 rtx pat = PATTERN (next);
5606 rtx src = SET_SRC (pat);
5607 rtx t = XEXP (src,0);
5609 PUT_CODE (t, swap_condition (GET_CODE (t)));
5610 SET_SRC (pattern) = gen_rtx_NEG (GET_MODE (SET_SRC (pattern)),
5611 SET_SRC (pattern));
5612 INSN_CODE (next) = -1;
5613 INSN_CODE (insn) = -1;
5619 /* Returns register number for function return value.*/
5622 avr_ret_register (void)
5624 return 24;
5627 /* Ceate an RTX representing the place where a
5628 library function returns a value of mode MODE. */
5631 avr_libcall_value (enum machine_mode mode)
5633 int offs = GET_MODE_SIZE (mode);
5634 if (offs < 2)
5635 offs = 2;
5636 return gen_rtx_REG (mode, RET_REGISTER + 2 - offs);
5639 /* Create an RTX representing the place where a
5640 function returns a value of data type VALTYPE. */
5643 avr_function_value (tree type, tree func ATTRIBUTE_UNUSED)
5645 unsigned int offs;
5647 if (TYPE_MODE (type) != BLKmode)
5648 return avr_libcall_value (TYPE_MODE (type));
5650 offs = int_size_in_bytes (type);
5651 if (offs < 2)
5652 offs = 2;
5653 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
5654 offs = GET_MODE_SIZE (SImode);
5655 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
5656 offs = GET_MODE_SIZE (DImode);
5658 return gen_rtx_REG (BLKmode, RET_REGISTER + 2 - offs);
5661 /* Returns nonzero if the number MASK has only one bit set. */
5664 mask_one_bit_p (HOST_WIDE_INT mask)
5666 int i;
5667 unsigned HOST_WIDE_INT n=mask;
5668 for (i = 0; i < 32; ++i)
5670 if (n & 0x80000000L)
5672 if (n & 0x7fffffffL)
5673 return 0;
5674 else
5675 return 32-i;
5677 n<<=1;
5679 return 0;
5683 /* Places additional restrictions on the register class to
5684 use when it is necessary to copy value X into a register
5685 in class CLASS. */
5687 enum reg_class
5688 preferred_reload_class (rtx x ATTRIBUTE_UNUSED, enum reg_class class)
5690 return class;
5694 test_hard_reg_class (enum reg_class class, rtx x)
5696 int regno = true_regnum (x);
5697 if (regno < 0)
5698 return 0;
5700 if (TEST_HARD_REG_CLASS (class, regno))
5701 return 1;
5703 return 0;
5708 jump_over_one_insn_p (rtx insn, rtx dest)
5710 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
5711 ? XEXP (dest, 0)
5712 : dest);
5713 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
5714 int dest_addr = INSN_ADDRESSES (uid);
5715 return dest_addr - jump_addr == get_attr_length (insn) + 1;
5718 /* Returns 1 if a value of mode MODE can be stored starting with hard
5719 register number REGNO. On the enhanced core, anything larger than
5720 1 byte must start in even numbered register for "movw" to work
5721 (this way we don't have to check for odd registers everywhere). */
5724 avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
5726 /* The only thing that can go into registers r28:r29 is a Pmode. */
5727 if (regno == REG_Y && mode == Pmode)
5728 return 1;
5730 /* Otherwise disallow all regno/mode combinations that span r28:r29. */
5731 if (regno <= (REG_Y + 1) && (regno + GET_MODE_SIZE (mode)) >= (REG_Y + 1))
5732 return 0;
5734 if (mode == QImode)
5735 return 1;
5737 /* Modes larger than QImode occupy consecutive registers. */
5738 if (regno + GET_MODE_SIZE (mode) > FIRST_PSEUDO_REGISTER)
5739 return 0;
5741 /* All modes larger than QImode should start in an even register. */
5742 return !(regno & 1);
5745 /* Returns 1 if X is a valid address for an I/O register of size SIZE
5746 (1 or 2). Used for lds/sts -> in/out optimization. Add 0x20 to SIZE
5747 to check for the lower half of I/O space (for cbi/sbi/sbic/sbis). */
5750 avr_io_address_p (rtx x, int size)
5752 return (optimize > 0 && GET_CODE (x) == CONST_INT
5753 && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size);
5756 /* Returns nonzero (bit number + 1) if X, or -X, is a constant power of 2. */
5759 const_int_pow2_p (rtx x)
5761 if (GET_CODE (x) == CONST_INT)
5763 HOST_WIDE_INT d = INTVAL (x);
5764 HOST_WIDE_INT abs_d = (d >= 0) ? d : -d;
5765 return exact_log2 (abs_d) + 1;
5767 return 0;
5770 const char *
5771 output_reload_inhi (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
5773 int tmp;
5774 if (!len)
5775 len = &tmp;
5777 if (GET_CODE (operands[1]) == CONST_INT)
5779 int val = INTVAL (operands[1]);
5780 if ((val & 0xff) == 0)
5782 *len = 3;
5783 return (AS2 (mov,%A0,__zero_reg__) CR_TAB
5784 AS2 (ldi,%2,hi8(%1)) CR_TAB
5785 AS2 (mov,%B0,%2));
5787 else if ((val & 0xff00) == 0)
5789 *len = 3;
5790 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5791 AS2 (mov,%A0,%2) CR_TAB
5792 AS2 (mov,%B0,__zero_reg__));
5794 else if ((val & 0xff) == ((val & 0xff00) >> 8))
5796 *len = 3;
5797 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5798 AS2 (mov,%A0,%2) CR_TAB
5799 AS2 (mov,%B0,%2));
5802 *len = 4;
5803 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5804 AS2 (mov,%A0,%2) CR_TAB
5805 AS2 (ldi,%2,hi8(%1)) CR_TAB
5806 AS2 (mov,%B0,%2));
5810 const char *
5811 output_reload_insisf (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
5813 rtx src = operands[1];
5814 int cnst = (GET_CODE (src) == CONST_INT);
5816 if (len)
5818 if (cnst)
5819 *len = 4 + ((INTVAL (src) & 0xff) != 0)
5820 + ((INTVAL (src) & 0xff00) != 0)
5821 + ((INTVAL (src) & 0xff0000) != 0)
5822 + ((INTVAL (src) & 0xff000000) != 0);
5823 else
5824 *len = 8;
5826 return "";
5829 if (cnst && ((INTVAL (src) & 0xff) == 0))
5830 output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
5831 else
5833 output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
5834 output_asm_insn (AS2 (mov, %A0, %2), operands);
5836 if (cnst && ((INTVAL (src) & 0xff00) == 0))
5837 output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
5838 else
5840 output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
5841 output_asm_insn (AS2 (mov, %B0, %2), operands);
5843 if (cnst && ((INTVAL (src) & 0xff0000) == 0))
5844 output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
5845 else
5847 output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
5848 output_asm_insn (AS2 (mov, %C0, %2), operands);
5850 if (cnst && ((INTVAL (src) & 0xff000000) == 0))
5851 output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
5852 else
5854 output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
5855 output_asm_insn (AS2 (mov, %D0, %2), operands);
5857 return "";
5860 void
5861 avr_output_bld (rtx operands[], int bit_nr)
5863 static char s[] = "bld %A0,0";
5865 s[5] = 'A' + (bit_nr >> 3);
5866 s[8] = '0' + (bit_nr & 7);
5867 output_asm_insn (s, operands);
5870 void
5871 avr_output_addr_vec_elt (FILE *stream, int value)
5873 progmem_section ();
5874 if (AVR_MEGA)
5875 fprintf (stream, "\t.word pm(.L%d)\n", value);
5876 else
5877 fprintf (stream, "\trjmp .L%d\n", value);
5879 jump_tables_size++;
5882 /* Returns 1 if SCRATCH are safe to be allocated as a scratch
5883 registers (for a define_peephole2) in the current function. */
5886 avr_peep2_scratch_safe (rtx scratch)
5888 if ((interrupt_function_p (current_function_decl)
5889 || signal_function_p (current_function_decl))
5890 && leaf_function_p ())
5892 int first_reg = true_regnum (scratch);
5893 int last_reg = first_reg + GET_MODE_SIZE (GET_MODE (scratch)) - 1;
5894 int reg;
5896 for (reg = first_reg; reg <= last_reg; reg++)
5898 if (!regs_ever_live[reg])
5899 return 0;
5902 return 1;
5905 /* Output a branch that tests a single bit of a register (QI, HI or SImode)
5906 or memory location in the I/O space (QImode only).
5908 Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
5909 Operand 1: register operand to test, or CONST_INT memory address.
5910 Operand 2: bit number (for QImode operand) or mask (HImode, SImode).
5911 Operand 3: label to jump to if the test is true. */
5913 const char *
5914 avr_out_sbxx_branch (rtx insn, rtx operands[])
5916 enum rtx_code comp = GET_CODE (operands[0]);
5917 int long_jump = (get_attr_length (insn) >= 4);
5918 int reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
5920 if (comp == GE)
5921 comp = EQ;
5922 else if (comp == LT)
5923 comp = NE;
5925 if (reverse)
5926 comp = reverse_condition (comp);
5928 if (GET_CODE (operands[1]) == CONST_INT)
5930 if (INTVAL (operands[1]) < 0x40)
5932 if (comp == EQ)
5933 output_asm_insn (AS2 (sbis,%1-0x20,%2), operands);
5934 else
5935 output_asm_insn (AS2 (sbic,%1-0x20,%2), operands);
5937 else
5939 output_asm_insn (AS2 (in,__tmp_reg__,%1-0x20), operands);
5940 if (comp == EQ)
5941 output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands);
5942 else
5943 output_asm_insn (AS2 (sbrc,__tmp_reg__,%2), operands);
5946 else /* GET_CODE (operands[1]) == REG */
5948 if (GET_MODE (operands[1]) == QImode)
5950 if (comp == EQ)
5951 output_asm_insn (AS2 (sbrs,%1,%2), operands);
5952 else
5953 output_asm_insn (AS2 (sbrc,%1,%2), operands);
5955 else /* HImode or SImode */
5957 static char buf[] = "sbrc %A1,0";
5958 int bit_nr = exact_log2 (INTVAL (operands[2])
5959 & GET_MODE_MASK (GET_MODE (operands[1])));
5961 buf[3] = (comp == EQ) ? 's' : 'c';
5962 buf[6] = 'A' + (bit_nr >> 3);
5963 buf[9] = '0' + (bit_nr & 7);
5964 output_asm_insn (buf, operands);
5968 if (long_jump)
5969 return (AS1 (rjmp,.+4) CR_TAB
5970 AS1 (jmp,%3));
5971 if (!reverse)
5972 return AS1 (rjmp,%3);
5973 return "";
5976 /* Worker function for TARGET_ASM_CONSTRUCTOR. */
5978 static void
5979 avr_asm_out_ctor (rtx symbol, int priority)
5981 fputs ("\t.global __do_global_ctors\n", asm_out_file);
5982 default_ctor_section_asm_out_constructor (symbol, priority);
5985 /* Worker function for TARGET_ASM_DESTRUCTOR. */
5987 static void
5988 avr_asm_out_dtor (rtx symbol, int priority)
5990 fputs ("\t.global __do_global_dtors\n", asm_out_file);
5991 default_dtor_section_asm_out_destructor (symbol, priority);
5994 /* Worker function for TARGET_RETURN_IN_MEMORY. */
5996 static bool
5997 avr_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
5999 if (TYPE_MODE (type) == BLKmode)
6001 HOST_WIDE_INT size = int_size_in_bytes (type);
6002 return (size == -1 || size > 8);
6004 else
6005 return false;
6008 #include "gt-avr.h"