Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / gcc / config / avr / avr.c
blob42dbf0295c7d9b646f61b6855a0585fdf693b96f
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 int avr_naked_function_p (tree);
52 static int interrupt_function_p (tree);
53 static int signal_function_p (tree);
54 static int avr_regs_to_save (HARD_REG_SET *);
55 static int sequent_regs_live (void);
56 static const char *ptrreg_to_str (int);
57 static const char *cond_string (enum rtx_code);
58 static int avr_num_arg_regs (enum machine_mode, tree);
59 static int out_adj_frame_ptr (FILE *, int);
60 static int out_set_stack_ptr (FILE *, int, int);
61 static RTX_CODE compare_condition (rtx insn);
62 static int compare_sign_p (rtx insn);
63 static tree avr_handle_progmem_attribute (tree *, tree, tree, int, bool *);
64 static tree avr_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
65 const struct attribute_spec avr_attribute_table[];
66 static bool avr_assemble_integer (rtx, unsigned int, int);
67 static void avr_file_start (void);
68 static void avr_file_end (void);
69 static void avr_output_function_prologue (FILE *, HOST_WIDE_INT);
70 static void avr_output_function_epilogue (FILE *, HOST_WIDE_INT);
71 static void avr_insert_attributes (tree, tree *);
72 static unsigned int avr_section_type_flags (tree, const char *, int);
74 static void avr_reorg (void);
75 static void avr_asm_out_ctor (rtx, int);
76 static void avr_asm_out_dtor (rtx, int);
77 static int avr_operand_rtx_cost (rtx, enum machine_mode, enum rtx_code);
78 static bool avr_rtx_costs (rtx, int, int, int *);
79 static int avr_address_cost (rtx);
80 static bool avr_return_in_memory (tree, tree);
82 /* Allocate registers from r25 to r8 for parameters for function calls. */
83 #define FIRST_CUM_REG 26
85 /* Temporary register RTX (gen_rtx_REG (QImode, TMP_REGNO)) */
86 static GTY(()) rtx tmp_reg_rtx;
88 /* Zeroed register RTX (gen_rtx_REG (QImode, ZERO_REGNO)) */
89 static GTY(()) rtx zero_reg_rtx;
91 /* AVR register names {"r0", "r1", ..., "r31"} */
92 static const char *const avr_regnames[] = REGISTER_NAMES;
94 /* This holds the last insn address. */
95 static int last_insn_address = 0;
97 /* Commands count in the compiled file */
98 static int commands_in_file;
100 /* Commands in the functions prologues in the compiled file */
101 static int commands_in_prologues;
103 /* Commands in the functions epilogues in the compiled file */
104 static int commands_in_epilogues;
106 /* Prologue/Epilogue size in words */
107 static int prologue_size;
108 static int epilogue_size;
110 /* Size of all jump tables in the current function, in words. */
111 static int jump_tables_size;
113 /* Initial stack value specified by the `-minit-stack=' option */
114 const char *avr_init_stack = "__stack";
116 /* Default MCU name */
117 const char *avr_mcu_name = "avr2";
119 /* Preprocessor macros to define depending on MCU type. */
120 const char *avr_base_arch_macro;
121 const char *avr_extra_arch_macro;
123 /* More than 8K of program memory: use "call" and "jmp". */
124 int avr_mega_p = 0;
126 /* Enhanced core: use "movw", "mul", ... */
127 int avr_enhanced_p = 0;
129 /* Assembler only. */
130 int avr_asm_only_p = 0;
132 struct base_arch_s {
133 int asm_only;
134 int enhanced;
135 int mega;
136 const char *const macro;
139 static const struct base_arch_s avr_arch_types[] = {
140 { 1, 0, 0, NULL }, /* unknown device specified */
141 { 1, 0, 0, "__AVR_ARCH__=1" },
142 { 0, 0, 0, "__AVR_ARCH__=2" },
143 { 0, 0, 1, "__AVR_ARCH__=3" },
144 { 0, 1, 0, "__AVR_ARCH__=4" },
145 { 0, 1, 1, "__AVR_ARCH__=5" }
148 struct mcu_type_s {
149 const char *const name;
150 int arch; /* index in avr_arch_types[] */
151 /* Must lie outside user's namespace. NULL == no macro. */
152 const char *const macro;
155 /* List of all known AVR MCU types - if updated, it has to be kept
156 in sync in several places (FIXME: is there a better way?):
157 - here
158 - avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
159 - t-avr (MULTILIB_MATCHES)
160 - gas/config/tc-avr.c
161 - avr-libc */
163 static const struct mcu_type_s avr_mcu_types[] = {
164 /* Classic, <= 8K. */
165 { "avr2", 2, NULL },
166 { "at90s2313", 2, "__AVR_AT90S2313__" },
167 { "at90s2323", 2, "__AVR_AT90S2323__" },
168 { "at90s2333", 2, "__AVR_AT90S2333__" },
169 { "at90s2343", 2, "__AVR_AT90S2343__" },
170 { "attiny22", 2, "__AVR_ATtiny22__" },
171 { "attiny26", 2, "__AVR_ATtiny26__" },
172 { "at90s4414", 2, "__AVR_AT90S4414__" },
173 { "at90s4433", 2, "__AVR_AT90S4433__" },
174 { "at90s4434", 2, "__AVR_AT90S4434__" },
175 { "at90s8515", 2, "__AVR_AT90S8515__" },
176 { "at90c8534", 2, "__AVR_AT90C8534__" },
177 { "at90s8535", 2, "__AVR_AT90S8535__" },
178 { "at86rf401", 2, "__AVR_AT86RF401__" },
179 /* Classic + MOVW, <= 8K. */
180 { "attiny13", 2, "__AVR_ATtiny13__" },
181 { "attiny2313", 2, "__AVR_ATtiny2313__" },
182 /* Classic, > 8K. */
183 { "avr3", 3, NULL },
184 { "atmega103", 3, "__AVR_ATmega103__" },
185 { "atmega603", 3, "__AVR_ATmega603__" },
186 { "at43usb320", 3, "__AVR_AT43USB320__" },
187 { "at43usb355", 3, "__AVR_AT43USB355__" },
188 { "at76c711", 3, "__AVR_AT76C711__" },
189 /* Enhanced, <= 8K. */
190 { "avr4", 4, NULL },
191 { "atmega8", 4, "__AVR_ATmega8__" },
192 { "atmega48", 4, "__AVR_ATmega48__" },
193 { "atmega88", 4, "__AVR_ATmega88__" },
194 { "atmega8515", 4, "__AVR_ATmega8515__" },
195 { "atmega8535", 4, "__AVR_ATmega8535__" },
196 /* Enhanced, > 8K. */
197 { "avr5", 5, NULL },
198 { "atmega16", 5, "__AVR_ATmega16__" },
199 { "atmega161", 5, "__AVR_ATmega161__" },
200 { "atmega162", 5, "__AVR_ATmega162__" },
201 { "atmega163", 5, "__AVR_ATmega163__" },
202 { "atmega165", 5, "__AVR_ATmega165__" },
203 { "atmega168", 5, "__AVR_ATmega168__" },
204 { "atmega169", 5, "__AVR_ATmega169__" },
205 { "atmega32", 5, "__AVR_ATmega32__" },
206 { "atmega323", 5, "__AVR_ATmega323__" },
207 { "atmega325", 5, "__AVR_ATmega325__" },
208 { "atmega3250", 5, "__AVR_ATmega3250__" },
209 { "atmega64", 5, "__AVR_ATmega64__" },
210 { "atmega645", 5, "__AVR_ATmega645__" },
211 { "atmega6450", 5, "__AVR_ATmega6450__" },
212 { "atmega128", 5, "__AVR_ATmega128__" },
213 { "at90can128", 5, "__AVR_AT90CAN128__" },
214 { "at94k", 5, "__AVR_AT94K__" },
215 /* Assembler only. */
216 { "avr1", 1, NULL },
217 { "at90s1200", 1, "__AVR_AT90S1200__" },
218 { "attiny11", 1, "__AVR_ATtiny11__" },
219 { "attiny12", 1, "__AVR_ATtiny12__" },
220 { "attiny15", 1, "__AVR_ATtiny15__" },
221 { "attiny28", 1, "__AVR_ATtiny28__" },
222 { NULL, 0, NULL }
225 int avr_case_values_threshold = 30000;
227 /* Initialize the GCC target structure. */
228 #undef TARGET_ASM_ALIGNED_HI_OP
229 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
230 #undef TARGET_ASM_INTEGER
231 #define TARGET_ASM_INTEGER avr_assemble_integer
232 #undef TARGET_ASM_FILE_START
233 #define TARGET_ASM_FILE_START avr_file_start
234 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
235 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
236 #undef TARGET_ASM_FILE_END
237 #define TARGET_ASM_FILE_END avr_file_end
239 #undef TARGET_ASM_FUNCTION_PROLOGUE
240 #define TARGET_ASM_FUNCTION_PROLOGUE avr_output_function_prologue
241 #undef TARGET_ASM_FUNCTION_EPILOGUE
242 #define TARGET_ASM_FUNCTION_EPILOGUE avr_output_function_epilogue
243 #undef TARGET_ATTRIBUTE_TABLE
244 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
245 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
246 #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
247 #undef TARGET_INSERT_ATTRIBUTES
248 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
249 #undef TARGET_SECTION_TYPE_FLAGS
250 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
251 #undef TARGET_RTX_COSTS
252 #define TARGET_RTX_COSTS avr_rtx_costs
253 #undef TARGET_ADDRESS_COST
254 #define TARGET_ADDRESS_COST avr_address_cost
255 #undef TARGET_MACHINE_DEPENDENT_REORG
256 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
258 #undef TARGET_RETURN_IN_MEMORY
259 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
261 #undef TARGET_STRICT_ARGUMENT_NAMING
262 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
264 struct gcc_target targetm = TARGET_INITIALIZER;
266 void
267 avr_override_options (void)
269 const struct mcu_type_s *t;
270 const struct base_arch_s *base;
272 for (t = avr_mcu_types; t->name; t++)
273 if (strcmp (t->name, avr_mcu_name) == 0)
274 break;
276 if (!t->name)
278 fprintf (stderr, "unknown MCU `%s' specified\nKnown MCU names:\n",
279 avr_mcu_name);
280 for (t = avr_mcu_types; t->name; t++)
281 fprintf (stderr," %s\n", t->name);
284 base = &avr_arch_types[t->arch];
285 avr_asm_only_p = base->asm_only;
286 avr_enhanced_p = base->enhanced;
287 avr_mega_p = base->mega;
288 avr_base_arch_macro = base->macro;
289 avr_extra_arch_macro = t->macro;
291 if (optimize && !TARGET_NO_TABLEJUMP)
292 avr_case_values_threshold = (!AVR_MEGA || TARGET_CALL_PROLOGUES) ? 8 : 17;
294 tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO);
295 zero_reg_rtx = gen_rtx_REG (QImode, ZERO_REGNO);
298 /* return register class from register number. */
300 static const int reg_class_tab[]={
301 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
302 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
303 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
304 GENERAL_REGS, /* r0 - r15 */
305 LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
306 LD_REGS, /* r16 - 23 */
307 ADDW_REGS,ADDW_REGS, /* r24,r25 */
308 POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
309 POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
310 POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
311 STACK_REG,STACK_REG /* SPL,SPH */
314 /* Return register class for register R. */
316 enum reg_class
317 avr_regno_reg_class (int r)
319 if (r <= 33)
320 return reg_class_tab[r];
321 return ALL_REGS;
325 /* A C expression which defines the machine-dependent operand
326 constraint letters for register classes. If C is such a
327 letter, the value should be the register class corresponding to
328 it. Otherwise, the value should be `NO_REGS'. The register
329 letter `r', corresponding to class `GENERAL_REGS', will not be
330 passed to this macro; you do not need to handle it. */
332 enum reg_class
333 avr_reg_class_from_letter (int c)
335 switch (c)
337 case 't' : return R0_REG;
338 case 'b' : return BASE_POINTER_REGS;
339 case 'e' : return POINTER_REGS;
340 case 'w' : return ADDW_REGS;
341 case 'd' : return LD_REGS;
342 case 'l' : return NO_LD_REGS;
343 case 'a' : return SIMPLE_LD_REGS;
344 case 'x' : return POINTER_X_REGS;
345 case 'y' : return POINTER_Y_REGS;
346 case 'z' : return POINTER_Z_REGS;
347 case 'q' : return STACK_REG;
348 default: break;
350 return NO_REGS;
353 /* Return nonzero if FUNC is a naked function. */
355 static int
356 avr_naked_function_p (tree func)
358 tree a;
360 if (TREE_CODE (func) != FUNCTION_DECL)
361 abort ();
363 a = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
364 return a != NULL_TREE;
367 /* Return nonzero if FUNC is an interrupt function as specified
368 by the "interrupt" attribute. */
370 static int
371 interrupt_function_p (tree func)
373 tree a;
375 if (TREE_CODE (func) != FUNCTION_DECL)
376 return 0;
378 a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
379 return a != NULL_TREE;
382 /* Return nonzero if FUNC is a signal function as specified
383 by the "signal" attribute. */
385 static int
386 signal_function_p (tree func)
388 tree a;
390 if (TREE_CODE (func) != FUNCTION_DECL)
391 return 0;
393 a = lookup_attribute ("signal", DECL_ATTRIBUTES (func));
394 return a != NULL_TREE;
397 /* Return the number of hard registers to push/pop in the prologue/epilogue
398 of the current function, and optionally store these registers in SET. */
400 static int
401 avr_regs_to_save (HARD_REG_SET *set)
403 int reg, count;
404 int int_or_sig_p = (interrupt_function_p (current_function_decl)
405 || signal_function_p (current_function_decl));
406 int leaf_func_p = leaf_function_p ();
408 if (set)
409 CLEAR_HARD_REG_SET (*set);
410 count = 0;
412 /* No need to save any registers if the function never returns. */
413 if (TREE_THIS_VOLATILE (current_function_decl))
414 return 0;
416 for (reg = 0; reg < 32; reg++)
418 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
419 any global register variables. */
420 if (fixed_regs[reg])
421 continue;
423 if ((int_or_sig_p && !leaf_func_p && call_used_regs[reg])
424 || (regs_ever_live[reg]
425 && (int_or_sig_p || !call_used_regs[reg])
426 && !(frame_pointer_needed
427 && (reg == REG_Y || reg == (REG_Y+1)))))
429 if (set)
430 SET_HARD_REG_BIT (*set, reg);
431 count++;
434 return count;
437 /* Compute offset between arg_pointer and frame_pointer. */
440 initial_elimination_offset (int from, int to)
442 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
443 return 0;
444 else
446 int offset = frame_pointer_needed ? 2 : 0;
448 offset += avr_regs_to_save (NULL);
449 return get_frame_size () + 2 + 1 + offset;
453 /* Return 1 if the function epilogue is just a single "ret". */
456 avr_simple_epilogue (void)
458 return (! frame_pointer_needed
459 && get_frame_size () == 0
460 && avr_regs_to_save (NULL) == 0
461 && ! interrupt_function_p (current_function_decl)
462 && ! signal_function_p (current_function_decl)
463 && ! avr_naked_function_p (current_function_decl)
464 && ! MAIN_NAME_P (DECL_NAME (current_function_decl))
465 && ! TREE_THIS_VOLATILE (current_function_decl));
468 /* This function checks sequence of live registers. */
470 static int
471 sequent_regs_live (void)
473 int reg;
474 int live_seq=0;
475 int cur_seq=0;
477 for (reg = 0; reg < 18; ++reg)
479 if (!call_used_regs[reg])
481 if (regs_ever_live[reg])
483 ++live_seq;
484 ++cur_seq;
486 else
487 cur_seq = 0;
491 if (!frame_pointer_needed)
493 if (regs_ever_live[REG_Y])
495 ++live_seq;
496 ++cur_seq;
498 else
499 cur_seq = 0;
501 if (regs_ever_live[REG_Y+1])
503 ++live_seq;
504 ++cur_seq;
506 else
507 cur_seq = 0;
509 else
511 cur_seq += 2;
512 live_seq += 2;
514 return (cur_seq == live_seq) ? live_seq : 0;
518 /* Output to FILE the asm instructions to adjust the frame pointer by
519 ADJ (r29:r28 -= ADJ;) which can be positive (prologue) or negative
520 (epilogue). Returns the number of instructions generated. */
522 static int
523 out_adj_frame_ptr (FILE *file, int adj)
525 int size = 0;
527 if (adj)
529 if (TARGET_TINY_STACK)
531 if (adj < -63 || adj > 63)
532 warning ("large frame pointer change (%d) with -mtiny-stack", adj);
534 /* The high byte (r29) doesn't change - prefer "subi" (1 cycle)
535 over "sbiw" (2 cycles, same size). */
537 fprintf (file, (AS2 (subi, r28, %d) CR_TAB), adj);
538 size++;
540 else if (adj < -63 || adj > 63)
542 fprintf (file, (AS2 (subi, r28, lo8(%d)) CR_TAB
543 AS2 (sbci, r29, hi8(%d)) CR_TAB),
544 adj, adj);
545 size += 2;
547 else if (adj < 0)
549 fprintf (file, (AS2 (adiw, r28, %d) CR_TAB), -adj);
550 size++;
552 else
554 fprintf (file, (AS2 (sbiw, r28, %d) CR_TAB), adj);
555 size++;
558 return size;
562 /* Output to FILE the asm instructions to copy r29:r28 to SPH:SPL,
563 handling various cases of interrupt enable flag state BEFORE and AFTER
564 (0=disabled, 1=enabled, -1=unknown/unchanged) and target_flags.
565 Returns the number of instructions generated. */
567 static int
568 out_set_stack_ptr (FILE *file, int before, int after)
570 int do_sph, do_cli, do_save, do_sei, lock_sph, size;
572 /* The logic here is so that -mno-interrupts actually means
573 "it is safe to write SPH in one instruction, then SPL in the
574 next instruction, without disabling interrupts first".
575 The after != -1 case (interrupt/signal) is not affected. */
577 do_sph = !TARGET_TINY_STACK;
578 lock_sph = do_sph && !TARGET_NO_INTERRUPTS;
579 do_cli = (before != 0 && (after == 0 || lock_sph));
580 do_save = (do_cli && before == -1 && after == -1);
581 do_sei = ((do_cli || before != 1) && after == 1);
582 size = 1;
584 if (do_save)
586 fprintf (file, AS2 (in, __tmp_reg__, __SREG__) CR_TAB);
587 size++;
590 if (do_cli)
592 fprintf (file, "cli" CR_TAB);
593 size++;
596 /* Do SPH first - maybe this will disable interrupts for one instruction
597 someday (a suggestion has been sent to avr@atmel.com for consideration
598 in future devices - that would make -mno-interrupts always safe). */
599 if (do_sph)
601 fprintf (file, AS2 (out, __SP_H__, r29) CR_TAB);
602 size++;
605 /* Set/restore the I flag now - interrupts will be really enabled only
606 after the next instruction. This is not clearly documented, but
607 believed to be true for all AVR devices. */
608 if (do_save)
610 fprintf (file, AS2 (out, __SREG__, __tmp_reg__) CR_TAB);
611 size++;
613 else if (do_sei)
615 fprintf (file, "sei" CR_TAB);
616 size++;
619 fprintf (file, AS2 (out, __SP_L__, r28) "\n");
621 return size;
625 /* Output function prologue. */
627 static void
628 avr_output_function_prologue (FILE *file, HOST_WIDE_INT size)
630 int reg;
631 int interrupt_func_p;
632 int signal_func_p;
633 int main_p;
634 int live_seq;
635 int minimize;
637 last_insn_address = 0;
638 jump_tables_size = 0;
639 prologue_size = 0;
640 fprintf (file, "/* prologue: frame size=" HOST_WIDE_INT_PRINT_DEC " */\n",
641 size);
643 if (avr_naked_function_p (current_function_decl))
645 fputs ("/* prologue: naked */\n", file);
646 goto out;
649 interrupt_func_p = interrupt_function_p (current_function_decl);
650 signal_func_p = signal_function_p (current_function_decl);
651 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
652 live_seq = sequent_regs_live ();
653 minimize = (TARGET_CALL_PROLOGUES
654 && !interrupt_func_p && !signal_func_p && live_seq);
656 if (interrupt_func_p)
658 fprintf (file,"\tsei\n");
659 ++prologue_size;
661 if (interrupt_func_p || signal_func_p)
663 fprintf (file, "\t"
664 AS1 (push,__zero_reg__) CR_TAB
665 AS1 (push,__tmp_reg__) CR_TAB
666 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
667 AS1 (push,__tmp_reg__) CR_TAB
668 AS1 (clr,__zero_reg__) "\n");
669 prologue_size += 5;
671 if (main_p)
673 fprintf (file, ("\t"
674 AS1 (ldi,r28) ",lo8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
675 AS1 (ldi,r29) ",hi8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
676 AS2 (out,__SP_H__,r29) CR_TAB
677 AS2 (out,__SP_L__,r28) "\n"),
678 avr_init_stack, size, avr_init_stack, size);
680 prologue_size += 4;
682 else if (minimize && (frame_pointer_needed || live_seq > 6))
684 const char *cfun_name = current_function_name ();
685 fprintf (file, ("\t"
686 AS1 (ldi, r26) ",lo8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
687 AS1 (ldi, r27) ",hi8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB), size, size);
689 fprintf (file, (AS2 (ldi, r30, pm_lo8(.L_%s_body)) CR_TAB
690 AS2 (ldi, r31, pm_hi8(.L_%s_body)) CR_TAB),
691 cfun_name, cfun_name);
693 prologue_size += 4;
695 if (AVR_MEGA)
697 fprintf (file, AS1 (jmp,__prologue_saves__+%d) "\n",
698 (18 - live_seq) * 2);
699 prologue_size += 2;
701 else
703 fprintf (file, AS1 (rjmp,__prologue_saves__+%d) "\n",
704 (18 - live_seq) * 2);
705 ++prologue_size;
707 fprintf (file, ".L_%s_body:\n", cfun_name);
709 else
711 HARD_REG_SET set;
713 prologue_size += avr_regs_to_save (&set);
714 for (reg = 0; reg < 32; ++reg)
716 if (TEST_HARD_REG_BIT (set, reg))
718 fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
721 if (frame_pointer_needed)
723 fprintf (file, "\t"
724 AS1 (push,r28) CR_TAB
725 AS1 (push,r29) CR_TAB
726 AS2 (in,r28,__SP_L__) CR_TAB
727 AS2 (in,r29,__SP_H__) "\n");
728 prologue_size += 4;
729 if (size)
731 fputs ("\t", file);
732 prologue_size += out_adj_frame_ptr (file, size);
734 if (interrupt_func_p)
736 prologue_size += out_set_stack_ptr (file, 1, 1);
738 else if (signal_func_p)
740 prologue_size += out_set_stack_ptr (file, 0, 0);
742 else
744 prologue_size += out_set_stack_ptr (file, -1, -1);
750 out:
751 fprintf (file, "/* prologue end (size=%d) */\n", prologue_size);
754 /* Output function epilogue. */
756 static void
757 avr_output_function_epilogue (FILE *file, HOST_WIDE_INT size)
759 int reg;
760 int interrupt_func_p;
761 int signal_func_p;
762 int main_p;
763 int function_size;
764 int live_seq;
765 int minimize;
766 rtx last = get_last_nonnote_insn ();
768 function_size = jump_tables_size;
769 if (last)
771 rtx first = get_first_nonnote_insn ();
772 function_size += (INSN_ADDRESSES (INSN_UID (last)) -
773 INSN_ADDRESSES (INSN_UID (first)));
774 function_size += get_attr_length (last);
777 fprintf (file, "/* epilogue: frame size=" HOST_WIDE_INT_PRINT_DEC " */\n", size);
778 epilogue_size = 0;
780 if (avr_naked_function_p (current_function_decl))
782 fputs ("/* epilogue: naked */\n", file);
783 goto out;
786 if (last && GET_CODE (last) == BARRIER)
788 fputs ("/* epilogue: noreturn */\n", file);
789 goto out;
792 interrupt_func_p = interrupt_function_p (current_function_decl);
793 signal_func_p = signal_function_p (current_function_decl);
794 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
795 live_seq = sequent_regs_live ();
796 minimize = (TARGET_CALL_PROLOGUES
797 && !interrupt_func_p && !signal_func_p && live_seq);
799 if (main_p)
801 /* Return value from main() is already in the correct registers
802 (r25:r24) as the exit() argument. */
803 if (AVR_MEGA)
805 fputs ("\t" AS1 (jmp,exit) "\n", file);
806 epilogue_size += 2;
808 else
810 fputs ("\t" AS1 (rjmp,exit) "\n", file);
811 ++epilogue_size;
814 else if (minimize && (frame_pointer_needed || live_seq > 4))
816 fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
817 ++epilogue_size;
818 if (frame_pointer_needed)
820 epilogue_size += out_adj_frame_ptr (file, -size);
822 else
824 fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
825 AS2 (in , r29, __SP_H__) CR_TAB));
826 epilogue_size += 2;
829 if (AVR_MEGA)
831 fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
832 (18 - live_seq) * 2);
833 epilogue_size += 2;
835 else
837 fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
838 (18 - live_seq) * 2);
839 ++epilogue_size;
842 else
844 HARD_REG_SET set;
846 if (frame_pointer_needed)
848 if (size)
850 fputs ("\t", file);
851 epilogue_size += out_adj_frame_ptr (file, -size);
853 if (interrupt_func_p || signal_func_p)
855 epilogue_size += out_set_stack_ptr (file, -1, 0);
857 else
859 epilogue_size += out_set_stack_ptr (file, -1, -1);
862 fprintf (file, "\t"
863 AS1 (pop,r29) CR_TAB
864 AS1 (pop,r28) "\n");
865 epilogue_size += 2;
868 epilogue_size += avr_regs_to_save (&set);
869 for (reg = 31; reg >= 0; --reg)
871 if (TEST_HARD_REG_BIT (set, reg))
873 fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
877 if (interrupt_func_p || signal_func_p)
879 fprintf (file, "\t"
880 AS1 (pop,__tmp_reg__) CR_TAB
881 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
882 AS1 (pop,__tmp_reg__) CR_TAB
883 AS1 (pop,__zero_reg__) "\n");
884 epilogue_size += 4;
885 fprintf (file, "\treti\n");
887 else
888 fprintf (file, "\tret\n");
889 ++epilogue_size;
892 out:
893 fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
894 fprintf (file, "/* function %s size %d (%d) */\n", current_function_name (),
895 prologue_size + function_size + epilogue_size, function_size);
896 commands_in_file += prologue_size + function_size + epilogue_size;
897 commands_in_prologues += prologue_size;
898 commands_in_epilogues += epilogue_size;
902 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
903 machine for a memory operand of mode MODE. */
906 legitimate_address_p (enum machine_mode mode, rtx x, int strict)
908 enum reg_class r = NO_REGS;
910 if (TARGET_ALL_DEBUG)
912 fprintf (stderr, "mode: (%s) %s %s %s %s:",
913 GET_MODE_NAME(mode),
914 strict ? "(strict)": "",
915 reload_completed ? "(reload_completed)": "",
916 reload_in_progress ? "(reload_in_progress)": "",
917 reg_renumber ? "(reg_renumber)" : "");
918 if (GET_CODE (x) == PLUS
919 && REG_P (XEXP (x, 0))
920 && GET_CODE (XEXP (x, 1)) == CONST_INT
921 && INTVAL (XEXP (x, 1)) >= 0
922 && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
923 && reg_renumber
925 fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
926 true_regnum (XEXP (x, 0)));
927 debug_rtx (x);
929 if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
930 : REG_OK_FOR_BASE_NOSTRICT_P (x)))
931 r = POINTER_REGS;
932 else if (CONSTANT_ADDRESS_P (x))
933 r = ALL_REGS;
934 else if (GET_CODE (x) == PLUS
935 && REG_P (XEXP (x, 0))
936 && GET_CODE (XEXP (x, 1)) == CONST_INT
937 && INTVAL (XEXP (x, 1)) >= 0)
939 int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
940 if (fit)
942 if (! strict
943 || REGNO (XEXP (x,0)) == REG_Y
944 || REGNO (XEXP (x,0)) == REG_Z)
945 r = BASE_POINTER_REGS;
946 if (XEXP (x,0) == frame_pointer_rtx
947 || XEXP (x,0) == arg_pointer_rtx)
948 r = BASE_POINTER_REGS;
950 else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
951 r = POINTER_Y_REGS;
953 else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
954 && REG_P (XEXP (x, 0))
955 && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
956 : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
958 r = POINTER_REGS;
960 if (TARGET_ALL_DEBUG)
962 fprintf (stderr, " ret = %c\n", r);
964 return r == NO_REGS ? 0 : (int)r;
967 /* Attempts to replace X with a valid
968 memory address for an operand of mode MODE */
971 legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
973 x = oldx;
974 if (TARGET_ALL_DEBUG)
976 fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
977 debug_rtx (oldx);
980 if (GET_CODE (oldx) == PLUS
981 && REG_P (XEXP (oldx,0)))
983 if (REG_P (XEXP (oldx,1)))
984 x = force_reg (GET_MODE (oldx), oldx);
985 else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
987 int offs = INTVAL (XEXP (oldx,1));
988 if (frame_pointer_rtx != XEXP (oldx,0))
989 if (offs > MAX_LD_OFFSET (mode))
991 if (TARGET_ALL_DEBUG)
992 fprintf (stderr, "force_reg (big offset)\n");
993 x = force_reg (GET_MODE (oldx), oldx);
997 return x;
1001 /* Return a pointer register name as a string. */
1003 static const char *
1004 ptrreg_to_str (int regno)
1006 switch (regno)
1008 case REG_X: return "X";
1009 case REG_Y: return "Y";
1010 case REG_Z: return "Z";
1011 default:
1012 abort ();
1014 return NULL;
1017 /* Return the condition name as a string.
1018 Used in conditional jump constructing */
1020 static const char *
1021 cond_string (enum rtx_code code)
1023 switch (code)
1025 case NE:
1026 return "ne";
1027 case EQ:
1028 return "eq";
1029 case GE:
1030 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1031 return "pl";
1032 else
1033 return "ge";
1034 case LT:
1035 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1036 return "mi";
1037 else
1038 return "lt";
1039 case GEU:
1040 return "sh";
1041 case LTU:
1042 return "lo";
1043 default:
1044 abort ();
1048 /* Output ADDR to FILE as address. */
1050 void
1051 print_operand_address (FILE *file, rtx addr)
1053 switch (GET_CODE (addr))
1055 case REG:
1056 fprintf (file, ptrreg_to_str (REGNO (addr)));
1057 break;
1059 case PRE_DEC:
1060 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1061 break;
1063 case POST_INC:
1064 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1065 break;
1067 default:
1068 if (CONSTANT_ADDRESS_P (addr)
1069 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (addr))
1070 || GET_CODE (addr) == LABEL_REF))
1072 fprintf (file, "pm(");
1073 output_addr_const (file,addr);
1074 fprintf (file ,")");
1076 else
1077 output_addr_const (file, addr);
1082 /* Output X as assembler operand to file FILE. */
1084 void
1085 print_operand (FILE *file, rtx x, int code)
1087 int abcd = 0;
1089 if (code >= 'A' && code <= 'D')
1090 abcd = code - 'A';
1092 if (code == '~')
1094 if (!AVR_MEGA)
1095 fputc ('r', file);
1097 else if (REG_P (x))
1099 if (x == zero_reg_rtx)
1100 fprintf (file, "__zero_reg__");
1101 else
1102 fprintf (file, reg_names[true_regnum (x) + abcd]);
1104 else if (GET_CODE (x) == CONST_INT)
1105 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd);
1106 else if (GET_CODE (x) == MEM)
1108 rtx addr = XEXP (x,0);
1110 if (CONSTANT_P (addr) && abcd)
1112 fputc ('(', file);
1113 output_address (addr);
1114 fprintf (file, ")+%d", abcd);
1116 else if (code == 'o')
1118 if (GET_CODE (addr) != PLUS)
1119 fatal_insn ("bad address, not (reg+disp):", addr);
1121 print_operand (file, XEXP (addr, 1), 0);
1123 else if (GET_CODE (addr) == PLUS)
1125 print_operand_address (file, XEXP (addr,0));
1126 if (REGNO (XEXP (addr, 0)) == REG_X)
1127 fatal_insn ("internal compiler error. Bad address:"
1128 ,addr);
1129 fputc ('+', file);
1130 print_operand (file, XEXP (addr,1), code);
1132 else
1133 print_operand_address (file, addr);
1135 else if (GET_CODE (x) == CONST_DOUBLE)
1137 long val;
1138 REAL_VALUE_TYPE rv;
1139 if (GET_MODE (x) != SFmode)
1140 fatal_insn ("internal compiler error. Unknown mode:", x);
1141 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1142 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1143 fprintf (file, "0x%lx", val);
1145 else if (code == 'j')
1146 fputs (cond_string (GET_CODE (x)), file);
1147 else if (code == 'k')
1148 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
1149 else
1150 print_operand_address (file, x);
1153 /* Recognize operand OP of mode MODE used in call instructions. */
1156 call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1158 if (GET_CODE (op) == MEM)
1160 rtx inside = XEXP (op, 0);
1161 if (register_operand (inside, Pmode))
1162 return 1;
1163 if (CONSTANT_ADDRESS_P (inside))
1164 return 1;
1166 return 0;
1169 /* Update the condition code in the INSN. */
1171 void
1172 notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
1174 rtx set;
1176 switch (get_attr_cc (insn))
1178 case CC_NONE:
1179 /* Insn does not affect CC at all. */
1180 break;
1182 case CC_SET_N:
1183 CC_STATUS_INIT;
1184 break;
1186 case CC_SET_ZN:
1187 set = single_set (insn);
1188 CC_STATUS_INIT;
1189 if (set)
1191 cc_status.flags |= CC_NO_OVERFLOW;
1192 cc_status.value1 = SET_DEST (set);
1194 break;
1196 case CC_SET_CZN:
1197 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1198 The V flag may or may not be known but that's ok because
1199 alter_cond will change tests to use EQ/NE. */
1200 set = single_set (insn);
1201 CC_STATUS_INIT;
1202 if (set)
1204 cc_status.value1 = SET_DEST (set);
1205 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1207 break;
1209 case CC_COMPARE:
1210 set = single_set (insn);
1211 CC_STATUS_INIT;
1212 if (set)
1213 cc_status.value1 = SET_SRC (set);
1214 break;
1216 case CC_CLOBBER:
1217 /* Insn doesn't leave CC in a usable state. */
1218 CC_STATUS_INIT;
1220 /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1221 set = single_set (insn);
1222 if (set)
1224 rtx src = SET_SRC (set);
1226 if (GET_CODE (src) == ASHIFTRT
1227 && GET_MODE (src) == QImode)
1229 rtx x = XEXP (src, 1);
1231 if (GET_CODE (x) == CONST_INT
1232 && INTVAL (x) > 0
1233 && INTVAL (x) != 6)
1235 cc_status.value1 = SET_DEST (set);
1236 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1240 break;
1244 /* Return maximum number of consecutive registers of
1245 class CLASS needed to hold a value of mode MODE. */
1248 class_max_nregs (enum reg_class class ATTRIBUTE_UNUSED,enum machine_mode mode)
1250 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1253 /* Choose mode for jump insn:
1254 1 - relative jump in range -63 <= x <= 62 ;
1255 2 - relative jump in range -2046 <= x <= 2045 ;
1256 3 - absolute jump (only for ATmega[16]03). */
1259 avr_jump_mode (rtx x, rtx insn)
1261 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1262 ? XEXP (x, 0) : x));
1263 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1264 int jump_distance = cur_addr - dest_addr;
1266 if (-63 <= jump_distance && jump_distance <= 62)
1267 return 1;
1268 else if (-2046 <= jump_distance && jump_distance <= 2045)
1269 return 2;
1270 else if (AVR_MEGA)
1271 return 3;
1273 return 2;
1276 /* return an AVR condition jump commands.
1277 X is a comparison RTX.
1278 LEN is a number returned by avr_jump_mode function.
1279 if REVERSE nonzero then condition code in X must be reversed. */
1281 const char *
1282 ret_cond_branch (rtx x, int len, int reverse)
1284 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1286 switch (cond)
1288 case GT:
1289 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1290 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1291 AS1 (brpl,%0)) :
1292 len == 2 ? (AS1 (breq,.+4) CR_TAB
1293 AS1 (brmi,.+2) CR_TAB
1294 AS1 (rjmp,%0)) :
1295 (AS1 (breq,.+6) CR_TAB
1296 AS1 (brmi,.+4) CR_TAB
1297 AS1 (jmp,%0)));
1299 else
1300 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1301 AS1 (brge,%0)) :
1302 len == 2 ? (AS1 (breq,.+4) CR_TAB
1303 AS1 (brlt,.+2) CR_TAB
1304 AS1 (rjmp,%0)) :
1305 (AS1 (breq,.+6) CR_TAB
1306 AS1 (brlt,.+4) CR_TAB
1307 AS1 (jmp,%0)));
1308 case GTU:
1309 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1310 AS1 (brsh,%0)) :
1311 len == 2 ? (AS1 (breq,.+4) CR_TAB
1312 AS1 (brlo,.+2) CR_TAB
1313 AS1 (rjmp,%0)) :
1314 (AS1 (breq,.+6) CR_TAB
1315 AS1 (brlo,.+4) CR_TAB
1316 AS1 (jmp,%0)));
1317 case LE:
1318 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1319 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1320 AS1 (brmi,%0)) :
1321 len == 2 ? (AS1 (breq,.+2) CR_TAB
1322 AS1 (brpl,.+2) CR_TAB
1323 AS1 (rjmp,%0)) :
1324 (AS1 (breq,.+2) CR_TAB
1325 AS1 (brpl,.+4) CR_TAB
1326 AS1 (jmp,%0)));
1327 else
1328 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1329 AS1 (brlt,%0)) :
1330 len == 2 ? (AS1 (breq,.+2) CR_TAB
1331 AS1 (brge,.+2) CR_TAB
1332 AS1 (rjmp,%0)) :
1333 (AS1 (breq,.+2) CR_TAB
1334 AS1 (brge,.+4) CR_TAB
1335 AS1 (jmp,%0)));
1336 case LEU:
1337 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1338 AS1 (brlo,%0)) :
1339 len == 2 ? (AS1 (breq,.+2) CR_TAB
1340 AS1 (brsh,.+2) CR_TAB
1341 AS1 (rjmp,%0)) :
1342 (AS1 (breq,.+2) CR_TAB
1343 AS1 (brsh,.+4) CR_TAB
1344 AS1 (jmp,%0)));
1345 default:
1346 if (reverse)
1348 switch (len)
1350 case 1:
1351 return AS1 (br%k1,%0);
1352 case 2:
1353 return (AS1 (br%j1,.+2) CR_TAB
1354 AS1 (rjmp,%0));
1355 default:
1356 return (AS1 (br%j1,.+4) CR_TAB
1357 AS1 (jmp,%0));
1360 else
1362 switch (len)
1364 case 1:
1365 return AS1 (br%j1,%0);
1366 case 2:
1367 return (AS1 (br%k1,.+2) CR_TAB
1368 AS1 (rjmp,%0));
1369 default:
1370 return (AS1 (br%k1,.+4) CR_TAB
1371 AS1 (jmp,%0));
1375 return "";
1378 /* Predicate function for immediate operand which fits to byte (8bit) */
1381 byte_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1383 return (GET_CODE (op) == CONST_INT
1384 && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1387 /* Output all insn addresses and their sizes into the assembly language
1388 output file. This is helpful for debugging whether the length attributes
1389 in the md file are correct.
1390 Output insn cost for next insn. */
1392 void
1393 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
1394 int num_operands ATTRIBUTE_UNUSED)
1396 int uid = INSN_UID (insn);
1398 if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1400 fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1401 INSN_ADDRESSES (uid),
1402 INSN_ADDRESSES (uid) - last_insn_address,
1403 rtx_cost (PATTERN (insn), INSN));
1405 last_insn_address = INSN_ADDRESSES (uid);
1408 /* Return 0 if undefined, 1 if always true or always false. */
1411 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE operator, rtx x)
1413 unsigned int max = (mode == QImode ? 0xff :
1414 mode == HImode ? 0xffff :
1415 mode == SImode ? 0xffffffff : 0);
1416 if (max && operator && GET_CODE (x) == CONST_INT)
1418 if (unsigned_condition (operator) != operator)
1419 max >>= 1;
1421 if (max != (INTVAL (x) & max)
1422 && INTVAL (x) != 0xff)
1423 return 1;
1425 return 0;
1429 /* Returns nonzero if REGNO is the number of a hard
1430 register in which function arguments are sometimes passed. */
1433 function_arg_regno_p(int r)
1435 return (r >= 8 && r <= 25);
1438 /* Initializing the variable cum for the state at the beginning
1439 of the argument list. */
1441 void
1442 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
1443 tree fndecl ATTRIBUTE_UNUSED)
1445 cum->nregs = 18;
1446 cum->regno = FIRST_CUM_REG;
1447 if (!libname && fntype)
1449 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1450 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1451 != void_type_node));
1452 if (stdarg)
1453 cum->nregs = 0;
1457 /* Returns the number of registers to allocate for a function argument. */
1459 static int
1460 avr_num_arg_regs (enum machine_mode mode, tree type)
1462 int size;
1464 if (mode == BLKmode)
1465 size = int_size_in_bytes (type);
1466 else
1467 size = GET_MODE_SIZE (mode);
1469 /* Align all function arguments to start in even-numbered registers.
1470 Odd-sized arguments leave holes above them. */
1472 return (size + 1) & ~1;
1475 /* Controls whether a function argument is passed
1476 in a register, and which register. */
1479 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1480 int named ATTRIBUTE_UNUSED)
1482 int bytes = avr_num_arg_regs (mode, type);
1484 if (cum->nregs && bytes <= cum->nregs)
1485 return gen_rtx_REG (mode, cum->regno - bytes);
1487 return NULL_RTX;
1490 /* Update the summarizer variable CUM to advance past an argument
1491 in the argument list. */
1493 void
1494 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1495 int named ATTRIBUTE_UNUSED)
1497 int bytes = avr_num_arg_regs (mode, type);
1499 cum->nregs -= bytes;
1500 cum->regno -= bytes;
1502 if (cum->nregs <= 0)
1504 cum->nregs = 0;
1505 cum->regno = FIRST_CUM_REG;
1509 /***********************************************************************
1510 Functions for outputting various mov's for a various modes
1511 ************************************************************************/
1512 const char *
1513 output_movqi (rtx insn, rtx operands[], int *l)
1515 int dummy;
1516 rtx dest = operands[0];
1517 rtx src = operands[1];
1518 int *real_l = l;
1520 if (!l)
1521 l = &dummy;
1523 *l = 1;
1525 if (register_operand (dest, QImode))
1527 if (register_operand (src, QImode)) /* mov r,r */
1529 if (test_hard_reg_class (STACK_REG, dest))
1530 return AS2 (out,%0,%1);
1531 else if (test_hard_reg_class (STACK_REG, src))
1532 return AS2 (in,%0,%1);
1534 return AS2 (mov,%0,%1);
1536 else if (CONSTANT_P (src))
1538 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1539 return AS2 (ldi,%0,lo8(%1));
1541 if (GET_CODE (src) == CONST_INT)
1543 if (src == const0_rtx) /* mov r,L */
1544 return AS1 (clr,%0);
1545 else if (src == const1_rtx)
1547 *l = 2;
1548 return (AS1 (clr,%0) CR_TAB
1549 AS1 (inc,%0));
1551 else if (src == constm1_rtx)
1553 /* Immediate constants -1 to any register */
1554 *l = 2;
1555 return (AS1 (clr,%0) CR_TAB
1556 AS1 (dec,%0));
1558 else
1560 int bit_nr = exact_log2 (INTVAL (src));
1562 if (bit_nr >= 0)
1564 *l = 3;
1565 if (!real_l)
1566 output_asm_insn ((AS1 (clr,%0) CR_TAB
1567 "set"), operands);
1568 if (!real_l)
1569 avr_output_bld (operands, bit_nr);
1571 return "";
1576 /* Last resort, larger than loading from memory. */
1577 *l = 4;
1578 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1579 AS2 (ldi,r31,lo8(%1)) CR_TAB
1580 AS2 (mov,%0,r31) CR_TAB
1581 AS2 (mov,r31,__tmp_reg__));
1583 else if (GET_CODE (src) == MEM)
1584 return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1586 else if (GET_CODE (dest) == MEM)
1588 const char *template;
1590 if (src == const0_rtx)
1591 operands[1] = zero_reg_rtx;
1593 template = out_movqi_mr_r (insn, operands, real_l);
1595 if (!real_l)
1596 output_asm_insn (template, operands);
1598 operands[1] = src;
1600 return "";
1604 const char *
1605 output_movhi (rtx insn, rtx operands[], int *l)
1607 int dummy;
1608 rtx dest = operands[0];
1609 rtx src = operands[1];
1610 int *real_l = l;
1612 if (!l)
1613 l = &dummy;
1615 if (register_operand (dest, HImode))
1617 if (register_operand (src, HImode)) /* mov r,r */
1619 if (test_hard_reg_class (STACK_REG, dest))
1621 if (TARGET_TINY_STACK)
1623 *l = 1;
1624 return AS2 (out,__SP_L__,%A1);
1626 else if (TARGET_NO_INTERRUPTS)
1628 *l = 2;
1629 return (AS2 (out,__SP_H__,%B1) CR_TAB
1630 AS2 (out,__SP_L__,%A1));
1633 *l = 5;
1634 return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB
1635 "cli" CR_TAB
1636 AS2 (out,__SP_H__,%B1) CR_TAB
1637 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1638 AS2 (out,__SP_L__,%A1));
1640 else if (test_hard_reg_class (STACK_REG, src))
1642 *l = 2;
1643 return (AS2 (in,%A0,__SP_L__) CR_TAB
1644 AS2 (in,%B0,__SP_H__));
1647 if (AVR_ENHANCED)
1649 *l = 1;
1650 return (AS2 (movw,%0,%1));
1653 if (true_regnum (dest) > true_regnum (src))
1655 *l = 2;
1656 return (AS2 (mov,%B0,%B1) CR_TAB
1657 AS2 (mov,%A0,%A1));
1659 else
1661 *l = 2;
1662 return (AS2 (mov,%A0,%A1) CR_TAB
1663 AS2 (mov,%B0,%B1));
1666 else if (CONSTANT_P (src))
1668 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1670 *l = 2;
1671 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1672 AS2 (ldi,%B0,hi8(%1)));
1675 if (GET_CODE (src) == CONST_INT)
1677 if (src == const0_rtx) /* mov r,L */
1679 *l = 2;
1680 return (AS1 (clr,%A0) CR_TAB
1681 AS1 (clr,%B0));
1683 else if (src == const1_rtx)
1685 *l = 3;
1686 return (AS1 (clr,%A0) CR_TAB
1687 AS1 (clr,%B0) CR_TAB
1688 AS1 (inc,%A0));
1690 else if (src == constm1_rtx)
1692 /* Immediate constants -1 to any register */
1693 *l = 3;
1694 return (AS1 (clr,%0) CR_TAB
1695 AS1 (dec,%A0) CR_TAB
1696 AS2 (mov,%B0,%A0));
1698 else
1700 int bit_nr = exact_log2 (INTVAL (src));
1702 if (bit_nr >= 0)
1704 *l = 4;
1705 if (!real_l)
1706 output_asm_insn ((AS1 (clr,%A0) CR_TAB
1707 AS1 (clr,%B0) CR_TAB
1708 "set"), operands);
1709 if (!real_l)
1710 avr_output_bld (operands, bit_nr);
1712 return "";
1716 if ((INTVAL (src) & 0xff) == 0)
1718 *l = 5;
1719 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1720 AS1 (clr,%A0) CR_TAB
1721 AS2 (ldi,r31,hi8(%1)) CR_TAB
1722 AS2 (mov,%B0,r31) CR_TAB
1723 AS2 (mov,r31,__tmp_reg__));
1725 else if ((INTVAL (src) & 0xff00) == 0)
1727 *l = 5;
1728 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1729 AS2 (ldi,r31,lo8(%1)) CR_TAB
1730 AS2 (mov,%A0,r31) CR_TAB
1731 AS1 (clr,%B0) CR_TAB
1732 AS2 (mov,r31,__tmp_reg__));
1736 /* Last resort, equal to loading from memory. */
1737 *l = 6;
1738 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1739 AS2 (ldi,r31,lo8(%1)) CR_TAB
1740 AS2 (mov,%A0,r31) CR_TAB
1741 AS2 (ldi,r31,hi8(%1)) CR_TAB
1742 AS2 (mov,%B0,r31) CR_TAB
1743 AS2 (mov,r31,__tmp_reg__));
1745 else if (GET_CODE (src) == MEM)
1746 return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1748 else if (GET_CODE (dest) == MEM)
1750 const char *template;
1752 if (src == const0_rtx)
1753 operands[1] = zero_reg_rtx;
1755 template = out_movhi_mr_r (insn, operands, real_l);
1757 if (!real_l)
1758 output_asm_insn (template, operands);
1760 operands[1] = src;
1761 return "";
1763 fatal_insn ("invalid insn:", insn);
1764 return "";
1767 const char *
1768 out_movqi_r_mr (rtx insn, rtx op[], int *l)
1770 rtx dest = op[0];
1771 rtx src = op[1];
1772 rtx x = XEXP (src, 0);
1773 int dummy;
1775 if (!l)
1776 l = &dummy;
1778 if (CONSTANT_ADDRESS_P (x))
1780 if (avr_io_address_p (x, 1))
1782 *l = 1;
1783 return AS2 (in,%0,%1-0x20);
1785 *l = 2;
1786 return AS2 (lds,%0,%1);
1788 /* memory access by reg+disp */
1789 else if (GET_CODE (x) == PLUS
1790 && REG_P (XEXP (x,0))
1791 && GET_CODE (XEXP (x,1)) == CONST_INT)
1793 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1795 int disp = INTVAL (XEXP (x,1));
1796 if (REGNO (XEXP (x,0)) != REG_Y)
1797 fatal_insn ("incorrect insn:",insn);
1799 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1800 return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
1801 AS2 (ldd,%0,Y+63) CR_TAB
1802 AS2 (sbiw,r28,%o1-63));
1804 return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1805 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1806 AS2 (ld,%0,Y) CR_TAB
1807 AS2 (subi,r28,lo8(%o1)) CR_TAB
1808 AS2 (sbci,r29,hi8(%o1)));
1810 else if (REGNO (XEXP (x,0)) == REG_X)
1812 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1813 it but I have this situation with extremal optimizing options. */
1814 if (reg_overlap_mentioned_p (dest, XEXP (x,0))
1815 || reg_unused_after (insn, XEXP (x,0)))
1816 return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
1817 AS2 (ld,%0,X));
1819 return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
1820 AS2 (ld,%0,X) CR_TAB
1821 AS2 (sbiw,r26,%o1));
1823 *l = 1;
1824 return AS2 (ldd,%0,%1);
1826 *l = 1;
1827 return AS2 (ld,%0,%1);
1830 const char *
1831 out_movhi_r_mr (rtx insn, rtx op[], int *l)
1833 rtx dest = op[0];
1834 rtx src = op[1];
1835 rtx base = XEXP (src, 0);
1836 int reg_dest = true_regnum (dest);
1837 int reg_base = true_regnum (base);
1838 int tmp;
1840 if (!l)
1841 l = &tmp;
1843 if (reg_base > 0)
1845 if (reg_dest == reg_base) /* R = (R) */
1847 *l = 3;
1848 return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1849 AS2 (ld,%B0,%1) CR_TAB
1850 AS2 (mov,%A0,__tmp_reg__));
1852 else if (reg_base == REG_X) /* (R26) */
1854 if (reg_unused_after (insn, base))
1856 *l = 2;
1857 return (AS2 (ld,%A0,X+) CR_TAB
1858 AS2 (ld,%B0,X));
1860 *l = 3;
1861 return (AS2 (ld,%A0,X+) CR_TAB
1862 AS2 (ld,%B0,X) CR_TAB
1863 AS2 (sbiw,r26,1));
1865 else /* (R) */
1867 *l = 2;
1868 return (AS2 (ld,%A0,%1) CR_TAB
1869 AS2 (ldd,%B0,%1+1));
1872 else if (GET_CODE (base) == PLUS) /* (R + i) */
1874 int disp = INTVAL (XEXP (base, 1));
1875 int reg_base = true_regnum (XEXP (base, 0));
1877 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
1879 if (REGNO (XEXP (base, 0)) != REG_Y)
1880 fatal_insn ("incorrect insn:",insn);
1882 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1883 return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
1884 AS2 (ldd,%A0,Y+62) CR_TAB
1885 AS2 (ldd,%B0,Y+63) CR_TAB
1886 AS2 (sbiw,r28,%o1-62));
1888 return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1889 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1890 AS2 (ld,%A0,Y) CR_TAB
1891 AS2 (ldd,%B0,Y+1) CR_TAB
1892 AS2 (subi,r28,lo8(%o1)) CR_TAB
1893 AS2 (sbci,r29,hi8(%o1)));
1895 if (reg_base == REG_X)
1897 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1898 it but I have this situation with extremal
1899 optimization options. */
1901 *l = 4;
1902 if (reg_base == reg_dest)
1903 return (AS2 (adiw,r26,%o1) CR_TAB
1904 AS2 (ld,__tmp_reg__,X+) CR_TAB
1905 AS2 (ld,%B0,X) CR_TAB
1906 AS2 (mov,%A0,__tmp_reg__));
1908 return (AS2 (adiw,r26,%o1) CR_TAB
1909 AS2 (ld,%A0,X+) CR_TAB
1910 AS2 (ld,%B0,X) CR_TAB
1911 AS2 (sbiw,r26,%o1+1));
1914 if (reg_base == reg_dest)
1916 *l = 3;
1917 return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
1918 AS2 (ldd,%B0,%B1) CR_TAB
1919 AS2 (mov,%A0,__tmp_reg__));
1922 *l = 2;
1923 return (AS2 (ldd,%A0,%A1) CR_TAB
1924 AS2 (ldd,%B0,%B1));
1926 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
1928 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1929 fatal_insn ("incorrect insn:", insn);
1931 *l = 2;
1932 return (AS2 (ld,%B0,%1) CR_TAB
1933 AS2 (ld,%A0,%1));
1935 else if (GET_CODE (base) == POST_INC) /* (R++) */
1937 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1938 fatal_insn ("incorrect insn:", insn);
1940 *l = 2;
1941 return (AS2 (ld,%A0,%1) CR_TAB
1942 AS2 (ld,%B0,%1));
1944 else if (CONSTANT_ADDRESS_P (base))
1946 if (avr_io_address_p (base, 2))
1948 *l = 2;
1949 return (AS2 (in,%A0,%A1-0x20) CR_TAB
1950 AS2 (in,%B0,%B1-0x20));
1952 *l = 4;
1953 return (AS2 (lds,%A0,%A1) CR_TAB
1954 AS2 (lds,%B0,%B1));
1957 fatal_insn ("unknown move insn:",insn);
1958 return "";
1961 const char *
1962 out_movsi_r_mr (rtx insn, rtx op[], int *l)
1964 rtx dest = op[0];
1965 rtx src = op[1];
1966 rtx base = XEXP (src, 0);
1967 int reg_dest = true_regnum (dest);
1968 int reg_base = true_regnum (base);
1969 int tmp;
1971 if (!l)
1972 l = &tmp;
1974 if (reg_base > 0)
1976 if (reg_base == REG_X) /* (R26) */
1978 if (reg_dest == REG_X)
1979 /* "ld r26,-X" is undefined */
1980 return *l=7, (AS2 (adiw,r26,3) CR_TAB
1981 AS2 (ld,r29,X) CR_TAB
1982 AS2 (ld,r28,-X) CR_TAB
1983 AS2 (ld,__tmp_reg__,-X) CR_TAB
1984 AS2 (sbiw,r26,1) CR_TAB
1985 AS2 (ld,r26,X) CR_TAB
1986 AS2 (mov,r27,__tmp_reg__));
1987 else if (reg_dest == REG_X - 2)
1988 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
1989 AS2 (ld,%B0,X+) CR_TAB
1990 AS2 (ld,__tmp_reg__,X+) CR_TAB
1991 AS2 (ld,%D0,X) CR_TAB
1992 AS2 (mov,%C0,__tmp_reg__));
1993 else if (reg_unused_after (insn, base))
1994 return *l=4, (AS2 (ld,%A0,X+) CR_TAB
1995 AS2 (ld,%B0,X+) CR_TAB
1996 AS2 (ld,%C0,X+) CR_TAB
1997 AS2 (ld,%D0,X));
1998 else
1999 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2000 AS2 (ld,%B0,X+) CR_TAB
2001 AS2 (ld,%C0,X+) CR_TAB
2002 AS2 (ld,%D0,X) CR_TAB
2003 AS2 (sbiw,r26,3));
2005 else
2007 if (reg_dest == reg_base)
2008 return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
2009 AS2 (ldd,%C0,%1+2) CR_TAB
2010 AS2 (ldd,__tmp_reg__,%1+1) CR_TAB
2011 AS2 (ld,%A0,%1) CR_TAB
2012 AS2 (mov,%B0,__tmp_reg__));
2013 else if (reg_base == reg_dest + 2)
2014 return *l=5, (AS2 (ld ,%A0,%1) CR_TAB
2015 AS2 (ldd,%B0,%1+1) CR_TAB
2016 AS2 (ldd,__tmp_reg__,%1+2) CR_TAB
2017 AS2 (ldd,%D0,%1+3) CR_TAB
2018 AS2 (mov,%C0,__tmp_reg__));
2019 else
2020 return *l=4, (AS2 (ld ,%A0,%1) CR_TAB
2021 AS2 (ldd,%B0,%1+1) CR_TAB
2022 AS2 (ldd,%C0,%1+2) CR_TAB
2023 AS2 (ldd,%D0,%1+3));
2026 else if (GET_CODE (base) == PLUS) /* (R + i) */
2028 int disp = INTVAL (XEXP (base, 1));
2030 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2032 if (REGNO (XEXP (base, 0)) != REG_Y)
2033 fatal_insn ("incorrect insn:",insn);
2035 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2036 return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2037 AS2 (ldd,%A0,Y+60) CR_TAB
2038 AS2 (ldd,%B0,Y+61) CR_TAB
2039 AS2 (ldd,%C0,Y+62) CR_TAB
2040 AS2 (ldd,%D0,Y+63) CR_TAB
2041 AS2 (sbiw,r28,%o1-60));
2043 return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2044 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2045 AS2 (ld,%A0,Y) CR_TAB
2046 AS2 (ldd,%B0,Y+1) CR_TAB
2047 AS2 (ldd,%C0,Y+2) CR_TAB
2048 AS2 (ldd,%D0,Y+3) CR_TAB
2049 AS2 (subi,r28,lo8(%o1)) CR_TAB
2050 AS2 (sbci,r29,hi8(%o1)));
2053 reg_base = true_regnum (XEXP (base, 0));
2054 if (reg_base == REG_X)
2056 /* R = (X + d) */
2057 if (reg_dest == REG_X)
2059 *l = 7;
2060 /* "ld r26,-X" is undefined */
2061 return (AS2 (adiw,r26,%o1+3) CR_TAB
2062 AS2 (ld,r29,X) CR_TAB
2063 AS2 (ld,r28,-X) CR_TAB
2064 AS2 (ld,__tmp_reg__,-X) CR_TAB
2065 AS2 (sbiw,r26,1) CR_TAB
2066 AS2 (ld,r26,X) CR_TAB
2067 AS2 (mov,r27,__tmp_reg__));
2069 *l = 6;
2070 if (reg_dest == REG_X - 2)
2071 return (AS2 (adiw,r26,%o1) CR_TAB
2072 AS2 (ld,r24,X+) CR_TAB
2073 AS2 (ld,r25,X+) CR_TAB
2074 AS2 (ld,__tmp_reg__,X+) CR_TAB
2075 AS2 (ld,r27,X) CR_TAB
2076 AS2 (mov,r26,__tmp_reg__));
2078 return (AS2 (adiw,r26,%o1) CR_TAB
2079 AS2 (ld,%A0,X+) CR_TAB
2080 AS2 (ld,%B0,X+) CR_TAB
2081 AS2 (ld,%C0,X+) CR_TAB
2082 AS2 (ld,%D0,X) CR_TAB
2083 AS2 (sbiw,r26,%o1+3));
2085 if (reg_dest == reg_base)
2086 return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2087 AS2 (ldd,%C0,%C1) CR_TAB
2088 AS2 (ldd,__tmp_reg__,%B1) CR_TAB
2089 AS2 (ldd,%A0,%A1) CR_TAB
2090 AS2 (mov,%B0,__tmp_reg__));
2091 else if (reg_dest == reg_base - 2)
2092 return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2093 AS2 (ldd,%B0,%B1) CR_TAB
2094 AS2 (ldd,__tmp_reg__,%C1) CR_TAB
2095 AS2 (ldd,%D0,%D1) CR_TAB
2096 AS2 (mov,%C0,__tmp_reg__));
2097 return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2098 AS2 (ldd,%B0,%B1) CR_TAB
2099 AS2 (ldd,%C0,%C1) CR_TAB
2100 AS2 (ldd,%D0,%D1));
2102 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2103 return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2104 AS2 (ld,%C0,%1) CR_TAB
2105 AS2 (ld,%B0,%1) CR_TAB
2106 AS2 (ld,%A0,%1));
2107 else if (GET_CODE (base) == POST_INC) /* (R++) */
2108 return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2109 AS2 (ld,%B0,%1) CR_TAB
2110 AS2 (ld,%C0,%1) CR_TAB
2111 AS2 (ld,%D0,%1));
2112 else if (CONSTANT_ADDRESS_P (base))
2113 return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2114 AS2 (lds,%B0,%B1) CR_TAB
2115 AS2 (lds,%C0,%C1) CR_TAB
2116 AS2 (lds,%D0,%D1));
2118 fatal_insn ("unknown move insn:",insn);
2119 return "";
2122 const char *
2123 out_movsi_mr_r (rtx insn, rtx op[], int *l)
2125 rtx dest = op[0];
2126 rtx src = op[1];
2127 rtx base = XEXP (dest, 0);
2128 int reg_base = true_regnum (base);
2129 int reg_src = true_regnum (src);
2130 int tmp;
2132 if (!l)
2133 l = &tmp;
2135 if (CONSTANT_ADDRESS_P (base))
2136 return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2137 AS2 (sts,%B0,%B1) CR_TAB
2138 AS2 (sts,%C0,%C1) CR_TAB
2139 AS2 (sts,%D0,%D1));
2140 if (reg_base > 0) /* (r) */
2142 if (reg_base == REG_X) /* (R26) */
2144 if (reg_src == REG_X)
2146 /* "st X+,r26" is undefined */
2147 if (reg_unused_after (insn, base))
2148 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2149 AS2 (st,X,r26) CR_TAB
2150 AS2 (adiw,r26,1) CR_TAB
2151 AS2 (st,X+,__tmp_reg__) CR_TAB
2152 AS2 (st,X+,r28) CR_TAB
2153 AS2 (st,X,r29));
2154 else
2155 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2156 AS2 (st,X,r26) CR_TAB
2157 AS2 (adiw,r26,1) CR_TAB
2158 AS2 (st,X+,__tmp_reg__) CR_TAB
2159 AS2 (st,X+,r28) CR_TAB
2160 AS2 (st,X,r29) CR_TAB
2161 AS2 (sbiw,r26,3));
2163 else if (reg_base == reg_src + 2)
2165 if (reg_unused_after (insn, base))
2166 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2167 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2168 AS2 (st,%0+,%A1) CR_TAB
2169 AS2 (st,%0+,%B1) CR_TAB
2170 AS2 (st,%0+,__zero_reg__) CR_TAB
2171 AS2 (st,%0,__tmp_reg__) CR_TAB
2172 AS1 (clr,__zero_reg__));
2173 else
2174 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2175 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2176 AS2 (st,%0+,%A1) CR_TAB
2177 AS2 (st,%0+,%B1) CR_TAB
2178 AS2 (st,%0+,__zero_reg__) CR_TAB
2179 AS2 (st,%0,__tmp_reg__) CR_TAB
2180 AS1 (clr,__zero_reg__) CR_TAB
2181 AS2 (sbiw,r26,3));
2183 return *l=5, (AS2 (st,%0+,%A1) CR_TAB
2184 AS2 (st,%0+,%B1) CR_TAB
2185 AS2 (st,%0+,%C1) CR_TAB
2186 AS2 (st,%0,%D1) CR_TAB
2187 AS2 (sbiw,r26,3));
2189 else
2190 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2191 AS2 (std,%0+1,%B1) CR_TAB
2192 AS2 (std,%0+2,%C1) CR_TAB
2193 AS2 (std,%0+3,%D1));
2195 else if (GET_CODE (base) == PLUS) /* (R + i) */
2197 int disp = INTVAL (XEXP (base, 1));
2198 reg_base = REGNO (XEXP (base, 0));
2199 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2201 if (reg_base != REG_Y)
2202 fatal_insn ("incorrect insn:",insn);
2204 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2205 return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2206 AS2 (std,Y+60,%A1) CR_TAB
2207 AS2 (std,Y+61,%B1) CR_TAB
2208 AS2 (std,Y+62,%C1) CR_TAB
2209 AS2 (std,Y+63,%D1) CR_TAB
2210 AS2 (sbiw,r28,%o0-60));
2212 return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2213 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2214 AS2 (st,Y,%A1) CR_TAB
2215 AS2 (std,Y+1,%B1) CR_TAB
2216 AS2 (std,Y+2,%C1) CR_TAB
2217 AS2 (std,Y+3,%D1) CR_TAB
2218 AS2 (subi,r28,lo8(%o0)) CR_TAB
2219 AS2 (sbci,r29,hi8(%o0)));
2221 if (reg_base == REG_X)
2223 /* (X + d) = R */
2224 if (reg_src == REG_X)
2226 *l = 9;
2227 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2228 AS2 (mov,__zero_reg__,r27) CR_TAB
2229 AS2 (adiw,r26,%o0) CR_TAB
2230 AS2 (st,X+,__tmp_reg__) CR_TAB
2231 AS2 (st,X+,__zero_reg__) CR_TAB
2232 AS2 (st,X+,r28) CR_TAB
2233 AS2 (st,X,r29) CR_TAB
2234 AS1 (clr,__zero_reg__) CR_TAB
2235 AS2 (sbiw,r26,%o0+3));
2237 else if (reg_src == REG_X - 2)
2239 *l = 9;
2240 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2241 AS2 (mov,__zero_reg__,r27) CR_TAB
2242 AS2 (adiw,r26,%o0) CR_TAB
2243 AS2 (st,X+,r24) CR_TAB
2244 AS2 (st,X+,r25) CR_TAB
2245 AS2 (st,X+,__tmp_reg__) CR_TAB
2246 AS2 (st,X,__zero_reg__) CR_TAB
2247 AS1 (clr,__zero_reg__) CR_TAB
2248 AS2 (sbiw,r26,%o0+3));
2250 *l = 6;
2251 return (AS2 (adiw,r26,%o0) CR_TAB
2252 AS2 (st,X+,%A1) CR_TAB
2253 AS2 (st,X+,%B1) CR_TAB
2254 AS2 (st,X+,%C1) CR_TAB
2255 AS2 (st,X,%D1) CR_TAB
2256 AS2 (sbiw,r26,%o0+3));
2258 return *l=4, (AS2 (std,%A0,%A1) CR_TAB
2259 AS2 (std,%B0,%B1) CR_TAB
2260 AS2 (std,%C0,%C1) CR_TAB
2261 AS2 (std,%D0,%D1));
2263 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2264 return *l=4, (AS2 (st,%0,%D1) CR_TAB
2265 AS2 (st,%0,%C1) CR_TAB
2266 AS2 (st,%0,%B1) CR_TAB
2267 AS2 (st,%0,%A1));
2268 else if (GET_CODE (base) == POST_INC) /* (R++) */
2269 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2270 AS2 (st,%0,%B1) CR_TAB
2271 AS2 (st,%0,%C1) CR_TAB
2272 AS2 (st,%0,%D1));
2273 fatal_insn ("unknown move insn:",insn);
2274 return "";
2277 const char *
2278 output_movsisf(rtx insn, rtx operands[], int *l)
2280 int dummy;
2281 rtx dest = operands[0];
2282 rtx src = operands[1];
2283 int *real_l = l;
2285 if (!l)
2286 l = &dummy;
2288 if (register_operand (dest, VOIDmode))
2290 if (register_operand (src, VOIDmode)) /* mov r,r */
2292 if (true_regnum (dest) > true_regnum (src))
2294 if (AVR_ENHANCED)
2296 *l = 2;
2297 return (AS2 (movw,%C0,%C1) CR_TAB
2298 AS2 (movw,%A0,%A1));
2300 *l = 4;
2301 return (AS2 (mov,%D0,%D1) CR_TAB
2302 AS2 (mov,%C0,%C1) CR_TAB
2303 AS2 (mov,%B0,%B1) CR_TAB
2304 AS2 (mov,%A0,%A1));
2306 else
2308 if (AVR_ENHANCED)
2310 *l = 2;
2311 return (AS2 (movw,%A0,%A1) CR_TAB
2312 AS2 (movw,%C0,%C1));
2314 *l = 4;
2315 return (AS2 (mov,%A0,%A1) CR_TAB
2316 AS2 (mov,%B0,%B1) CR_TAB
2317 AS2 (mov,%C0,%C1) CR_TAB
2318 AS2 (mov,%D0,%D1));
2321 else if (CONSTANT_P (src))
2323 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2325 *l = 4;
2326 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
2327 AS2 (ldi,%B0,hi8(%1)) CR_TAB
2328 AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2329 AS2 (ldi,%D0,hhi8(%1)));
2332 if (GET_CODE (src) == CONST_INT)
2334 const char *const clr_op0 =
2335 AVR_ENHANCED ? (AS1 (clr,%A0) CR_TAB
2336 AS1 (clr,%B0) CR_TAB
2337 AS2 (movw,%C0,%A0))
2338 : (AS1 (clr,%A0) CR_TAB
2339 AS1 (clr,%B0) CR_TAB
2340 AS1 (clr,%C0) CR_TAB
2341 AS1 (clr,%D0));
2343 if (src == const0_rtx) /* mov r,L */
2345 *l = AVR_ENHANCED ? 3 : 4;
2346 return clr_op0;
2348 else if (src == const1_rtx)
2350 if (!real_l)
2351 output_asm_insn (clr_op0, operands);
2352 *l = AVR_ENHANCED ? 4 : 5;
2353 return AS1 (inc,%A0);
2355 else if (src == constm1_rtx)
2357 /* Immediate constants -1 to any register */
2358 if (AVR_ENHANCED)
2360 *l = 4;
2361 return (AS1 (clr,%A0) CR_TAB
2362 AS1 (dec,%A0) CR_TAB
2363 AS2 (mov,%B0,%A0) CR_TAB
2364 AS2 (movw,%C0,%A0));
2366 *l = 5;
2367 return (AS1 (clr,%A0) CR_TAB
2368 AS1 (dec,%A0) CR_TAB
2369 AS2 (mov,%B0,%A0) CR_TAB
2370 AS2 (mov,%C0,%A0) CR_TAB
2371 AS2 (mov,%D0,%A0));
2373 else
2375 int bit_nr = exact_log2 (INTVAL (src));
2377 if (bit_nr >= 0)
2379 *l = AVR_ENHANCED ? 5 : 6;
2380 if (!real_l)
2382 output_asm_insn (clr_op0, operands);
2383 output_asm_insn ("set", operands);
2385 if (!real_l)
2386 avr_output_bld (operands, bit_nr);
2388 return "";
2393 /* Last resort, better than loading from memory. */
2394 *l = 10;
2395 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2396 AS2 (ldi,r31,lo8(%1)) CR_TAB
2397 AS2 (mov,%A0,r31) CR_TAB
2398 AS2 (ldi,r31,hi8(%1)) CR_TAB
2399 AS2 (mov,%B0,r31) CR_TAB
2400 AS2 (ldi,r31,hlo8(%1)) CR_TAB
2401 AS2 (mov,%C0,r31) CR_TAB
2402 AS2 (ldi,r31,hhi8(%1)) CR_TAB
2403 AS2 (mov,%D0,r31) CR_TAB
2404 AS2 (mov,r31,__tmp_reg__));
2406 else if (GET_CODE (src) == MEM)
2407 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2409 else if (GET_CODE (dest) == MEM)
2411 const char *template;
2413 if (src == const0_rtx)
2414 operands[1] = zero_reg_rtx;
2416 template = out_movsi_mr_r (insn, operands, real_l);
2418 if (!real_l)
2419 output_asm_insn (template, operands);
2421 operands[1] = src;
2422 return "";
2424 fatal_insn ("invalid insn:", insn);
2425 return "";
2428 const char *
2429 out_movqi_mr_r (rtx insn, rtx op[], int *l)
2431 rtx dest = op[0];
2432 rtx src = op[1];
2433 rtx x = XEXP (dest, 0);
2434 int dummy;
2436 if (!l)
2437 l = &dummy;
2439 if (CONSTANT_ADDRESS_P (x))
2441 if (avr_io_address_p (x, 1))
2443 *l = 1;
2444 return AS2 (out,%0-0x20,%1);
2446 *l = 2;
2447 return AS2 (sts,%0,%1);
2449 /* memory access by reg+disp */
2450 else if (GET_CODE (x) == PLUS
2451 && REG_P (XEXP (x,0))
2452 && GET_CODE (XEXP (x,1)) == CONST_INT)
2454 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2456 int disp = INTVAL (XEXP (x,1));
2457 if (REGNO (XEXP (x,0)) != REG_Y)
2458 fatal_insn ("incorrect insn:",insn);
2460 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2461 return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2462 AS2 (std,Y+63,%1) CR_TAB
2463 AS2 (sbiw,r28,%o0-63));
2465 return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2466 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2467 AS2 (st,Y,%1) CR_TAB
2468 AS2 (subi,r28,lo8(%o0)) CR_TAB
2469 AS2 (sbci,r29,hi8(%o0)));
2471 else if (REGNO (XEXP (x,0)) == REG_X)
2473 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2475 if (reg_unused_after (insn, XEXP (x,0)))
2476 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2477 AS2 (adiw,r26,%o0) CR_TAB
2478 AS2 (st,X,__tmp_reg__));
2480 return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2481 AS2 (adiw,r26,%o0) CR_TAB
2482 AS2 (st,X,__tmp_reg__) CR_TAB
2483 AS2 (sbiw,r26,%o0));
2485 else
2487 if (reg_unused_after (insn, XEXP (x,0)))
2488 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2489 AS2 (st,X,%1));
2491 return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2492 AS2 (st,X,%1) CR_TAB
2493 AS2 (sbiw,r26,%o0));
2496 *l = 1;
2497 return AS2 (std,%0,%1);
2499 *l = 1;
2500 return AS2 (st,%0,%1);
2503 const char *
2504 out_movhi_mr_r (rtx insn, rtx op[], int *l)
2506 rtx dest = op[0];
2507 rtx src = op[1];
2508 rtx base = XEXP (dest, 0);
2509 int reg_base = true_regnum (base);
2510 int reg_src = true_regnum (src);
2511 int tmp;
2512 if (!l)
2513 l = &tmp;
2514 if (CONSTANT_ADDRESS_P (base))
2516 if (avr_io_address_p (base, 2))
2518 *l = 2;
2519 return (AS2 (out,%B0-0x20,%B1) CR_TAB
2520 AS2 (out,%A0-0x20,%A1));
2522 return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2523 AS2 (sts,%A0,%A1));
2525 if (reg_base > 0)
2527 if (reg_base == REG_X)
2529 if (reg_src == REG_X)
2531 /* "st X+,r26" is undefined */
2532 if (reg_unused_after (insn, src))
2533 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2534 AS2 (st,X,r26) CR_TAB
2535 AS2 (adiw,r26,1) CR_TAB
2536 AS2 (st,X,__tmp_reg__));
2537 else
2538 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2539 AS2 (st,X,r26) CR_TAB
2540 AS2 (adiw,r26,1) CR_TAB
2541 AS2 (st,X,__tmp_reg__) CR_TAB
2542 AS2 (sbiw,r26,1));
2544 else
2546 if (reg_unused_after (insn, base))
2547 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2548 AS2 (st,X,%B1));
2549 else
2550 return *l=3, (AS2 (st ,X+,%A1) CR_TAB
2551 AS2 (st ,X,%B1) CR_TAB
2552 AS2 (sbiw,r26,1));
2555 else
2556 return *l=2, (AS2 (st ,%0,%A1) CR_TAB
2557 AS2 (std,%0+1,%B1));
2559 else if (GET_CODE (base) == PLUS)
2561 int disp = INTVAL (XEXP (base, 1));
2562 reg_base = REGNO (XEXP (base, 0));
2563 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2565 if (reg_base != REG_Y)
2566 fatal_insn ("incorrect insn:",insn);
2568 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2569 return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2570 AS2 (std,Y+62,%A1) CR_TAB
2571 AS2 (std,Y+63,%B1) CR_TAB
2572 AS2 (sbiw,r28,%o0-62));
2574 return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2575 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2576 AS2 (st,Y,%A1) CR_TAB
2577 AS2 (std,Y+1,%B1) CR_TAB
2578 AS2 (subi,r28,lo8(%o0)) CR_TAB
2579 AS2 (sbci,r29,hi8(%o0)));
2581 if (reg_base == REG_X)
2583 /* (X + d) = R */
2584 if (reg_src == REG_X)
2586 *l = 7;
2587 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2588 AS2 (mov,__zero_reg__,r27) CR_TAB
2589 AS2 (adiw,r26,%o0) CR_TAB
2590 AS2 (st,X+,__tmp_reg__) CR_TAB
2591 AS2 (st,X,__zero_reg__) CR_TAB
2592 AS1 (clr,__zero_reg__) CR_TAB
2593 AS2 (sbiw,r26,%o0+1));
2595 *l = 4;
2596 return (AS2 (adiw,r26,%o0) CR_TAB
2597 AS2 (st,X+,%A1) CR_TAB
2598 AS2 (st,X,%B1) CR_TAB
2599 AS2 (sbiw,r26,%o0+1));
2601 return *l=2, (AS2 (std,%A0,%A1) CR_TAB
2602 AS2 (std,%B0,%B1));
2604 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2605 return *l=2, (AS2 (st,%0,%B1) CR_TAB
2606 AS2 (st,%0,%A1));
2607 else if (GET_CODE (base) == POST_INC) /* (R++) */
2608 return *l=2, (AS2 (st,%0,%A1) CR_TAB
2609 AS2 (st,%0,%B1));
2610 fatal_insn ("unknown move insn:",insn);
2611 return "";
2614 /* Return 1 if frame pointer for current function required. */
2617 frame_pointer_required_p (void)
2619 return (current_function_calls_alloca
2620 || current_function_args_info.nregs == 0
2621 || get_frame_size () > 0);
2624 /* Returns the condition of compare insn INSN, or UNKNOWN. */
2626 static RTX_CODE
2627 compare_condition (rtx insn)
2629 rtx next = next_real_insn (insn);
2630 RTX_CODE cond = UNKNOWN;
2631 if (next && GET_CODE (next) == JUMP_INSN)
2633 rtx pat = PATTERN (next);
2634 rtx src = SET_SRC (pat);
2635 rtx t = XEXP (src, 0);
2636 cond = GET_CODE (t);
2638 return cond;
2641 /* Returns nonzero if INSN is a tst insn that only tests the sign. */
2643 static int
2644 compare_sign_p (rtx insn)
2646 RTX_CODE cond = compare_condition (insn);
2647 return (cond == GE || cond == LT);
2650 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
2651 that needs to be swapped (GT, GTU, LE, LEU). */
2654 compare_diff_p (rtx insn)
2656 RTX_CODE cond = compare_condition (insn);
2657 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2660 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition. */
2663 compare_eq_p (rtx insn)
2665 RTX_CODE cond = compare_condition (insn);
2666 return (cond == EQ || cond == NE);
2670 /* Output test instruction for HImode. */
2672 const char *
2673 out_tsthi (rtx insn, int *l)
2675 if (compare_sign_p (insn))
2677 if (l) *l = 1;
2678 return AS1 (tst,%B0);
2680 if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
2681 && compare_eq_p (insn))
2683 /* Faster than sbiw if we can clobber the operand. */
2684 if (l) *l = 1;
2685 return AS2 (or,%A0,%B0);
2687 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2689 if (l) *l = 1;
2690 return AS2 (sbiw,%0,0);
2692 if (l) *l = 2;
2693 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2694 AS2 (cpc,%B0,__zero_reg__));
2698 /* Output test instruction for SImode. */
2700 const char *
2701 out_tstsi (rtx insn, int *l)
2703 if (compare_sign_p (insn))
2705 if (l) *l = 1;
2706 return AS1 (tst,%D0);
2708 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2710 if (l) *l = 3;
2711 return (AS2 (sbiw,%A0,0) CR_TAB
2712 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2713 AS2 (cpc,%D0,__zero_reg__));
2715 if (l) *l = 4;
2716 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2717 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2718 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2719 AS2 (cpc,%D0,__zero_reg__));
2723 /* Generate asm equivalent for various shifts.
2724 Shift count is a CONST_INT, MEM or REG.
2725 This only handles cases that are not already
2726 carefully hand-optimized in ?sh??i3_out. */
2728 void
2729 out_shift_with_cnt (const char *template, rtx insn, rtx operands[],
2730 int *len, int t_len)
2732 rtx op[10];
2733 char str[500];
2734 int second_label = 1;
2735 int saved_in_tmp = 0;
2736 int use_zero_reg = 0;
2738 op[0] = operands[0];
2739 op[1] = operands[1];
2740 op[2] = operands[2];
2741 op[3] = operands[3];
2742 str[0] = 0;
2744 if (len)
2745 *len = 1;
2747 if (GET_CODE (operands[2]) == CONST_INT)
2749 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2750 int count = INTVAL (operands[2]);
2751 int max_len = 10; /* If larger than this, always use a loop. */
2753 if (count <= 0)
2755 if (len)
2756 *len = 0;
2757 return;
2760 if (count < 8 && !scratch)
2761 use_zero_reg = 1;
2763 if (optimize_size)
2764 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
2766 if (t_len * count <= max_len)
2768 /* Output shifts inline with no loop - faster. */
2769 if (len)
2770 *len = t_len * count;
2771 else
2773 while (count-- > 0)
2774 output_asm_insn (template, op);
2777 return;
2780 if (scratch)
2782 if (!len)
2783 strcat (str, AS2 (ldi,%3,%2));
2785 else if (use_zero_reg)
2787 /* Hack to save one word: use __zero_reg__ as loop counter.
2788 Set one bit, then shift in a loop until it is 0 again. */
2790 op[3] = zero_reg_rtx;
2791 if (len)
2792 *len = 2;
2793 else
2794 strcat (str, ("set" CR_TAB
2795 AS2 (bld,%3,%2-1)));
2797 else
2799 /* No scratch register available, use one from LD_REGS (saved in
2800 __tmp_reg__) that doesn't overlap with registers to shift. */
2802 op[3] = gen_rtx_REG (QImode,
2803 ((true_regnum (operands[0]) - 1) & 15) + 16);
2804 op[4] = tmp_reg_rtx;
2805 saved_in_tmp = 1;
2807 if (len)
2808 *len = 3; /* Includes "mov %3,%4" after the loop. */
2809 else
2810 strcat (str, (AS2 (mov,%4,%3) CR_TAB
2811 AS2 (ldi,%3,%2)));
2814 second_label = 0;
2816 else if (GET_CODE (operands[2]) == MEM)
2818 rtx op_mov[10];
2820 op[3] = op_mov[0] = tmp_reg_rtx;
2821 op_mov[1] = op[2];
2823 if (len)
2824 out_movqi_r_mr (insn, op_mov, len);
2825 else
2826 output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2828 else if (register_operand (operands[2], QImode))
2830 if (reg_unused_after (insn, operands[2]))
2831 op[3] = op[2];
2832 else
2834 op[3] = tmp_reg_rtx;
2835 if (!len)
2836 strcat (str, (AS2 (mov,%3,%2) CR_TAB));
2839 else
2840 fatal_insn ("bad shift insn:", insn);
2842 if (second_label)
2844 if (len)
2845 ++*len;
2846 else
2847 strcat (str, AS1 (rjmp,2f));
2850 if (len)
2851 *len += t_len + 2; /* template + dec + brXX */
2852 else
2854 strcat (str, "\n1:\t");
2855 strcat (str, template);
2856 strcat (str, second_label ? "\n2:\t" : "\n\t");
2857 strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
2858 strcat (str, CR_TAB);
2859 strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
2860 if (saved_in_tmp)
2861 strcat (str, (CR_TAB AS2 (mov,%3,%4)));
2862 output_asm_insn (str, op);
2867 /* 8bit shift left ((char)x << i) */
2869 const char *
2870 ashlqi3_out (rtx insn, rtx operands[], int *len)
2872 if (GET_CODE (operands[2]) == CONST_INT)
2874 int k;
2876 if (!len)
2877 len = &k;
2879 switch (INTVAL (operands[2]))
2881 default:
2882 if (INTVAL (operands[2]) < 8)
2883 break;
2885 *len = 1;
2886 return AS1 (clr,%0);
2888 case 1:
2889 *len = 1;
2890 return AS1 (lsl,%0);
2892 case 2:
2893 *len = 2;
2894 return (AS1 (lsl,%0) CR_TAB
2895 AS1 (lsl,%0));
2897 case 3:
2898 *len = 3;
2899 return (AS1 (lsl,%0) CR_TAB
2900 AS1 (lsl,%0) CR_TAB
2901 AS1 (lsl,%0));
2903 case 4:
2904 if (test_hard_reg_class (LD_REGS, operands[0]))
2906 *len = 2;
2907 return (AS1 (swap,%0) CR_TAB
2908 AS2 (andi,%0,0xf0));
2910 *len = 4;
2911 return (AS1 (lsl,%0) CR_TAB
2912 AS1 (lsl,%0) CR_TAB
2913 AS1 (lsl,%0) CR_TAB
2914 AS1 (lsl,%0));
2916 case 5:
2917 if (test_hard_reg_class (LD_REGS, operands[0]))
2919 *len = 3;
2920 return (AS1 (swap,%0) CR_TAB
2921 AS1 (lsl,%0) CR_TAB
2922 AS2 (andi,%0,0xe0));
2924 *len = 5;
2925 return (AS1 (lsl,%0) CR_TAB
2926 AS1 (lsl,%0) CR_TAB
2927 AS1 (lsl,%0) CR_TAB
2928 AS1 (lsl,%0) CR_TAB
2929 AS1 (lsl,%0));
2931 case 6:
2932 if (test_hard_reg_class (LD_REGS, operands[0]))
2934 *len = 4;
2935 return (AS1 (swap,%0) CR_TAB
2936 AS1 (lsl,%0) CR_TAB
2937 AS1 (lsl,%0) CR_TAB
2938 AS2 (andi,%0,0xc0));
2940 *len = 6;
2941 return (AS1 (lsl,%0) CR_TAB
2942 AS1 (lsl,%0) CR_TAB
2943 AS1 (lsl,%0) CR_TAB
2944 AS1 (lsl,%0) CR_TAB
2945 AS1 (lsl,%0) CR_TAB
2946 AS1 (lsl,%0));
2948 case 7:
2949 *len = 3;
2950 return (AS1 (ror,%0) CR_TAB
2951 AS1 (clr,%0) CR_TAB
2952 AS1 (ror,%0));
2955 else if (CONSTANT_P (operands[2]))
2956 fatal_insn ("internal compiler error. Incorrect shift:", insn);
2958 out_shift_with_cnt (AS1 (lsl,%0),
2959 insn, operands, len, 1);
2960 return "";
2964 /* 16bit shift left ((short)x << i) */
2966 const char *
2967 ashlhi3_out (rtx insn, rtx operands[], int *len)
2969 if (GET_CODE (operands[2]) == CONST_INT)
2971 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2972 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
2973 int k;
2974 int *t = len;
2976 if (!len)
2977 len = &k;
2979 switch (INTVAL (operands[2]))
2981 default:
2982 if (INTVAL (operands[2]) < 16)
2983 break;
2985 *len = 2;
2986 return (AS1 (clr,%B0) CR_TAB
2987 AS1 (clr,%A0));
2989 case 4:
2990 if (optimize_size && scratch)
2991 break; /* 5 */
2992 if (ldi_ok)
2994 *len = 6;
2995 return (AS1 (swap,%A0) CR_TAB
2996 AS1 (swap,%B0) CR_TAB
2997 AS2 (andi,%B0,0xf0) CR_TAB
2998 AS2 (eor,%B0,%A0) CR_TAB
2999 AS2 (andi,%A0,0xf0) CR_TAB
3000 AS2 (eor,%B0,%A0));
3002 if (scratch)
3004 *len = 7;
3005 return (AS1 (swap,%A0) CR_TAB
3006 AS1 (swap,%B0) CR_TAB
3007 AS2 (ldi,%3,0xf0) CR_TAB
3008 AS2 (and,%B0,%3) CR_TAB
3009 AS2 (eor,%B0,%A0) CR_TAB
3010 AS2 (and,%A0,%3) CR_TAB
3011 AS2 (eor,%B0,%A0));
3013 break; /* optimize_size ? 6 : 8 */
3015 case 5:
3016 if (optimize_size)
3017 break; /* scratch ? 5 : 6 */
3018 if (ldi_ok)
3020 *len = 8;
3021 return (AS1 (lsl,%A0) CR_TAB
3022 AS1 (rol,%B0) CR_TAB
3023 AS1 (swap,%A0) CR_TAB
3024 AS1 (swap,%B0) CR_TAB
3025 AS2 (andi,%B0,0xf0) CR_TAB
3026 AS2 (eor,%B0,%A0) CR_TAB
3027 AS2 (andi,%A0,0xf0) CR_TAB
3028 AS2 (eor,%B0,%A0));
3030 if (scratch)
3032 *len = 9;
3033 return (AS1 (lsl,%A0) CR_TAB
3034 AS1 (rol,%B0) CR_TAB
3035 AS1 (swap,%A0) CR_TAB
3036 AS1 (swap,%B0) CR_TAB
3037 AS2 (ldi,%3,0xf0) CR_TAB
3038 AS2 (and,%B0,%3) CR_TAB
3039 AS2 (eor,%B0,%A0) CR_TAB
3040 AS2 (and,%A0,%3) CR_TAB
3041 AS2 (eor,%B0,%A0));
3043 break; /* 10 */
3045 case 6:
3046 if (optimize_size)
3047 break; /* scratch ? 5 : 6 */
3048 *len = 9;
3049 return (AS1 (clr,__tmp_reg__) CR_TAB
3050 AS1 (lsr,%B0) CR_TAB
3051 AS1 (ror,%A0) CR_TAB
3052 AS1 (ror,__tmp_reg__) CR_TAB
3053 AS1 (lsr,%B0) CR_TAB
3054 AS1 (ror,%A0) CR_TAB
3055 AS1 (ror,__tmp_reg__) CR_TAB
3056 AS2 (mov,%B0,%A0) CR_TAB
3057 AS2 (mov,%A0,__tmp_reg__));
3059 case 7:
3060 *len = 5;
3061 return (AS1 (lsr,%B0) CR_TAB
3062 AS2 (mov,%B0,%A0) CR_TAB
3063 AS1 (clr,%A0) CR_TAB
3064 AS1 (ror,%B0) CR_TAB
3065 AS1 (ror,%A0));
3067 case 8:
3068 if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
3069 return *len = 1, AS1 (clr,%A0);
3070 else
3071 return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3072 AS1 (clr,%A0));
3074 case 9:
3075 *len = 3;
3076 return (AS2 (mov,%B0,%A0) CR_TAB
3077 AS1 (clr,%A0) CR_TAB
3078 AS1 (lsl,%B0));
3080 case 10:
3081 *len = 4;
3082 return (AS2 (mov,%B0,%A0) CR_TAB
3083 AS1 (clr,%A0) CR_TAB
3084 AS1 (lsl,%B0) CR_TAB
3085 AS1 (lsl,%B0));
3087 case 11:
3088 *len = 5;
3089 return (AS2 (mov,%B0,%A0) CR_TAB
3090 AS1 (clr,%A0) CR_TAB
3091 AS1 (lsl,%B0) CR_TAB
3092 AS1 (lsl,%B0) CR_TAB
3093 AS1 (lsl,%B0));
3095 case 12:
3096 if (ldi_ok)
3098 *len = 4;
3099 return (AS2 (mov,%B0,%A0) CR_TAB
3100 AS1 (clr,%A0) CR_TAB
3101 AS1 (swap,%B0) CR_TAB
3102 AS2 (andi,%B0,0xf0));
3104 if (scratch)
3106 *len = 5;
3107 return (AS2 (mov,%B0,%A0) CR_TAB
3108 AS1 (clr,%A0) CR_TAB
3109 AS1 (swap,%B0) CR_TAB
3110 AS2 (ldi,%3,0xf0) CR_TAB
3111 AS2 (and,%B0,%3));
3113 *len = 6;
3114 return (AS2 (mov,%B0,%A0) CR_TAB
3115 AS1 (clr,%A0) CR_TAB
3116 AS1 (lsl,%B0) CR_TAB
3117 AS1 (lsl,%B0) CR_TAB
3118 AS1 (lsl,%B0) CR_TAB
3119 AS1 (lsl,%B0));
3121 case 13:
3122 if (ldi_ok)
3124 *len = 5;
3125 return (AS2 (mov,%B0,%A0) CR_TAB
3126 AS1 (clr,%A0) CR_TAB
3127 AS1 (swap,%B0) CR_TAB
3128 AS1 (lsl,%B0) CR_TAB
3129 AS2 (andi,%B0,0xe0));
3131 if (AVR_ENHANCED && scratch)
3133 *len = 5;
3134 return (AS2 (ldi,%3,0x20) CR_TAB
3135 AS2 (mul,%A0,%3) CR_TAB
3136 AS2 (mov,%B0,r0) CR_TAB
3137 AS1 (clr,%A0) CR_TAB
3138 AS1 (clr,__zero_reg__));
3140 if (optimize_size && scratch)
3141 break; /* 5 */
3142 if (scratch)
3144 *len = 6;
3145 return (AS2 (mov,%B0,%A0) CR_TAB
3146 AS1 (clr,%A0) CR_TAB
3147 AS1 (swap,%B0) CR_TAB
3148 AS1 (lsl,%B0) CR_TAB
3149 AS2 (ldi,%3,0xe0) CR_TAB
3150 AS2 (and,%B0,%3));
3152 if (AVR_ENHANCED)
3154 *len = 6;
3155 return ("set" CR_TAB
3156 AS2 (bld,r1,5) CR_TAB
3157 AS2 (mul,%A0,r1) CR_TAB
3158 AS2 (mov,%B0,r0) CR_TAB
3159 AS1 (clr,%A0) CR_TAB
3160 AS1 (clr,__zero_reg__));
3162 *len = 7;
3163 return (AS2 (mov,%B0,%A0) CR_TAB
3164 AS1 (clr,%A0) CR_TAB
3165 AS1 (lsl,%B0) CR_TAB
3166 AS1 (lsl,%B0) CR_TAB
3167 AS1 (lsl,%B0) CR_TAB
3168 AS1 (lsl,%B0) CR_TAB
3169 AS1 (lsl,%B0));
3171 case 14:
3172 if (AVR_ENHANCED && ldi_ok)
3174 *len = 5;
3175 return (AS2 (ldi,%B0,0x40) CR_TAB
3176 AS2 (mul,%A0,%B0) CR_TAB
3177 AS2 (mov,%B0,r0) CR_TAB
3178 AS1 (clr,%A0) CR_TAB
3179 AS1 (clr,__zero_reg__));
3181 if (AVR_ENHANCED && scratch)
3183 *len = 5;
3184 return (AS2 (ldi,%3,0x40) CR_TAB
3185 AS2 (mul,%A0,%3) CR_TAB
3186 AS2 (mov,%B0,r0) CR_TAB
3187 AS1 (clr,%A0) CR_TAB
3188 AS1 (clr,__zero_reg__));
3190 if (optimize_size && ldi_ok)
3192 *len = 5;
3193 return (AS2 (mov,%B0,%A0) CR_TAB
3194 AS2 (ldi,%A0,6) "\n1:\t"
3195 AS1 (lsl,%B0) CR_TAB
3196 AS1 (dec,%A0) CR_TAB
3197 AS1 (brne,1b));
3199 if (optimize_size && scratch)
3200 break; /* 5 */
3201 *len = 6;
3202 return (AS1 (clr,%B0) CR_TAB
3203 AS1 (lsr,%A0) CR_TAB
3204 AS1 (ror,%B0) CR_TAB
3205 AS1 (lsr,%A0) CR_TAB
3206 AS1 (ror,%B0) CR_TAB
3207 AS1 (clr,%A0));
3209 case 15:
3210 *len = 4;
3211 return (AS1 (clr,%B0) CR_TAB
3212 AS1 (lsr,%A0) CR_TAB
3213 AS1 (ror,%B0) CR_TAB
3214 AS1 (clr,%A0));
3216 len = t;
3218 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3219 AS1 (rol,%B0)),
3220 insn, operands, len, 2);
3221 return "";
3225 /* 32bit shift left ((long)x << i) */
3227 const char *
3228 ashlsi3_out (rtx insn, rtx operands[], int *len)
3230 if (GET_CODE (operands[2]) == CONST_INT)
3232 int k;
3233 int *t = len;
3235 if (!len)
3236 len = &k;
3238 switch (INTVAL (operands[2]))
3240 default:
3241 if (INTVAL (operands[2]) < 32)
3242 break;
3244 if (AVR_ENHANCED)
3245 return *len = 3, (AS1 (clr,%D0) CR_TAB
3246 AS1 (clr,%C0) CR_TAB
3247 AS2 (movw,%A0,%C0));
3248 *len = 4;
3249 return (AS1 (clr,%D0) CR_TAB
3250 AS1 (clr,%C0) CR_TAB
3251 AS1 (clr,%B0) CR_TAB
3252 AS1 (clr,%A0));
3254 case 8:
3256 int reg0 = true_regnum (operands[0]);
3257 int reg1 = true_regnum (operands[1]);
3258 *len = 4;
3259 if (reg0 >= reg1)
3260 return (AS2 (mov,%D0,%C1) CR_TAB
3261 AS2 (mov,%C0,%B1) CR_TAB
3262 AS2 (mov,%B0,%A1) CR_TAB
3263 AS1 (clr,%A0));
3264 else if (reg0 + 1 == reg1)
3266 *len = 1;
3267 return AS1 (clr,%A0);
3269 else
3270 return (AS1 (clr,%A0) CR_TAB
3271 AS2 (mov,%B0,%A1) CR_TAB
3272 AS2 (mov,%C0,%B1) CR_TAB
3273 AS2 (mov,%D0,%C1));
3276 case 16:
3278 int reg0 = true_regnum (operands[0]);
3279 int reg1 = true_regnum (operands[1]);
3280 *len = 4;
3281 if (AVR_ENHANCED && (reg0 + 2 != reg1))
3283 *len = 3;
3284 return (AS2 (movw,%C0,%A1) CR_TAB
3285 AS1 (clr,%B0) CR_TAB
3286 AS1 (clr,%A0));
3288 if (reg0 + 1 >= reg1)
3289 return (AS2 (mov,%D0,%B1) CR_TAB
3290 AS2 (mov,%C0,%A1) CR_TAB
3291 AS1 (clr,%B0) CR_TAB
3292 AS1 (clr,%A0));
3293 if (reg0 + 2 == reg1)
3295 *len = 2;
3296 return (AS1 (clr,%B0) CR_TAB
3297 AS1 (clr,%A0));
3299 else
3300 return (AS2 (mov,%C0,%A1) CR_TAB
3301 AS2 (mov,%D0,%B1) CR_TAB
3302 AS1 (clr,%B0) CR_TAB
3303 AS1 (clr,%A0));
3306 case 24:
3307 *len = 4;
3308 if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
3309 return (AS2 (mov,%D0,%A1) CR_TAB
3310 AS1 (clr,%C0) CR_TAB
3311 AS1 (clr,%B0) CR_TAB
3312 AS1 (clr,%A0));
3313 else
3315 *len = 3;
3316 return (AS1 (clr,%C0) CR_TAB
3317 AS1 (clr,%B0) CR_TAB
3318 AS1 (clr,%A0));
3321 case 31:
3322 *len = 6;
3323 return (AS1 (clr,%D0) CR_TAB
3324 AS1 (lsr,%A0) CR_TAB
3325 AS1 (ror,%D0) CR_TAB
3326 AS1 (clr,%C0) CR_TAB
3327 AS1 (clr,%B0) CR_TAB
3328 AS1 (clr,%A0));
3330 len = t;
3332 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3333 AS1 (rol,%B0) CR_TAB
3334 AS1 (rol,%C0) CR_TAB
3335 AS1 (rol,%D0)),
3336 insn, operands, len, 4);
3337 return "";
3340 /* 8bit arithmetic shift right ((signed char)x >> i) */
3342 const char *
3343 ashrqi3_out (rtx insn, rtx operands[], int *len)
3345 if (GET_CODE (operands[2]) == CONST_INT)
3347 int k;
3349 if (!len)
3350 len = &k;
3352 switch (INTVAL (operands[2]))
3354 case 1:
3355 *len = 1;
3356 return AS1 (asr,%0);
3358 case 2:
3359 *len = 2;
3360 return (AS1 (asr,%0) CR_TAB
3361 AS1 (asr,%0));
3363 case 3:
3364 *len = 3;
3365 return (AS1 (asr,%0) CR_TAB
3366 AS1 (asr,%0) CR_TAB
3367 AS1 (asr,%0));
3369 case 4:
3370 *len = 4;
3371 return (AS1 (asr,%0) CR_TAB
3372 AS1 (asr,%0) CR_TAB
3373 AS1 (asr,%0) CR_TAB
3374 AS1 (asr,%0));
3376 case 5:
3377 *len = 5;
3378 return (AS1 (asr,%0) CR_TAB
3379 AS1 (asr,%0) CR_TAB
3380 AS1 (asr,%0) CR_TAB
3381 AS1 (asr,%0) CR_TAB
3382 AS1 (asr,%0));
3384 case 6:
3385 *len = 4;
3386 return (AS2 (bst,%0,6) CR_TAB
3387 AS1 (lsl,%0) CR_TAB
3388 AS2 (sbc,%0,%0) CR_TAB
3389 AS2 (bld,%0,0));
3391 default:
3392 if (INTVAL (operands[2]) < 8)
3393 break;
3395 /* fall through */
3397 case 7:
3398 *len = 2;
3399 return (AS1 (lsl,%0) CR_TAB
3400 AS2 (sbc,%0,%0));
3403 else if (CONSTANT_P (operands[2]))
3404 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3406 out_shift_with_cnt (AS1 (asr,%0),
3407 insn, operands, len, 1);
3408 return "";
3412 /* 16bit arithmetic shift right ((signed short)x >> i) */
3414 const char *
3415 ashrhi3_out (rtx insn, rtx operands[], int *len)
3417 if (GET_CODE (operands[2]) == CONST_INT)
3419 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3420 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3421 int k;
3422 int *t = len;
3424 if (!len)
3425 len = &k;
3427 switch (INTVAL (operands[2]))
3429 case 4:
3430 case 5:
3431 /* XXX try to optimize this too? */
3432 break;
3434 case 6:
3435 if (optimize_size)
3436 break; /* scratch ? 5 : 6 */
3437 *len = 8;
3438 return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3439 AS2 (mov,%A0,%B0) CR_TAB
3440 AS1 (lsl,__tmp_reg__) CR_TAB
3441 AS1 (rol,%A0) CR_TAB
3442 AS2 (sbc,%B0,%B0) CR_TAB
3443 AS1 (lsl,__tmp_reg__) CR_TAB
3444 AS1 (rol,%A0) CR_TAB
3445 AS1 (rol,%B0));
3447 case 7:
3448 *len = 4;
3449 return (AS1 (lsl,%A0) CR_TAB
3450 AS2 (mov,%A0,%B0) CR_TAB
3451 AS1 (rol,%A0) CR_TAB
3452 AS2 (sbc,%B0,%B0));
3454 case 8:
3456 int reg0 = true_regnum (operands[0]);
3457 int reg1 = true_regnum (operands[1]);
3459 if (reg0 == reg1)
3460 return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3461 AS1 (lsl,%B0) CR_TAB
3462 AS2 (sbc,%B0,%B0));
3463 else if (reg0 == reg1 + 1)
3464 return *len = 3, (AS1 (clr,%B0) CR_TAB
3465 AS2 (sbrc,%A0,7) CR_TAB
3466 AS1 (dec,%B0));
3468 return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3469 AS1 (clr,%B0) CR_TAB
3470 AS2 (sbrc,%A0,7) CR_TAB
3471 AS1 (dec,%B0));
3474 case 9:
3475 *len = 4;
3476 return (AS2 (mov,%A0,%B0) CR_TAB
3477 AS1 (lsl,%B0) CR_TAB
3478 AS2 (sbc,%B0,%B0) CR_TAB
3479 AS1 (asr,%A0));
3481 case 10:
3482 *len = 5;
3483 return (AS2 (mov,%A0,%B0) CR_TAB
3484 AS1 (lsl,%B0) CR_TAB
3485 AS2 (sbc,%B0,%B0) CR_TAB
3486 AS1 (asr,%A0) CR_TAB
3487 AS1 (asr,%A0));
3489 case 11:
3490 if (AVR_ENHANCED && ldi_ok)
3492 *len = 5;
3493 return (AS2 (ldi,%A0,0x20) CR_TAB
3494 AS2 (muls,%B0,%A0) CR_TAB
3495 AS2 (mov,%A0,r1) CR_TAB
3496 AS2 (sbc,%B0,%B0) CR_TAB
3497 AS1 (clr,__zero_reg__));
3499 if (optimize_size && scratch)
3500 break; /* 5 */
3501 *len = 6;
3502 return (AS2 (mov,%A0,%B0) CR_TAB
3503 AS1 (lsl,%B0) CR_TAB
3504 AS2 (sbc,%B0,%B0) CR_TAB
3505 AS1 (asr,%A0) CR_TAB
3506 AS1 (asr,%A0) CR_TAB
3507 AS1 (asr,%A0));
3509 case 12:
3510 if (AVR_ENHANCED && ldi_ok)
3512 *len = 5;
3513 return (AS2 (ldi,%A0,0x10) CR_TAB
3514 AS2 (muls,%B0,%A0) CR_TAB
3515 AS2 (mov,%A0,r1) CR_TAB
3516 AS2 (sbc,%B0,%B0) CR_TAB
3517 AS1 (clr,__zero_reg__));
3519 if (optimize_size && scratch)
3520 break; /* 5 */
3521 *len = 7;
3522 return (AS2 (mov,%A0,%B0) CR_TAB
3523 AS1 (lsl,%B0) CR_TAB
3524 AS2 (sbc,%B0,%B0) CR_TAB
3525 AS1 (asr,%A0) CR_TAB
3526 AS1 (asr,%A0) CR_TAB
3527 AS1 (asr,%A0) CR_TAB
3528 AS1 (asr,%A0));
3530 case 13:
3531 if (AVR_ENHANCED && ldi_ok)
3533 *len = 5;
3534 return (AS2 (ldi,%A0,0x08) CR_TAB
3535 AS2 (muls,%B0,%A0) CR_TAB
3536 AS2 (mov,%A0,r1) CR_TAB
3537 AS2 (sbc,%B0,%B0) CR_TAB
3538 AS1 (clr,__zero_reg__));
3540 if (optimize_size)
3541 break; /* scratch ? 5 : 7 */
3542 *len = 8;
3543 return (AS2 (mov,%A0,%B0) CR_TAB
3544 AS1 (lsl,%B0) CR_TAB
3545 AS2 (sbc,%B0,%B0) CR_TAB
3546 AS1 (asr,%A0) CR_TAB
3547 AS1 (asr,%A0) CR_TAB
3548 AS1 (asr,%A0) CR_TAB
3549 AS1 (asr,%A0) CR_TAB
3550 AS1 (asr,%A0));
3552 case 14:
3553 *len = 5;
3554 return (AS1 (lsl,%B0) CR_TAB
3555 AS2 (sbc,%A0,%A0) CR_TAB
3556 AS1 (lsl,%B0) CR_TAB
3557 AS2 (mov,%B0,%A0) CR_TAB
3558 AS1 (rol,%A0));
3560 default:
3561 if (INTVAL (operands[2]) < 16)
3562 break;
3564 /* fall through */
3566 case 15:
3567 return *len = 3, (AS1 (lsl,%B0) CR_TAB
3568 AS2 (sbc,%A0,%A0) CR_TAB
3569 AS2 (mov,%B0,%A0));
3571 len = t;
3573 out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3574 AS1 (ror,%A0)),
3575 insn, operands, len, 2);
3576 return "";
3580 /* 32bit arithmetic shift right ((signed long)x >> i) */
3582 const char *
3583 ashrsi3_out (rtx insn, rtx operands[], int *len)
3585 if (GET_CODE (operands[2]) == CONST_INT)
3587 int k;
3588 int *t = len;
3590 if (!len)
3591 len = &k;
3593 switch (INTVAL (operands[2]))
3595 case 8:
3597 int reg0 = true_regnum (operands[0]);
3598 int reg1 = true_regnum (operands[1]);
3599 *len=6;
3600 if (reg0 <= reg1)
3601 return (AS2 (mov,%A0,%B1) CR_TAB
3602 AS2 (mov,%B0,%C1) CR_TAB
3603 AS2 (mov,%C0,%D1) CR_TAB
3604 AS1 (clr,%D0) CR_TAB
3605 AS2 (sbrc,%C0,7) CR_TAB
3606 AS1 (dec,%D0));
3607 else if (reg0 == reg1 + 1)
3609 *len = 3;
3610 return (AS1 (clr,%D0) CR_TAB
3611 AS2 (sbrc,%C0,7) CR_TAB
3612 AS1 (dec,%D0));
3614 else
3615 return (AS1 (clr,%D0) CR_TAB
3616 AS2 (sbrc,%D1,7) CR_TAB
3617 AS1 (dec,%D0) CR_TAB
3618 AS2 (mov,%C0,%D1) CR_TAB
3619 AS2 (mov,%B0,%C1) CR_TAB
3620 AS2 (mov,%A0,%B1));
3623 case 16:
3625 int reg0 = true_regnum (operands[0]);
3626 int reg1 = true_regnum (operands[1]);
3627 *len=6;
3628 if (AVR_ENHANCED && (reg0 != reg1 + 2))
3630 *len = 5;
3631 return (AS2 (movw,%A0,%C1) CR_TAB
3632 AS1 (clr,%D0) CR_TAB
3633 AS2 (sbrc,%B0,7) CR_TAB
3634 AS1 (com,%D0) CR_TAB
3635 AS2 (mov,%C0,%D0));
3637 if (reg0 <= reg1 + 1)
3638 return (AS2 (mov,%A0,%C1) CR_TAB
3639 AS2 (mov,%B0,%D1) CR_TAB
3640 AS1 (clr,%D0) CR_TAB
3641 AS2 (sbrc,%B0,7) CR_TAB
3642 AS1 (com,%D0) CR_TAB
3643 AS2 (mov,%C0,%D0));
3644 else if (reg0 == reg1 + 2)
3645 return *len = 4, (AS1 (clr,%D0) CR_TAB
3646 AS2 (sbrc,%B0,7) CR_TAB
3647 AS1 (com,%D0) CR_TAB
3648 AS2 (mov,%C0,%D0));
3649 else
3650 return (AS2 (mov,%B0,%D1) CR_TAB
3651 AS2 (mov,%A0,%C1) CR_TAB
3652 AS1 (clr,%D0) CR_TAB
3653 AS2 (sbrc,%B0,7) CR_TAB
3654 AS1 (com,%D0) CR_TAB
3655 AS2 (mov,%C0,%D0));
3658 case 24:
3659 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3660 return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3661 AS1 (clr,%D0) CR_TAB
3662 AS2 (sbrc,%A0,7) CR_TAB
3663 AS1 (com,%D0) CR_TAB
3664 AS2 (mov,%B0,%D0) CR_TAB
3665 AS2 (mov,%C0,%D0));
3666 else
3667 return *len = 5, (AS1 (clr,%D0) CR_TAB
3668 AS2 (sbrc,%A0,7) CR_TAB
3669 AS1 (com,%D0) CR_TAB
3670 AS2 (mov,%B0,%D0) CR_TAB
3671 AS2 (mov,%C0,%D0));
3673 default:
3674 if (INTVAL (operands[2]) < 32)
3675 break;
3677 /* fall through */
3679 case 31:
3680 if (AVR_ENHANCED)
3681 return *len = 4, (AS1 (lsl,%D0) CR_TAB
3682 AS2 (sbc,%A0,%A0) CR_TAB
3683 AS2 (mov,%B0,%A0) CR_TAB
3684 AS2 (movw,%C0,%A0));
3685 else
3686 return *len = 5, (AS1 (lsl,%D0) CR_TAB
3687 AS2 (sbc,%A0,%A0) CR_TAB
3688 AS2 (mov,%B0,%A0) CR_TAB
3689 AS2 (mov,%C0,%A0) CR_TAB
3690 AS2 (mov,%D0,%A0));
3692 len = t;
3694 out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
3695 AS1 (ror,%C0) CR_TAB
3696 AS1 (ror,%B0) CR_TAB
3697 AS1 (ror,%A0)),
3698 insn, operands, len, 4);
3699 return "";
3702 /* 8bit logic shift right ((unsigned char)x >> i) */
3704 const char *
3705 lshrqi3_out (rtx insn, rtx operands[], int *len)
3707 if (GET_CODE (operands[2]) == CONST_INT)
3709 int k;
3711 if (!len)
3712 len = &k;
3714 switch (INTVAL (operands[2]))
3716 default:
3717 if (INTVAL (operands[2]) < 8)
3718 break;
3720 *len = 1;
3721 return AS1 (clr,%0);
3723 case 1:
3724 *len = 1;
3725 return AS1 (lsr,%0);
3727 case 2:
3728 *len = 2;
3729 return (AS1 (lsr,%0) CR_TAB
3730 AS1 (lsr,%0));
3731 case 3:
3732 *len = 3;
3733 return (AS1 (lsr,%0) CR_TAB
3734 AS1 (lsr,%0) CR_TAB
3735 AS1 (lsr,%0));
3737 case 4:
3738 if (test_hard_reg_class (LD_REGS, operands[0]))
3740 *len=2;
3741 return (AS1 (swap,%0) CR_TAB
3742 AS2 (andi,%0,0x0f));
3744 *len = 4;
3745 return (AS1 (lsr,%0) CR_TAB
3746 AS1 (lsr,%0) CR_TAB
3747 AS1 (lsr,%0) CR_TAB
3748 AS1 (lsr,%0));
3750 case 5:
3751 if (test_hard_reg_class (LD_REGS, operands[0]))
3753 *len = 3;
3754 return (AS1 (swap,%0) CR_TAB
3755 AS1 (lsr,%0) CR_TAB
3756 AS2 (andi,%0,0x7));
3758 *len = 5;
3759 return (AS1 (lsr,%0) CR_TAB
3760 AS1 (lsr,%0) CR_TAB
3761 AS1 (lsr,%0) CR_TAB
3762 AS1 (lsr,%0) CR_TAB
3763 AS1 (lsr,%0));
3765 case 6:
3766 if (test_hard_reg_class (LD_REGS, operands[0]))
3768 *len = 4;
3769 return (AS1 (swap,%0) CR_TAB
3770 AS1 (lsr,%0) CR_TAB
3771 AS1 (lsr,%0) CR_TAB
3772 AS2 (andi,%0,0x3));
3774 *len = 6;
3775 return (AS1 (lsr,%0) CR_TAB
3776 AS1 (lsr,%0) CR_TAB
3777 AS1 (lsr,%0) CR_TAB
3778 AS1 (lsr,%0) CR_TAB
3779 AS1 (lsr,%0) CR_TAB
3780 AS1 (lsr,%0));
3782 case 7:
3783 *len = 3;
3784 return (AS1 (rol,%0) CR_TAB
3785 AS1 (clr,%0) CR_TAB
3786 AS1 (rol,%0));
3789 else if (CONSTANT_P (operands[2]))
3790 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3792 out_shift_with_cnt (AS1 (lsr,%0),
3793 insn, operands, len, 1);
3794 return "";
3797 /* 16bit logic shift right ((unsigned short)x >> i) */
3799 const char *
3800 lshrhi3_out (rtx insn, rtx operands[], int *len)
3802 if (GET_CODE (operands[2]) == CONST_INT)
3804 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3805 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3806 int k;
3807 int *t = len;
3809 if (!len)
3810 len = &k;
3812 switch (INTVAL (operands[2]))
3814 default:
3815 if (INTVAL (operands[2]) < 16)
3816 break;
3818 *len = 2;
3819 return (AS1 (clr,%B0) CR_TAB
3820 AS1 (clr,%A0));
3822 case 4:
3823 if (optimize_size && scratch)
3824 break; /* 5 */
3825 if (ldi_ok)
3827 *len = 6;
3828 return (AS1 (swap,%B0) CR_TAB
3829 AS1 (swap,%A0) CR_TAB
3830 AS2 (andi,%A0,0x0f) CR_TAB
3831 AS2 (eor,%A0,%B0) CR_TAB
3832 AS2 (andi,%B0,0x0f) CR_TAB
3833 AS2 (eor,%A0,%B0));
3835 if (scratch)
3837 *len = 7;
3838 return (AS1 (swap,%B0) CR_TAB
3839 AS1 (swap,%A0) CR_TAB
3840 AS2 (ldi,%3,0x0f) CR_TAB
3841 AS2 (and,%A0,%3) CR_TAB
3842 AS2 (eor,%A0,%B0) CR_TAB
3843 AS2 (and,%B0,%3) CR_TAB
3844 AS2 (eor,%A0,%B0));
3846 break; /* optimize_size ? 6 : 8 */
3848 case 5:
3849 if (optimize_size)
3850 break; /* scratch ? 5 : 6 */
3851 if (ldi_ok)
3853 *len = 8;
3854 return (AS1 (lsr,%B0) CR_TAB
3855 AS1 (ror,%A0) CR_TAB
3856 AS1 (swap,%B0) CR_TAB
3857 AS1 (swap,%A0) CR_TAB
3858 AS2 (andi,%A0,0x0f) CR_TAB
3859 AS2 (eor,%A0,%B0) CR_TAB
3860 AS2 (andi,%B0,0x0f) CR_TAB
3861 AS2 (eor,%A0,%B0));
3863 if (scratch)
3865 *len = 9;
3866 return (AS1 (lsr,%B0) CR_TAB
3867 AS1 (ror,%A0) CR_TAB
3868 AS1 (swap,%B0) CR_TAB
3869 AS1 (swap,%A0) CR_TAB
3870 AS2 (ldi,%3,0x0f) CR_TAB
3871 AS2 (and,%A0,%3) CR_TAB
3872 AS2 (eor,%A0,%B0) CR_TAB
3873 AS2 (and,%B0,%3) CR_TAB
3874 AS2 (eor,%A0,%B0));
3876 break; /* 10 */
3878 case 6:
3879 if (optimize_size)
3880 break; /* scratch ? 5 : 6 */
3881 *len = 9;
3882 return (AS1 (clr,__tmp_reg__) CR_TAB
3883 AS1 (lsl,%A0) CR_TAB
3884 AS1 (rol,%B0) CR_TAB
3885 AS1 (rol,__tmp_reg__) CR_TAB
3886 AS1 (lsl,%A0) CR_TAB
3887 AS1 (rol,%B0) CR_TAB
3888 AS1 (rol,__tmp_reg__) CR_TAB
3889 AS2 (mov,%A0,%B0) CR_TAB
3890 AS2 (mov,%B0,__tmp_reg__));
3892 case 7:
3893 *len = 5;
3894 return (AS1 (lsl,%A0) CR_TAB
3895 AS2 (mov,%A0,%B0) CR_TAB
3896 AS1 (rol,%A0) CR_TAB
3897 AS2 (sbc,%B0,%B0) CR_TAB
3898 AS1 (neg,%B0));
3900 case 8:
3901 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
3902 return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
3903 AS1 (clr,%B0));
3904 else
3905 return *len = 1, AS1 (clr,%B0);
3907 case 9:
3908 *len = 3;
3909 return (AS2 (mov,%A0,%B0) CR_TAB
3910 AS1 (clr,%B0) CR_TAB
3911 AS1 (lsr,%A0));
3913 case 10:
3914 *len = 4;
3915 return (AS2 (mov,%A0,%B0) CR_TAB
3916 AS1 (clr,%B0) CR_TAB
3917 AS1 (lsr,%A0) CR_TAB
3918 AS1 (lsr,%A0));
3920 case 11:
3921 *len = 5;
3922 return (AS2 (mov,%A0,%B0) CR_TAB
3923 AS1 (clr,%B0) CR_TAB
3924 AS1 (lsr,%A0) CR_TAB
3925 AS1 (lsr,%A0) CR_TAB
3926 AS1 (lsr,%A0));
3928 case 12:
3929 if (ldi_ok)
3931 *len = 4;
3932 return (AS2 (mov,%A0,%B0) CR_TAB
3933 AS1 (clr,%B0) CR_TAB
3934 AS1 (swap,%A0) CR_TAB
3935 AS2 (andi,%A0,0x0f));
3937 if (scratch)
3939 *len = 5;
3940 return (AS2 (mov,%A0,%B0) CR_TAB
3941 AS1 (clr,%B0) CR_TAB
3942 AS1 (swap,%A0) CR_TAB
3943 AS2 (ldi,%3,0x0f) CR_TAB
3944 AS2 (and,%A0,%3));
3946 *len = 6;
3947 return (AS2 (mov,%A0,%B0) CR_TAB
3948 AS1 (clr,%B0) CR_TAB
3949 AS1 (lsr,%A0) CR_TAB
3950 AS1 (lsr,%A0) CR_TAB
3951 AS1 (lsr,%A0) CR_TAB
3952 AS1 (lsr,%A0));
3954 case 13:
3955 if (ldi_ok)
3957 *len = 5;
3958 return (AS2 (mov,%A0,%B0) CR_TAB
3959 AS1 (clr,%B0) CR_TAB
3960 AS1 (swap,%A0) CR_TAB
3961 AS1 (lsr,%A0) CR_TAB
3962 AS2 (andi,%A0,0x07));
3964 if (AVR_ENHANCED && scratch)
3966 *len = 5;
3967 return (AS2 (ldi,%3,0x08) CR_TAB
3968 AS2 (mul,%B0,%3) CR_TAB
3969 AS2 (mov,%A0,r1) CR_TAB
3970 AS1 (clr,%B0) CR_TAB
3971 AS1 (clr,__zero_reg__));
3973 if (optimize_size && scratch)
3974 break; /* 5 */
3975 if (scratch)
3977 *len = 6;
3978 return (AS2 (mov,%A0,%B0) CR_TAB
3979 AS1 (clr,%B0) CR_TAB
3980 AS1 (swap,%A0) CR_TAB
3981 AS1 (lsr,%A0) CR_TAB
3982 AS2 (ldi,%3,0x07) CR_TAB
3983 AS2 (and,%A0,%3));
3985 if (AVR_ENHANCED)
3987 *len = 6;
3988 return ("set" CR_TAB
3989 AS2 (bld,r1,3) CR_TAB
3990 AS2 (mul,%B0,r1) CR_TAB
3991 AS2 (mov,%A0,r1) CR_TAB
3992 AS1 (clr,%B0) CR_TAB
3993 AS1 (clr,__zero_reg__));
3995 *len = 7;
3996 return (AS2 (mov,%A0,%B0) CR_TAB
3997 AS1 (clr,%B0) CR_TAB
3998 AS1 (lsr,%A0) CR_TAB
3999 AS1 (lsr,%A0) CR_TAB
4000 AS1 (lsr,%A0) CR_TAB
4001 AS1 (lsr,%A0) CR_TAB
4002 AS1 (lsr,%A0));
4004 case 14:
4005 if (AVR_ENHANCED && ldi_ok)
4007 *len = 5;
4008 return (AS2 (ldi,%A0,0x04) CR_TAB
4009 AS2 (mul,%B0,%A0) CR_TAB
4010 AS2 (mov,%A0,r1) CR_TAB
4011 AS1 (clr,%B0) CR_TAB
4012 AS1 (clr,__zero_reg__));
4014 if (AVR_ENHANCED && scratch)
4016 *len = 5;
4017 return (AS2 (ldi,%3,0x04) CR_TAB
4018 AS2 (mul,%B0,%3) CR_TAB
4019 AS2 (mov,%A0,r1) CR_TAB
4020 AS1 (clr,%B0) CR_TAB
4021 AS1 (clr,__zero_reg__));
4023 if (optimize_size && ldi_ok)
4025 *len = 5;
4026 return (AS2 (mov,%A0,%B0) CR_TAB
4027 AS2 (ldi,%B0,6) "\n1:\t"
4028 AS1 (lsr,%A0) CR_TAB
4029 AS1 (dec,%B0) CR_TAB
4030 AS1 (brne,1b));
4032 if (optimize_size && scratch)
4033 break; /* 5 */
4034 *len = 6;
4035 return (AS1 (clr,%A0) CR_TAB
4036 AS1 (lsl,%B0) CR_TAB
4037 AS1 (rol,%A0) CR_TAB
4038 AS1 (lsl,%B0) CR_TAB
4039 AS1 (rol,%A0) CR_TAB
4040 AS1 (clr,%B0));
4042 case 15:
4043 *len = 4;
4044 return (AS1 (clr,%A0) CR_TAB
4045 AS1 (lsl,%B0) CR_TAB
4046 AS1 (rol,%A0) CR_TAB
4047 AS1 (clr,%B0));
4049 len = t;
4051 out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
4052 AS1 (ror,%A0)),
4053 insn, operands, len, 2);
4054 return "";
4057 /* 32bit logic shift right ((unsigned int)x >> i) */
4059 const char *
4060 lshrsi3_out (rtx insn, rtx operands[], int *len)
4062 if (GET_CODE (operands[2]) == CONST_INT)
4064 int k;
4065 int *t = len;
4067 if (!len)
4068 len = &k;
4070 switch (INTVAL (operands[2]))
4072 default:
4073 if (INTVAL (operands[2]) < 32)
4074 break;
4076 if (AVR_ENHANCED)
4077 return *len = 3, (AS1 (clr,%D0) CR_TAB
4078 AS1 (clr,%C0) CR_TAB
4079 AS2 (movw,%A0,%C0));
4080 *len = 4;
4081 return (AS1 (clr,%D0) CR_TAB
4082 AS1 (clr,%C0) CR_TAB
4083 AS1 (clr,%B0) CR_TAB
4084 AS1 (clr,%A0));
4086 case 8:
4088 int reg0 = true_regnum (operands[0]);
4089 int reg1 = true_regnum (operands[1]);
4090 *len = 4;
4091 if (reg0 <= reg1)
4092 return (AS2 (mov,%A0,%B1) CR_TAB
4093 AS2 (mov,%B0,%C1) CR_TAB
4094 AS2 (mov,%C0,%D1) CR_TAB
4095 AS1 (clr,%D0));
4096 else if (reg0 == reg1 + 1)
4097 return *len = 1, AS1 (clr,%D0);
4098 else
4099 return (AS1 (clr,%D0) CR_TAB
4100 AS2 (mov,%C0,%D1) CR_TAB
4101 AS2 (mov,%B0,%C1) CR_TAB
4102 AS2 (mov,%A0,%B1));
4105 case 16:
4107 int reg0 = true_regnum (operands[0]);
4108 int reg1 = true_regnum (operands[1]);
4109 *len = 4;
4110 if (AVR_ENHANCED && (reg0 != reg1 + 2))
4112 *len = 3;
4113 return (AS2 (movw,%A0,%C1) CR_TAB
4114 AS1 (clr,%C0) CR_TAB
4115 AS1 (clr,%D0));
4117 if (reg0 <= reg1 + 1)
4118 return (AS2 (mov,%A0,%C1) CR_TAB
4119 AS2 (mov,%B0,%D1) CR_TAB
4120 AS1 (clr,%C0) CR_TAB
4121 AS1 (clr,%D0));
4122 else if (reg0 == reg1 + 2)
4123 return *len = 2, (AS1 (clr,%C0) CR_TAB
4124 AS1 (clr,%D0));
4125 else
4126 return (AS2 (mov,%B0,%D1) CR_TAB
4127 AS2 (mov,%A0,%C1) CR_TAB
4128 AS1 (clr,%C0) CR_TAB
4129 AS1 (clr,%D0));
4132 case 24:
4133 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
4134 return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4135 AS1 (clr,%B0) CR_TAB
4136 AS1 (clr,%C0) CR_TAB
4137 AS1 (clr,%D0));
4138 else
4139 return *len = 3, (AS1 (clr,%B0) CR_TAB
4140 AS1 (clr,%C0) CR_TAB
4141 AS1 (clr,%D0));
4143 case 31:
4144 *len = 6;
4145 return (AS1 (clr,%A0) CR_TAB
4146 AS2 (sbrc,%D0,7) CR_TAB
4147 AS1 (inc,%A0) CR_TAB
4148 AS1 (clr,%B0) CR_TAB
4149 AS1 (clr,%C0) CR_TAB
4150 AS1 (clr,%D0));
4152 len = t;
4154 out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4155 AS1 (ror,%C0) CR_TAB
4156 AS1 (ror,%B0) CR_TAB
4157 AS1 (ror,%A0)),
4158 insn, operands, len, 4);
4159 return "";
4162 /* Modifies the length assigned to instruction INSN
4163 LEN is the initially computed length of the insn. */
4166 adjust_insn_length (rtx insn, int len)
4168 rtx patt = PATTERN (insn);
4169 rtx set;
4171 if (GET_CODE (patt) == SET)
4173 rtx op[10];
4174 op[1] = SET_SRC (patt);
4175 op[0] = SET_DEST (patt);
4176 if (general_operand (op[1], VOIDmode)
4177 && general_operand (op[0], VOIDmode))
4179 switch (GET_MODE (op[0]))
4181 case QImode:
4182 output_movqi (insn, op, &len);
4183 break;
4184 case HImode:
4185 output_movhi (insn, op, &len);
4186 break;
4187 case SImode:
4188 case SFmode:
4189 output_movsisf (insn, op, &len);
4190 break;
4191 default:
4192 break;
4195 else if (op[0] == cc0_rtx && REG_P (op[1]))
4197 switch (GET_MODE (op[1]))
4199 case HImode: out_tsthi (insn,&len); break;
4200 case SImode: out_tstsi (insn,&len); break;
4201 default: break;
4204 else if (GET_CODE (op[1]) == AND)
4206 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4208 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4209 if (GET_MODE (op[1]) == SImode)
4210 len = (((mask & 0xff) != 0xff)
4211 + ((mask & 0xff00) != 0xff00)
4212 + ((mask & 0xff0000L) != 0xff0000L)
4213 + ((mask & 0xff000000L) != 0xff000000L));
4214 else if (GET_MODE (op[1]) == HImode)
4215 len = (((mask & 0xff) != 0xff)
4216 + ((mask & 0xff00) != 0xff00));
4219 else if (GET_CODE (op[1]) == IOR)
4221 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4223 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4224 if (GET_MODE (op[1]) == SImode)
4225 len = (((mask & 0xff) != 0)
4226 + ((mask & 0xff00) != 0)
4227 + ((mask & 0xff0000L) != 0)
4228 + ((mask & 0xff000000L) != 0));
4229 else if (GET_MODE (op[1]) == HImode)
4230 len = (((mask & 0xff) != 0)
4231 + ((mask & 0xff00) != 0));
4235 set = single_set (insn);
4236 if (set)
4238 rtx op[10];
4240 op[1] = SET_SRC (set);
4241 op[0] = SET_DEST (set);
4243 if (GET_CODE (patt) == PARALLEL
4244 && general_operand (op[1], VOIDmode)
4245 && general_operand (op[0], VOIDmode))
4247 if (XVECLEN (patt, 0) == 2)
4248 op[2] = XVECEXP (patt, 0, 1);
4250 switch (GET_MODE (op[0]))
4252 case QImode:
4253 len = 2;
4254 break;
4255 case HImode:
4256 output_reload_inhi (insn, op, &len);
4257 break;
4258 case SImode:
4259 case SFmode:
4260 output_reload_insisf (insn, op, &len);
4261 break;
4262 default:
4263 break;
4266 else if (GET_CODE (op[1]) == ASHIFT
4267 || GET_CODE (op[1]) == ASHIFTRT
4268 || GET_CODE (op[1]) == LSHIFTRT)
4270 rtx ops[10];
4271 ops[0] = op[0];
4272 ops[1] = XEXP (op[1],0);
4273 ops[2] = XEXP (op[1],1);
4274 switch (GET_CODE (op[1]))
4276 case ASHIFT:
4277 switch (GET_MODE (op[0]))
4279 case QImode: ashlqi3_out (insn,ops,&len); break;
4280 case HImode: ashlhi3_out (insn,ops,&len); break;
4281 case SImode: ashlsi3_out (insn,ops,&len); break;
4282 default: break;
4284 break;
4285 case ASHIFTRT:
4286 switch (GET_MODE (op[0]))
4288 case QImode: ashrqi3_out (insn,ops,&len); break;
4289 case HImode: ashrhi3_out (insn,ops,&len); break;
4290 case SImode: ashrsi3_out (insn,ops,&len); break;
4291 default: break;
4293 break;
4294 case LSHIFTRT:
4295 switch (GET_MODE (op[0]))
4297 case QImode: lshrqi3_out (insn,ops,&len); break;
4298 case HImode: lshrhi3_out (insn,ops,&len); break;
4299 case SImode: lshrsi3_out (insn,ops,&len); break;
4300 default: break;
4302 break;
4303 default:
4304 break;
4308 return len;
4311 /* Return nonzero if register REG dead after INSN. */
4314 reg_unused_after (rtx insn, rtx reg)
4316 return (dead_or_set_p (insn, reg)
4317 || (REG_P(reg) && _reg_unused_after (insn, reg)));
4320 /* Return nonzero if REG is not used after INSN.
4321 We assume REG is a reload reg, and therefore does
4322 not live past labels. It may live past calls or jumps though. */
4325 _reg_unused_after (rtx insn, rtx reg)
4327 enum rtx_code code;
4328 rtx set;
4330 /* If the reg is set by this instruction, then it is safe for our
4331 case. Disregard the case where this is a store to memory, since
4332 we are checking a register used in the store address. */
4333 set = single_set (insn);
4334 if (set && GET_CODE (SET_DEST (set)) != MEM
4335 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4336 return 1;
4338 while ((insn = NEXT_INSN (insn)))
4340 rtx set;
4341 code = GET_CODE (insn);
4343 #if 0
4344 /* If this is a label that existed before reload, then the register
4345 if dead here. However, if this is a label added by reorg, then
4346 the register may still be live here. We can't tell the difference,
4347 so we just ignore labels completely. */
4348 if (code == CODE_LABEL)
4349 return 1;
4350 /* else */
4351 #endif
4353 if (!INSN_P (insn))
4354 continue;
4356 if (code == JUMP_INSN)
4357 return 0;
4359 /* If this is a sequence, we must handle them all at once.
4360 We could have for instance a call that sets the target register,
4361 and an insn in a delay slot that uses the register. In this case,
4362 we must return 0. */
4363 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
4365 int i;
4366 int retval = 0;
4368 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
4370 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
4371 rtx set = single_set (this_insn);
4373 if (GET_CODE (this_insn) == CALL_INSN)
4374 code = CALL_INSN;
4375 else if (GET_CODE (this_insn) == JUMP_INSN)
4377 if (INSN_ANNULLED_BRANCH_P (this_insn))
4378 return 0;
4379 code = JUMP_INSN;
4382 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4383 return 0;
4384 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4386 if (GET_CODE (SET_DEST (set)) != MEM)
4387 retval = 1;
4388 else
4389 return 0;
4391 if (set == 0
4392 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
4393 return 0;
4395 if (retval == 1)
4396 return 1;
4397 else if (code == JUMP_INSN)
4398 return 0;
4401 if (code == CALL_INSN)
4403 rtx tem;
4404 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4405 if (GET_CODE (XEXP (tem, 0)) == USE
4406 && REG_P (XEXP (XEXP (tem, 0), 0))
4407 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
4408 return 0;
4409 if (call_used_regs[REGNO (reg)])
4410 return 1;
4413 set = single_set (insn);
4415 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4416 return 0;
4417 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4418 return GET_CODE (SET_DEST (set)) != MEM;
4419 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
4420 return 0;
4422 return 1;
4425 /* Target hook for assembling integer objects. The AVR version needs
4426 special handling for references to certain labels. */
4428 static bool
4429 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
4431 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
4432 && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x))
4433 || GET_CODE (x) == LABEL_REF))
4435 fputs ("\t.word\tpm(", asm_out_file);
4436 output_addr_const (asm_out_file, x);
4437 fputs (")\n", asm_out_file);
4438 return true;
4440 return default_assemble_integer (x, size, aligned_p);
4443 /* The routine used to output NUL terminated strings. We use a special
4444 version of this for most svr4 targets because doing so makes the
4445 generated assembly code more compact (and thus faster to assemble)
4446 as well as more readable, especially for targets like the i386
4447 (where the only alternative is to output character sequences as
4448 comma separated lists of numbers). */
4450 void
4451 gas_output_limited_string(FILE *file, const char *str)
4453 const unsigned char *_limited_str = (unsigned char *) str;
4454 unsigned ch;
4455 fprintf (file, "%s\"", STRING_ASM_OP);
4456 for (; (ch = *_limited_str); _limited_str++)
4458 int escape;
4459 switch (escape = ESCAPES[ch])
4461 case 0:
4462 putc (ch, file);
4463 break;
4464 case 1:
4465 fprintf (file, "\\%03o", ch);
4466 break;
4467 default:
4468 putc ('\\', file);
4469 putc (escape, file);
4470 break;
4473 fprintf (file, "\"\n");
4476 /* The routine used to output sequences of byte values. We use a special
4477 version of this for most svr4 targets because doing so makes the
4478 generated assembly code more compact (and thus faster to assemble)
4479 as well as more readable. Note that if we find subparts of the
4480 character sequence which end with NUL (and which are shorter than
4481 STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
4483 void
4484 gas_output_ascii(FILE *file, const char *str, size_t length)
4486 const unsigned char *_ascii_bytes = (const unsigned char *) str;
4487 const unsigned char *limit = _ascii_bytes + length;
4488 unsigned bytes_in_chunk = 0;
4489 for (; _ascii_bytes < limit; _ascii_bytes++)
4491 const unsigned char *p;
4492 if (bytes_in_chunk >= 60)
4494 fprintf (file, "\"\n");
4495 bytes_in_chunk = 0;
4497 for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
4498 continue;
4499 if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
4501 if (bytes_in_chunk > 0)
4503 fprintf (file, "\"\n");
4504 bytes_in_chunk = 0;
4506 gas_output_limited_string (file, (char*)_ascii_bytes);
4507 _ascii_bytes = p;
4509 else
4511 int escape;
4512 unsigned ch;
4513 if (bytes_in_chunk == 0)
4514 fprintf (file, "\t.ascii\t\"");
4515 switch (escape = ESCAPES[ch = *_ascii_bytes])
4517 case 0:
4518 putc (ch, file);
4519 bytes_in_chunk++;
4520 break;
4521 case 1:
4522 fprintf (file, "\\%03o", ch);
4523 bytes_in_chunk += 4;
4524 break;
4525 default:
4526 putc ('\\', file);
4527 putc (escape, file);
4528 bytes_in_chunk += 2;
4529 break;
4533 if (bytes_in_chunk > 0)
4534 fprintf (file, "\"\n");
4537 /* Return value is nonzero if pseudos that have been
4538 assigned to registers of class CLASS would likely be spilled
4539 because registers of CLASS are needed for spill registers. */
4541 enum reg_class
4542 class_likely_spilled_p (int c)
4544 return (c != ALL_REGS && c != ADDW_REGS);
4547 /* Valid attributes:
4548 progmem - put data to program memory;
4549 signal - make a function to be hardware interrupt. After function
4550 prologue interrupts are disabled;
4551 interrupt - make a function to be hardware interrupt. After function
4552 prologue interrupts are enabled;
4553 naked - don't generate function prologue/epilogue and `ret' command.
4555 Only `progmem' attribute valid for type. */
4557 const struct attribute_spec avr_attribute_table[] =
4559 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
4560 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute },
4561 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4562 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4563 { "naked", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4564 { NULL, 0, 0, false, false, false, NULL }
4567 /* Handle a "progmem" attribute; arguments as in
4568 struct attribute_spec.handler. */
4569 static tree
4570 avr_handle_progmem_attribute (tree *node, tree name,
4571 tree args ATTRIBUTE_UNUSED,
4572 int flags ATTRIBUTE_UNUSED,
4573 bool *no_add_attrs)
4575 if (DECL_P (*node))
4577 if (TREE_CODE (*node) == TYPE_DECL)
4579 /* This is really a decl attribute, not a type attribute,
4580 but try to handle it for GCC 3.0 backwards compatibility. */
4582 tree type = TREE_TYPE (*node);
4583 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
4584 tree newtype = build_type_attribute_variant (type, attr);
4586 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
4587 TREE_TYPE (*node) = newtype;
4588 *no_add_attrs = true;
4590 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
4592 if (DECL_INITIAL (*node) == NULL_TREE && !DECL_EXTERNAL (*node))
4594 warning ("only initialized variables can be placed into "
4595 "program memory area");
4596 *no_add_attrs = true;
4599 else
4601 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name));
4602 *no_add_attrs = true;
4606 return NULL_TREE;
4609 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
4610 struct attribute_spec.handler. */
4612 static tree
4613 avr_handle_fndecl_attribute (tree *node, tree name,
4614 tree args ATTRIBUTE_UNUSED,
4615 int flags ATTRIBUTE_UNUSED,
4616 bool *no_add_attrs)
4618 if (TREE_CODE (*node) != FUNCTION_DECL)
4620 warning ("%qs attribute only applies to functions",
4621 IDENTIFIER_POINTER (name));
4622 *no_add_attrs = true;
4624 else
4626 const char *func_name = IDENTIFIER_POINTER (DECL_NAME (*node));
4627 const char *attr = IDENTIFIER_POINTER (name);
4629 /* If the function has the 'signal' or 'interrupt' attribute, test to
4630 make sure that the name of the function is "__vector_NN" so as to
4631 catch when the user misspells the interrupt vector name. */
4633 if (strncmp (attr, "interrupt", strlen ("interrupt")) == 0)
4635 if (strncmp (func_name, "__vector", strlen ("__vector")) != 0)
4637 warning ("`%s' appears to be a misspelled interrupt handler",
4638 func_name);
4641 else if (strncmp (attr, "signal", strlen ("signal")) == 0)
4643 if (strncmp (func_name, "__vector", strlen ("__vector")) != 0)
4645 warning ("`%s' appears to be a misspelled signal handler",
4646 func_name);
4651 return NULL_TREE;
4654 /* Look for attribute `progmem' in DECL
4655 if found return 1, otherwise 0. */
4658 avr_progmem_p (tree decl, tree attributes)
4660 tree a;
4662 if (TREE_CODE (decl) != VAR_DECL)
4663 return 0;
4665 if (NULL_TREE
4666 != lookup_attribute ("progmem", attributes))
4667 return 1;
4669 a=decl;
4671 a = TREE_TYPE(a);
4672 while (TREE_CODE (a) == ARRAY_TYPE);
4674 if (a == error_mark_node)
4675 return 0;
4677 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
4678 return 1;
4680 return 0;
4683 /* Add the section attribute if the variable is in progmem. */
4685 static void
4686 avr_insert_attributes (tree node, tree *attributes)
4688 if (TREE_CODE (node) == VAR_DECL
4689 && (TREE_STATIC (node) || DECL_EXTERNAL (node))
4690 && avr_progmem_p (node, *attributes))
4692 static const char dsec[] = ".progmem.data";
4693 *attributes = tree_cons (get_identifier ("section"),
4694 build_tree_list (NULL, build_string (strlen (dsec), dsec)),
4695 *attributes);
4697 /* ??? This seems sketchy. Why can't the user declare the
4698 thing const in the first place? */
4699 TREE_READONLY (node) = 1;
4703 static unsigned int
4704 avr_section_type_flags (tree decl, const char *name, int reloc)
4706 unsigned int flags = default_section_type_flags (decl, name, reloc);
4708 if (strncmp (name, ".noinit", 7) == 0)
4710 if (decl && TREE_CODE (decl) == VAR_DECL
4711 && DECL_INITIAL (decl) == NULL_TREE)
4712 flags |= SECTION_BSS; /* @nobits */
4713 else
4714 warning ("only uninitialized variables can be placed in the "
4715 ".noinit section");
4718 return flags;
4721 /* Outputs some appropriate text to go at the start of an assembler
4722 file. */
4724 static void
4725 avr_file_start (void)
4727 if (avr_asm_only_p)
4728 error ("MCU %qs supported for assembler only", avr_mcu_name);
4730 default_file_start ();
4732 fprintf (asm_out_file, "\t.arch %s\n", avr_mcu_name);
4733 fputs ("__SREG__ = 0x3f\n"
4734 "__SP_H__ = 0x3e\n"
4735 "__SP_L__ = 0x3d\n", asm_out_file);
4737 fputs ("__tmp_reg__ = 0\n"
4738 "__zero_reg__ = 1\n", asm_out_file);
4740 /* FIXME: output these only if there is anything in the .data / .bss
4741 sections - some code size could be saved by not linking in the
4742 initialization code from libgcc if one or both sections are empty. */
4743 fputs ("\t.global __do_copy_data\n", asm_out_file);
4744 fputs ("\t.global __do_clear_bss\n", asm_out_file);
4746 commands_in_file = 0;
4747 commands_in_prologues = 0;
4748 commands_in_epilogues = 0;
4751 /* Outputs to the stdio stream FILE some
4752 appropriate text to go at the end of an assembler file. */
4754 static void
4755 avr_file_end (void)
4757 fputs ("/* File ", asm_out_file);
4758 output_quoted_string (asm_out_file, main_input_filename);
4759 fprintf (asm_out_file,
4760 ": code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
4761 commands_in_file,
4762 commands_in_file,
4763 commands_in_file - commands_in_prologues - commands_in_epilogues,
4764 commands_in_prologues, commands_in_epilogues);
4767 /* Choose the order in which to allocate hard registers for
4768 pseudo-registers local to a basic block.
4770 Store the desired register order in the array `reg_alloc_order'.
4771 Element 0 should be the register to allocate first; element 1, the
4772 next register; and so on. */
4774 void
4775 order_regs_for_local_alloc (void)
4777 unsigned int i;
4778 static const int order_0[] = {
4779 24,25,
4780 18,19,
4781 20,21,
4782 22,23,
4783 30,31,
4784 26,27,
4785 28,29,
4786 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4787 0,1,
4788 32,33,34,35
4790 static const int order_1[] = {
4791 18,19,
4792 20,21,
4793 22,23,
4794 24,25,
4795 30,31,
4796 26,27,
4797 28,29,
4798 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4799 0,1,
4800 32,33,34,35
4802 static const int order_2[] = {
4803 25,24,
4804 23,22,
4805 21,20,
4806 19,18,
4807 30,31,
4808 26,27,
4809 28,29,
4810 17,16,
4811 15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4812 1,0,
4813 32,33,34,35
4816 const int *order = (TARGET_ORDER_1 ? order_1 :
4817 TARGET_ORDER_2 ? order_2 :
4818 order_0);
4819 for (i=0; i < ARRAY_SIZE (order_0); ++i)
4820 reg_alloc_order[i] = order[i];
4824 /* Mutually recursive subroutine of avr_rtx_cost for calculating the
4825 cost of an RTX operand given its context. X is the rtx of the
4826 operand, MODE is its mode, and OUTER is the rtx_code of this
4827 operand's parent operator. */
4829 static int
4830 avr_operand_rtx_cost (rtx x, enum machine_mode mode, enum rtx_code outer)
4832 enum rtx_code code = GET_CODE (x);
4833 int total;
4835 switch (code)
4837 case REG:
4838 case SUBREG:
4839 return 0;
4841 case CONST_INT:
4842 case CONST_DOUBLE:
4843 return COSTS_N_INSNS (GET_MODE_SIZE (mode));
4845 default:
4846 break;
4849 total = 0;
4850 avr_rtx_costs (x, code, outer, &total);
4851 return total;
4854 /* The AVR backend's rtx_cost function. X is rtx expression whose cost
4855 is to be calculated. Return true if the complete cost has been
4856 computed, and false if subexpressions should be scanned. In either
4857 case, *TOTAL contains the cost result. */
4859 static bool
4860 avr_rtx_costs (rtx x, int code, int outer_code, int *total)
4862 enum machine_mode mode = GET_MODE (x);
4863 HOST_WIDE_INT val;
4865 switch (code)
4867 case CONST_INT:
4868 case CONST_DOUBLE:
4869 /* Immediate constants are as cheap as registers. */
4870 *total = 0;
4871 return true;
4873 case MEM:
4874 case CONST:
4875 case LABEL_REF:
4876 case SYMBOL_REF:
4877 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
4878 return true;
4880 case NEG:
4881 switch (mode)
4883 case QImode:
4884 case SFmode:
4885 *total = COSTS_N_INSNS (1);
4886 break;
4888 case HImode:
4889 *total = COSTS_N_INSNS (3);
4890 break;
4892 case SImode:
4893 *total = COSTS_N_INSNS (7);
4894 break;
4896 default:
4897 return false;
4899 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
4900 return true;
4902 case ABS:
4903 switch (mode)
4905 case QImode:
4906 case SFmode:
4907 *total = COSTS_N_INSNS (1);
4908 break;
4910 default:
4911 return false;
4913 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
4914 return true;
4916 case NOT:
4917 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
4918 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
4919 return true;
4921 case ZERO_EXTEND:
4922 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
4923 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
4924 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
4925 return true;
4927 case SIGN_EXTEND:
4928 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
4929 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
4930 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
4931 return true;
4933 case PLUS:
4934 switch (mode)
4936 case QImode:
4937 *total = COSTS_N_INSNS (1);
4938 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4939 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
4940 break;
4942 case HImode:
4943 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4945 *total = COSTS_N_INSNS (2);
4946 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
4948 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
4949 *total = COSTS_N_INSNS (1);
4950 else
4951 *total = COSTS_N_INSNS (2);
4952 break;
4954 case SImode:
4955 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4957 *total = COSTS_N_INSNS (4);
4958 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
4960 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
4961 *total = COSTS_N_INSNS (1);
4962 else
4963 *total = COSTS_N_INSNS (4);
4964 break;
4966 default:
4967 return false;
4969 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
4970 return true;
4972 case MINUS:
4973 case AND:
4974 case IOR:
4975 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
4976 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
4977 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4978 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
4979 return true;
4981 case XOR:
4982 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
4983 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
4984 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
4985 return true;
4987 case MULT:
4988 switch (mode)
4990 case QImode:
4991 if (AVR_ENHANCED)
4992 *total = COSTS_N_INSNS (optimize_size ? 3 : 4);
4993 else if (optimize_size)
4994 *total = COSTS_N_INSNS (AVR_MEGA ? 2 : 1);
4995 else
4996 return false;
4998 case HImode:
4999 if (AVR_ENHANCED)
5000 *total = COSTS_N_INSNS (optimize_size ? 7 : 10);
5001 else if (optimize_size)
5002 *total = COSTS_N_INSNS (AVR_MEGA ? 2 : 1);
5003 else
5004 return false;
5006 default:
5007 return false;
5009 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5010 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5011 return true;
5013 case DIV:
5014 case MOD:
5015 case UDIV:
5016 case UMOD:
5017 if (optimize_size)
5018 *total = COSTS_N_INSNS (AVR_MEGA ? 2 : 1);
5019 else
5020 return false;
5021 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5022 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5023 return true;
5025 case ASHIFT:
5026 switch (mode)
5028 case QImode:
5029 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5031 *total = COSTS_N_INSNS (optimize_size ? 4 : 17);
5032 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5034 else
5036 val = INTVAL (XEXP (x, 1));
5037 if (val == 7)
5038 *total = COSTS_N_INSNS (3);
5039 else if (val >= 0 && val <= 7)
5040 *total = COSTS_N_INSNS (val);
5041 else
5042 *total = COSTS_N_INSNS (1);
5044 break;
5046 case HImode:
5047 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5049 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5050 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5052 else
5053 switch (INTVAL (XEXP (x, 1)))
5055 case 0:
5056 *total = 0;
5057 break;
5058 case 1:
5059 case 8:
5060 *total = COSTS_N_INSNS (2);
5061 break;
5062 case 9:
5063 *total = COSTS_N_INSNS (3);
5064 break;
5065 case 2:
5066 case 3:
5067 case 10:
5068 case 15:
5069 *total = COSTS_N_INSNS (4);
5070 break;
5071 case 7:
5072 case 11:
5073 case 12:
5074 *total = COSTS_N_INSNS (5);
5075 break;
5076 case 4:
5077 *total = COSTS_N_INSNS (optimize_size ? 5 : 8);
5078 break;
5079 case 6:
5080 *total = COSTS_N_INSNS (optimize_size ? 5 : 9);
5081 break;
5082 case 5:
5083 *total = COSTS_N_INSNS (optimize_size ? 5 : 10);
5084 break;
5085 default:
5086 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5087 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5089 break;
5091 case SImode:
5092 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5094 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5095 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5097 else
5098 switch (INTVAL (XEXP (x, 1)))
5100 case 0:
5101 *total = 0;
5102 break;
5103 case 24:
5104 *total = COSTS_N_INSNS (3);
5105 break;
5106 case 1:
5107 case 8:
5108 case 16:
5109 *total = COSTS_N_INSNS (4);
5110 break;
5111 case 31:
5112 *total = COSTS_N_INSNS (6);
5113 break;
5114 case 2:
5115 *total = COSTS_N_INSNS (optimize_size ? 7 : 8);
5116 break;
5117 default:
5118 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5119 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5121 break;
5123 default:
5124 return false;
5126 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5127 return true;
5129 case ASHIFTRT:
5130 switch (mode)
5132 case QImode:
5133 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5135 *total = COSTS_N_INSNS (optimize_size ? 4 : 17);
5136 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5138 else
5140 val = INTVAL (XEXP (x, 1));
5141 if (val == 6)
5142 *total = COSTS_N_INSNS (4);
5143 else if (val == 7)
5144 *total = COSTS_N_INSNS (2);
5145 else if (val >= 0 && val <= 7)
5146 *total = COSTS_N_INSNS (val);
5147 else
5148 *total = COSTS_N_INSNS (1);
5150 break;
5152 case HImode:
5153 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5155 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5156 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5158 else
5159 switch (INTVAL (XEXP (x, 1)))
5161 case 0:
5162 *total = 0;
5163 break;
5164 case 1:
5165 *total = COSTS_N_INSNS (2);
5166 break;
5167 case 15:
5168 *total = COSTS_N_INSNS (3);
5169 break;
5170 case 2:
5171 case 7:
5172 case 8:
5173 case 9:
5174 *total = COSTS_N_INSNS (4);
5175 break;
5176 case 10:
5177 case 14:
5178 *total = COSTS_N_INSNS (5);
5179 break;
5180 case 11:
5181 *total = COSTS_N_INSNS (optimize_size ? 5 : 6);
5182 break;
5183 case 12:
5184 *total = COSTS_N_INSNS (optimize_size ? 5 : 7);
5185 break;
5186 case 6:
5187 case 13:
5188 *total = COSTS_N_INSNS (optimize_size ? 5 : 8);
5189 break;
5190 default:
5191 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5192 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5194 break;
5196 case SImode:
5197 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5199 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5200 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5202 else
5203 switch (INTVAL (XEXP (x, 1)))
5205 case 0:
5206 *total = 0;
5207 break;
5208 case 1:
5209 *total = COSTS_N_INSNS (4);
5210 break;
5211 case 8:
5212 case 16:
5213 case 24:
5214 *total = COSTS_N_INSNS (6);
5215 break;
5216 case 2:
5217 *total = COSTS_N_INSNS (optimize_size ? 7 : 8);
5218 break;
5219 case 31:
5220 *total = COSTS_N_INSNS (AVR_ENHANCED ? 4 : 5);
5221 break;
5222 default:
5223 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5224 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5226 break;
5228 default:
5229 return false;
5231 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5232 return true;
5234 case LSHIFTRT:
5235 switch (mode)
5237 case QImode:
5238 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5240 *total = COSTS_N_INSNS (optimize_size ? 4 : 17);
5241 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5243 else
5245 val = INTVAL (XEXP (x, 1));
5246 if (val == 7)
5247 *total = COSTS_N_INSNS (3);
5248 else if (val >= 0 && val <= 7)
5249 *total = COSTS_N_INSNS (val);
5250 else
5251 *total = COSTS_N_INSNS (1);
5253 break;
5255 case HImode:
5256 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5258 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5259 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5261 else
5262 switch (INTVAL (XEXP (x, 1)))
5264 case 0:
5265 *total = 0;
5266 break;
5267 case 1:
5268 case 8:
5269 *total = COSTS_N_INSNS (2);
5270 break;
5271 case 9:
5272 *total = COSTS_N_INSNS (3);
5273 break;
5274 case 2:
5275 case 10:
5276 case 15:
5277 *total = COSTS_N_INSNS (4);
5278 break;
5279 case 7:
5280 case 11:
5281 *total = COSTS_N_INSNS (5);
5282 break;
5283 case 3:
5284 case 12:
5285 case 13:
5286 case 14:
5287 *total = COSTS_N_INSNS (optimize_size ? 5 : 6);
5288 break;
5289 case 4:
5290 *total = COSTS_N_INSNS (optimize_size ? 5 : 7);
5291 break;
5292 case 5:
5293 case 6:
5294 *total = COSTS_N_INSNS (optimize_size ? 5 : 9);
5295 break;
5296 default:
5297 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5298 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5300 break;
5302 case SImode:
5303 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5305 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5306 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5308 else
5309 switch (INTVAL (XEXP (x, 1)))
5311 case 0:
5312 *total = 0;
5313 break;
5314 case 1:
5315 *total = COSTS_N_INSNS (4);
5316 break;
5317 case 2:
5318 *total = COSTS_N_INSNS (optimize_size ? 7 : 8);
5319 break;
5320 case 8:
5321 case 16:
5322 case 24:
5323 *total = COSTS_N_INSNS (4);
5324 break;
5325 case 31:
5326 *total = COSTS_N_INSNS (6);
5327 break;
5328 default:
5329 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5330 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5332 break;
5334 default:
5335 return false;
5337 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5338 return true;
5340 case COMPARE:
5341 switch (GET_MODE (XEXP (x, 0)))
5343 case QImode:
5344 *total = COSTS_N_INSNS (1);
5345 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5346 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5347 break;
5349 case HImode:
5350 *total = COSTS_N_INSNS (2);
5351 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5352 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5353 else if (INTVAL (XEXP (x, 1)) != 0)
5354 *total += COSTS_N_INSNS (1);
5355 break;
5357 case SImode:
5358 *total = COSTS_N_INSNS (4);
5359 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5360 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5361 else if (INTVAL (XEXP (x, 1)) != 0)
5362 *total += COSTS_N_INSNS (3);
5363 break;
5365 default:
5366 return false;
5368 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5369 return true;
5371 default:
5372 break;
5374 return false;
5377 /* Calculate the cost of a memory address. */
5379 static int
5380 avr_address_cost (rtx x)
5382 if (GET_CODE (x) == PLUS
5383 && GET_CODE (XEXP (x,1)) == CONST_INT
5384 && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
5385 && INTVAL (XEXP (x,1)) >= 61)
5386 return 18;
5387 if (CONSTANT_ADDRESS_P (x))
5389 if (avr_io_address_p (x, 1))
5390 return 2;
5391 return 4;
5393 return 4;
5396 /* EXTRA_CONSTRAINT helper */
5399 extra_constraint (rtx x, int c)
5401 if (c == 'Q'
5402 && GET_CODE (x) == MEM
5403 && GET_CODE (XEXP (x,0)) == PLUS)
5405 if (TARGET_ALL_DEBUG)
5407 fprintf (stderr, ("extra_constraint:\n"
5408 "reload_completed: %d\n"
5409 "reload_in_progress: %d\n"),
5410 reload_completed, reload_in_progress);
5411 debug_rtx (x);
5413 if (GET_CODE (x) == MEM
5414 && GET_CODE (XEXP (x,0)) == PLUS
5415 && REG_P (XEXP (XEXP (x,0), 0))
5416 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
5417 && (INTVAL (XEXP (XEXP (x,0), 1))
5418 <= MAX_LD_OFFSET (GET_MODE (x))))
5420 rtx xx = XEXP (XEXP (x,0), 0);
5421 int regno = REGNO (xx);
5422 if (TARGET_ALL_DEBUG)
5424 fprintf (stderr, ("extra_constraint:\n"
5425 "reload_completed: %d\n"
5426 "reload_in_progress: %d\n"),
5427 reload_completed, reload_in_progress);
5428 debug_rtx (x);
5430 if (regno >= FIRST_PSEUDO_REGISTER)
5431 return 1; /* allocate pseudos */
5432 else if (regno == REG_Z || regno == REG_Y)
5433 return 1; /* strictly check */
5434 else if (xx == frame_pointer_rtx
5435 || xx == arg_pointer_rtx)
5436 return 1; /* XXX frame & arg pointer checks */
5439 return 0;
5442 /* Convert condition code CONDITION to the valid AVR condition code. */
5444 RTX_CODE
5445 avr_normalize_condition (RTX_CODE condition)
5447 switch (condition)
5449 case GT:
5450 return GE;
5451 case GTU:
5452 return GEU;
5453 case LE:
5454 return LT;
5455 case LEU:
5456 return LTU;
5457 default:
5458 abort ();
5462 /* This function optimizes conditional jumps. */
5464 static void
5465 avr_reorg (void)
5467 rtx insn, pattern;
5469 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5471 if (! (GET_CODE (insn) == INSN
5472 || GET_CODE (insn) == CALL_INSN
5473 || GET_CODE (insn) == JUMP_INSN)
5474 || !single_set (insn))
5475 continue;
5477 pattern = PATTERN (insn);
5479 if (GET_CODE (pattern) == PARALLEL)
5480 pattern = XVECEXP (pattern, 0, 0);
5481 if (GET_CODE (pattern) == SET
5482 && SET_DEST (pattern) == cc0_rtx
5483 && compare_diff_p (insn))
5485 if (GET_CODE (SET_SRC (pattern)) == COMPARE)
5487 /* Now we work under compare insn. */
5489 pattern = SET_SRC (pattern);
5490 if (true_regnum (XEXP (pattern,0)) >= 0
5491 && true_regnum (XEXP (pattern,1)) >= 0 )
5493 rtx x = XEXP (pattern,0);
5494 rtx next = next_real_insn (insn);
5495 rtx pat = PATTERN (next);
5496 rtx src = SET_SRC (pat);
5497 rtx t = XEXP (src,0);
5498 PUT_CODE (t, swap_condition (GET_CODE (t)));
5499 XEXP (pattern,0) = XEXP (pattern,1);
5500 XEXP (pattern,1) = x;
5501 INSN_CODE (next) = -1;
5503 else if (true_regnum (XEXP (pattern,0)) >= 0
5504 && GET_CODE (XEXP (pattern,1)) == CONST_INT)
5506 rtx x = XEXP (pattern,1);
5507 rtx next = next_real_insn (insn);
5508 rtx pat = PATTERN (next);
5509 rtx src = SET_SRC (pat);
5510 rtx t = XEXP (src,0);
5511 enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
5513 if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
5515 XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
5516 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
5517 INSN_CODE (next) = -1;
5518 INSN_CODE (insn) = -1;
5522 else if (true_regnum (SET_SRC (pattern)) >= 0)
5524 /* This is a tst insn */
5525 rtx next = next_real_insn (insn);
5526 rtx pat = PATTERN (next);
5527 rtx src = SET_SRC (pat);
5528 rtx t = XEXP (src,0);
5530 PUT_CODE (t, swap_condition (GET_CODE (t)));
5531 SET_SRC (pattern) = gen_rtx_NEG (GET_MODE (SET_SRC (pattern)),
5532 SET_SRC (pattern));
5533 INSN_CODE (next) = -1;
5534 INSN_CODE (insn) = -1;
5540 /* Returns register number for function return value.*/
5543 avr_ret_register (void)
5545 return 24;
5548 /* Ceate an RTX representing the place where a
5549 library function returns a value of mode MODE. */
5552 avr_libcall_value (enum machine_mode mode)
5554 int offs = GET_MODE_SIZE (mode);
5555 if (offs < 2)
5556 offs = 2;
5557 return gen_rtx_REG (mode, RET_REGISTER + 2 - offs);
5560 /* Create an RTX representing the place where a
5561 function returns a value of data type VALTYPE. */
5564 avr_function_value (tree type, tree func ATTRIBUTE_UNUSED)
5566 unsigned int offs;
5568 if (TYPE_MODE (type) != BLKmode)
5569 return avr_libcall_value (TYPE_MODE (type));
5571 offs = int_size_in_bytes (type);
5572 if (offs < 2)
5573 offs = 2;
5574 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
5575 offs = GET_MODE_SIZE (SImode);
5576 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
5577 offs = GET_MODE_SIZE (DImode);
5579 return gen_rtx_REG (BLKmode, RET_REGISTER + 2 - offs);
5582 /* Returns nonzero if the number MASK has only one bit set. */
5585 mask_one_bit_p (HOST_WIDE_INT mask)
5587 int i;
5588 unsigned HOST_WIDE_INT n=mask;
5589 for (i = 0; i < 32; ++i)
5591 if (n & 0x80000000L)
5593 if (n & 0x7fffffffL)
5594 return 0;
5595 else
5596 return 32-i;
5598 n<<=1;
5600 return 0;
5604 /* Places additional restrictions on the register class to
5605 use when it is necessary to copy value X into a register
5606 in class CLASS. */
5608 enum reg_class
5609 preferred_reload_class (rtx x ATTRIBUTE_UNUSED, enum reg_class class)
5611 return class;
5615 test_hard_reg_class (enum reg_class class, rtx x)
5617 int regno = true_regnum (x);
5618 if (regno < 0)
5619 return 0;
5621 if (TEST_HARD_REG_CLASS (class, regno))
5622 return 1;
5624 return 0;
5629 jump_over_one_insn_p (rtx insn, rtx dest)
5631 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
5632 ? XEXP (dest, 0)
5633 : dest);
5634 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
5635 int dest_addr = INSN_ADDRESSES (uid);
5636 return dest_addr - jump_addr == get_attr_length (insn) + 1;
5639 /* Returns 1 if a value of mode MODE can be stored starting with hard
5640 register number REGNO. On the enhanced core, anything larger than
5641 1 byte must start in even numbered register for "movw" to work
5642 (this way we don't have to check for odd registers everywhere). */
5645 avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
5647 /* The only thing that can go into registers r28:r29 is a Pmode. */
5648 if (regno == REG_Y && mode == Pmode)
5649 return 1;
5651 /* Otherwise disallow all regno/mode combinations that span r28:r29. */
5652 if (regno <= (REG_Y + 1) && (regno + GET_MODE_SIZE (mode)) >= (REG_Y + 1))
5653 return 0;
5655 if (mode == QImode)
5656 return 1;
5658 /* Modes larger than QImode occupy consecutive registers. */
5659 if (regno + GET_MODE_SIZE (mode) > FIRST_PSEUDO_REGISTER)
5660 return 0;
5662 /* All modes larger than QImode should start in an even register. */
5663 return !(regno & 1);
5666 /* Returns 1 if X is a valid address for an I/O register of size SIZE
5667 (1 or 2). Used for lds/sts -> in/out optimization. Add 0x20 to SIZE
5668 to check for the lower half of I/O space (for cbi/sbi/sbic/sbis). */
5671 avr_io_address_p (rtx x, int size)
5673 return (optimize > 0 && GET_CODE (x) == CONST_INT
5674 && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size);
5677 /* Returns nonzero (bit number + 1) if X, or -X, is a constant power of 2. */
5680 const_int_pow2_p (rtx x)
5682 if (GET_CODE (x) == CONST_INT)
5684 HOST_WIDE_INT d = INTVAL (x);
5685 HOST_WIDE_INT abs_d = (d >= 0) ? d : -d;
5686 return exact_log2 (abs_d) + 1;
5688 return 0;
5691 const char *
5692 output_reload_inhi (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
5694 int tmp;
5695 if (!len)
5696 len = &tmp;
5698 if (GET_CODE (operands[1]) == CONST_INT)
5700 int val = INTVAL (operands[1]);
5701 if ((val & 0xff) == 0)
5703 *len = 3;
5704 return (AS2 (mov,%A0,__zero_reg__) CR_TAB
5705 AS2 (ldi,%2,hi8(%1)) CR_TAB
5706 AS2 (mov,%B0,%2));
5708 else if ((val & 0xff00) == 0)
5710 *len = 3;
5711 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5712 AS2 (mov,%A0,%2) CR_TAB
5713 AS2 (mov,%B0,__zero_reg__));
5715 else if ((val & 0xff) == ((val & 0xff00) >> 8))
5717 *len = 3;
5718 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5719 AS2 (mov,%A0,%2) CR_TAB
5720 AS2 (mov,%B0,%2));
5723 *len = 4;
5724 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5725 AS2 (mov,%A0,%2) CR_TAB
5726 AS2 (ldi,%2,hi8(%1)) CR_TAB
5727 AS2 (mov,%B0,%2));
5731 const char *
5732 output_reload_insisf (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
5734 rtx src = operands[1];
5735 int cnst = (GET_CODE (src) == CONST_INT);
5737 if (len)
5739 if (cnst)
5740 *len = 4 + ((INTVAL (src) & 0xff) != 0)
5741 + ((INTVAL (src) & 0xff00) != 0)
5742 + ((INTVAL (src) & 0xff0000) != 0)
5743 + ((INTVAL (src) & 0xff000000) != 0);
5744 else
5745 *len = 8;
5747 return "";
5750 if (cnst && ((INTVAL (src) & 0xff) == 0))
5751 output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
5752 else
5754 output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
5755 output_asm_insn (AS2 (mov, %A0, %2), operands);
5757 if (cnst && ((INTVAL (src) & 0xff00) == 0))
5758 output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
5759 else
5761 output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
5762 output_asm_insn (AS2 (mov, %B0, %2), operands);
5764 if (cnst && ((INTVAL (src) & 0xff0000) == 0))
5765 output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
5766 else
5768 output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
5769 output_asm_insn (AS2 (mov, %C0, %2), operands);
5771 if (cnst && ((INTVAL (src) & 0xff000000) == 0))
5772 output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
5773 else
5775 output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
5776 output_asm_insn (AS2 (mov, %D0, %2), operands);
5778 return "";
5781 void
5782 avr_output_bld (rtx operands[], int bit_nr)
5784 static char s[] = "bld %A0,0";
5786 s[5] = 'A' + (bit_nr >> 3);
5787 s[8] = '0' + (bit_nr & 7);
5788 output_asm_insn (s, operands);
5791 void
5792 avr_output_addr_vec_elt (FILE *stream, int value)
5794 if (AVR_MEGA)
5795 fprintf (stream, "\t.word pm(.L%d)\n", value);
5796 else
5797 fprintf (stream, "\trjmp .L%d\n", value);
5799 jump_tables_size++;
5802 /* Returns 1 if SCRATCH are safe to be allocated as a scratch
5803 registers (for a define_peephole2) in the current function. */
5806 avr_peep2_scratch_safe (rtx scratch)
5808 if ((interrupt_function_p (current_function_decl)
5809 || signal_function_p (current_function_decl))
5810 && leaf_function_p ())
5812 int first_reg = true_regnum (scratch);
5813 int last_reg = first_reg + GET_MODE_SIZE (GET_MODE (scratch)) - 1;
5814 int reg;
5816 for (reg = first_reg; reg <= last_reg; reg++)
5818 if (!regs_ever_live[reg])
5819 return 0;
5822 return 1;
5825 /* Output a branch that tests a single bit of a register (QI, HI or SImode)
5826 or memory location in the I/O space (QImode only).
5828 Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
5829 Operand 1: register operand to test, or CONST_INT memory address.
5830 Operand 2: bit number (for QImode operand) or mask (HImode, SImode).
5831 Operand 3: label to jump to if the test is true. */
5833 const char *
5834 avr_out_sbxx_branch (rtx insn, rtx operands[])
5836 enum rtx_code comp = GET_CODE (operands[0]);
5837 int long_jump = (get_attr_length (insn) >= 4);
5838 int reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
5840 if (comp == GE)
5841 comp = EQ;
5842 else if (comp == LT)
5843 comp = NE;
5845 if (reverse)
5846 comp = reverse_condition (comp);
5848 if (GET_CODE (operands[1]) == CONST_INT)
5850 if (INTVAL (operands[1]) < 0x40)
5852 if (comp == EQ)
5853 output_asm_insn (AS2 (sbis,%1-0x20,%2), operands);
5854 else
5855 output_asm_insn (AS2 (sbic,%1-0x20,%2), operands);
5857 else
5859 output_asm_insn (AS2 (in,__tmp_reg__,%1-0x20), operands);
5860 if (comp == EQ)
5861 output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands);
5862 else
5863 output_asm_insn (AS2 (sbrc,__tmp_reg__,%2), operands);
5866 else /* GET_CODE (operands[1]) == REG */
5868 if (GET_MODE (operands[1]) == QImode)
5870 if (comp == EQ)
5871 output_asm_insn (AS2 (sbrs,%1,%2), operands);
5872 else
5873 output_asm_insn (AS2 (sbrc,%1,%2), operands);
5875 else /* HImode or SImode */
5877 static char buf[] = "sbrc %A1,0";
5878 int bit_nr = exact_log2 (INTVAL (operands[2])
5879 & GET_MODE_MASK (GET_MODE (operands[1])));
5881 buf[3] = (comp == EQ) ? 's' : 'c';
5882 buf[6] = 'A' + (bit_nr >> 3);
5883 buf[9] = '0' + (bit_nr & 7);
5884 output_asm_insn (buf, operands);
5888 if (long_jump)
5889 return (AS1 (rjmp,.+4) CR_TAB
5890 AS1 (jmp,%3));
5891 if (!reverse)
5892 return AS1 (rjmp,%3);
5893 return "";
5896 /* Worker function for TARGET_ASM_CONSTRUCTOR. */
5898 static void
5899 avr_asm_out_ctor (rtx symbol, int priority)
5901 fputs ("\t.global __do_global_ctors\n", asm_out_file);
5902 default_ctor_section_asm_out_constructor (symbol, priority);
5905 /* Worker function for TARGET_ASM_DESTRUCTOR. */
5907 static void
5908 avr_asm_out_dtor (rtx symbol, int priority)
5910 fputs ("\t.global __do_global_dtors\n", asm_out_file);
5911 default_dtor_section_asm_out_destructor (symbol, priority);
5914 /* Worker function for TARGET_RETURN_IN_MEMORY. */
5916 static bool
5917 avr_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
5919 if (TYPE_MODE (type) == BLKmode)
5921 HOST_WIDE_INT size = int_size_in_bytes (type);
5922 return (size == -1 || size > 8);
5924 else
5925 return false;
5928 #include "gt-avr.h"