re PR target/14599 (ieee/20000320-1.c fails for -mips16 using -O2 and above)
[official-gcc.git] / gcc / config / avr / avr.c
blob092f1da9e0307eca6fba241d9be340e732101c53
1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004
3 Free Software Foundation, Inc.
4 Contributed by Denis Chertykov (denisc@overta.ru)
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "real.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "insn-attr.h"
34 #include "flags.h"
35 #include "reload.h"
36 #include "tree.h"
37 #include "output.h"
38 #include "expr.h"
39 #include "toplev.h"
40 #include "obstack.h"
41 #include "function.h"
42 #include "recog.h"
43 #include "ggc.h"
44 #include "tm_p.h"
45 #include "target.h"
46 #include "target-def.h"
48 /* Maximal allowed offset for an address in the LD command */
49 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
51 static int avr_naked_function_p (tree);
52 static int interrupt_function_p (tree);
53 static int signal_function_p (tree);
54 static int avr_regs_to_save (HARD_REG_SET *);
55 static int sequent_regs_live (void);
56 static const char *ptrreg_to_str (int);
57 static const char *cond_string (enum rtx_code);
58 static int avr_num_arg_regs (enum machine_mode, tree);
59 static int out_adj_frame_ptr (FILE *, int);
60 static int out_set_stack_ptr (FILE *, int, int);
61 static RTX_CODE compare_condition (rtx insn);
62 static int compare_sign_p (rtx insn);
63 static tree avr_handle_progmem_attribute (tree *, tree, tree, int, bool *);
64 static tree avr_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
65 const struct attribute_spec avr_attribute_table[];
66 static bool avr_assemble_integer (rtx, unsigned int, int);
67 static void avr_file_start (void);
68 static void avr_file_end (void);
69 static void avr_output_function_prologue (FILE *, HOST_WIDE_INT);
70 static void avr_output_function_epilogue (FILE *, HOST_WIDE_INT);
71 static void avr_unique_section (tree, int);
72 static void avr_insert_attributes (tree, tree *);
73 static unsigned int avr_section_type_flags (tree, const char *, int);
75 static void avr_reorg (void);
76 static void avr_asm_out_ctor (rtx, int);
77 static void avr_asm_out_dtor (rtx, int);
78 static int default_rtx_costs (rtx, enum rtx_code, enum rtx_code);
79 static bool avr_rtx_costs (rtx, int, int, int *);
80 static int avr_address_cost (rtx);
81 static bool avr_return_in_memory (tree, tree);
83 /* Allocate registers from r25 to r8 for parameters for function calls. */
84 #define FIRST_CUM_REG 26
86 /* Temporary register RTX (gen_rtx_REG (QImode, TMP_REGNO)) */
87 static GTY(()) rtx tmp_reg_rtx;
89 /* Zeroed register RTX (gen_rtx_REG (QImode, ZERO_REGNO)) */
90 static GTY(()) rtx zero_reg_rtx;
92 /* AVR register names {"r0", "r1", ..., "r31"} */
93 static const char *const avr_regnames[] = REGISTER_NAMES;
95 /* This holds the last insn address. */
96 static int last_insn_address = 0;
98 /* Commands count in the compiled file */
99 static int commands_in_file;
101 /* Commands in the functions prologues in the compiled file */
102 static int commands_in_prologues;
104 /* Commands in the functions epilogues in the compiled file */
105 static int commands_in_epilogues;
107 /* Prologue/Epilogue size in words */
108 static int prologue_size;
109 static int epilogue_size;
111 /* Size of all jump tables in the current function, in words. */
112 static int jump_tables_size;
114 /* Initial stack value specified by the `-minit-stack=' option */
115 const char *avr_init_stack = "__stack";
117 /* Default MCU name */
118 const char *avr_mcu_name = "avr2";
120 /* Preprocessor macros to define depending on MCU type. */
121 const char *avr_base_arch_macro;
122 const char *avr_extra_arch_macro;
124 /* More than 8K of program memory: use "call" and "jmp". */
125 int avr_mega_p = 0;
127 /* Enhanced core: use "movw", "mul", ... */
128 int avr_enhanced_p = 0;
130 /* Assembler only. */
131 int avr_asm_only_p = 0;
133 struct base_arch_s {
134 int asm_only;
135 int enhanced;
136 int mega;
137 const char *const macro;
140 static const struct base_arch_s avr_arch_types[] = {
141 { 1, 0, 0, NULL }, /* unknown device specified */
142 { 1, 0, 0, "__AVR_ARCH__=1" },
143 { 0, 0, 0, "__AVR_ARCH__=2" },
144 { 0, 0, 1, "__AVR_ARCH__=3" },
145 { 0, 1, 0, "__AVR_ARCH__=4" },
146 { 0, 1, 1, "__AVR_ARCH__=5" }
149 struct mcu_type_s {
150 const char *const name;
151 int arch; /* index in avr_arch_types[] */
152 /* Must lie outside user's namespace. NULL == no macro. */
153 const char *const macro;
156 /* List of all known AVR MCU types - if updated, it has to be kept
157 in sync in several places (FIXME: is there a better way?):
158 - here
159 - avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
160 - t-avr (MULTILIB_MATCHES)
161 - gas/config/tc-avr.c
162 - avr-libc */
164 static const struct mcu_type_s avr_mcu_types[] = {
165 /* Classic, <= 8K. */
166 { "avr2", 2, NULL },
167 { "at90s2313", 2, "__AVR_AT90S2313__" },
168 { "at90s2323", 2, "__AVR_AT90S2323__" },
169 { "at90s2333", 2, "__AVR_AT90S2333__" },
170 { "at90s2343", 2, "__AVR_AT90S2343__" },
171 { "attiny22", 2, "__AVR_ATtiny22__" },
172 { "attiny26", 2, "__AVR_ATtiny26__" },
173 { "at90s4414", 2, "__AVR_AT90S4414__" },
174 { "at90s4433", 2, "__AVR_AT90S4433__" },
175 { "at90s4434", 2, "__AVR_AT90S4434__" },
176 { "at90s8515", 2, "__AVR_AT90S8515__" },
177 { "at90c8534", 2, "__AVR_AT90C8534__" },
178 { "at90s8535", 2, "__AVR_AT90S8535__" },
179 { "at86rf401", 2, "__AVR_AT86RF401__" },
180 /* Classic, > 8K. */
181 { "avr3", 3, NULL },
182 { "atmega103", 3, "__AVR_ATmega103__" },
183 { "atmega603", 3, "__AVR_ATmega603__" },
184 { "at43usb320", 3, "__AVR_AT43USB320__" },
185 { "at43usb355", 3, "__AVR_AT43USB355__" },
186 { "at76c711", 3, "__AVR_AT76C711__" },
187 /* Enhanced, <= 8K. */
188 { "avr4", 4, NULL },
189 { "atmega8", 4, "__AVR_ATmega8__" },
190 { "atmega8515", 4, "__AVR_ATmega8515__" },
191 { "atmega8535", 4, "__AVR_ATmega8535__" },
192 /* Enhanced, > 8K. */
193 { "avr5", 5, NULL },
194 { "atmega16", 5, "__AVR_ATmega16__" },
195 { "atmega161", 5, "__AVR_ATmega161__" },
196 { "atmega162", 5, "__AVR_ATmega162__" },
197 { "atmega163", 5, "__AVR_ATmega163__" },
198 { "atmega169", 5, "__AVR_ATmega169__" },
199 { "atmega32", 5, "__AVR_ATmega32__" },
200 { "atmega323", 5, "__AVR_ATmega323__" },
201 { "atmega64", 5, "__AVR_ATmega64__" },
202 { "atmega128", 5, "__AVR_ATmega128__" },
203 { "at94k", 5, "__AVR_AT94K__" },
204 /* Assembler only. */
205 { "avr1", 1, NULL },
206 { "at90s1200", 1, "__AVR_AT90S1200__" },
207 { "attiny11", 1, "__AVR_ATtiny11__" },
208 { "attiny12", 1, "__AVR_ATtiny12__" },
209 { "attiny15", 1, "__AVR_ATtiny15__" },
210 { "attiny28", 1, "__AVR_ATtiny28__" },
211 { NULL, 0, NULL }
214 int avr_case_values_threshold = 30000;
216 /* Initialize the GCC target structure. */
217 #undef TARGET_ASM_ALIGNED_HI_OP
218 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
219 #undef TARGET_ASM_INTEGER
220 #define TARGET_ASM_INTEGER avr_assemble_integer
221 #undef TARGET_ASM_FILE_START
222 #define TARGET_ASM_FILE_START avr_file_start
223 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
224 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
225 #undef TARGET_ASM_FILE_END
226 #define TARGET_ASM_FILE_END avr_file_end
228 #undef TARGET_ASM_FUNCTION_PROLOGUE
229 #define TARGET_ASM_FUNCTION_PROLOGUE avr_output_function_prologue
230 #undef TARGET_ASM_FUNCTION_EPILOGUE
231 #define TARGET_ASM_FUNCTION_EPILOGUE avr_output_function_epilogue
232 #undef TARGET_ATTRIBUTE_TABLE
233 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
234 #undef TARGET_ASM_UNIQUE_SECTION
235 #define TARGET_ASM_UNIQUE_SECTION avr_unique_section
236 #undef TARGET_INSERT_ATTRIBUTES
237 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
238 #undef TARGET_SECTION_TYPE_FLAGS
239 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
240 #undef TARGET_RTX_COSTS
241 #define TARGET_RTX_COSTS avr_rtx_costs
242 #undef TARGET_ADDRESS_COST
243 #define TARGET_ADDRESS_COST avr_address_cost
244 #undef TARGET_MACHINE_DEPENDENT_REORG
245 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
247 #undef TARGET_RETURN_IN_MEMORY
248 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
250 #undef TARGET_STRICT_ARGUMENT_NAMING
251 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
253 struct gcc_target targetm = TARGET_INITIALIZER;
255 void
256 avr_override_options (void)
258 const struct mcu_type_s *t;
259 const struct base_arch_s *base;
261 for (t = avr_mcu_types; t->name; t++)
262 if (strcmp (t->name, avr_mcu_name) == 0)
263 break;
265 if (!t->name)
267 fprintf (stderr, "unknown MCU `%s' specified\nKnown MCU names:\n",
268 avr_mcu_name);
269 for (t = avr_mcu_types; t->name; t++)
270 fprintf (stderr," %s\n", t->name);
273 base = &avr_arch_types[t->arch];
274 avr_asm_only_p = base->asm_only;
275 avr_enhanced_p = base->enhanced;
276 avr_mega_p = base->mega;
277 avr_base_arch_macro = base->macro;
278 avr_extra_arch_macro = t->macro;
280 if (optimize && !TARGET_NO_TABLEJUMP)
281 avr_case_values_threshold = (!AVR_MEGA || TARGET_CALL_PROLOGUES) ? 8 : 17;
283 tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO);
284 zero_reg_rtx = gen_rtx_REG (QImode, ZERO_REGNO);
287 /* return register class from register number. */
289 static const int reg_class_tab[]={
290 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
291 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
292 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
293 GENERAL_REGS, /* r0 - r15 */
294 LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
295 LD_REGS, /* r16 - 23 */
296 ADDW_REGS,ADDW_REGS, /* r24,r25 */
297 POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
298 POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
299 POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
300 STACK_REG,STACK_REG /* SPL,SPH */
303 /* Return register class for register R. */
305 enum reg_class
306 avr_regno_reg_class (int r)
308 if (r <= 33)
309 return reg_class_tab[r];
310 return ALL_REGS;
314 /* A C expression which defines the machine-dependent operand
315 constraint letters for register classes. If C is such a
316 letter, the value should be the register class corresponding to
317 it. Otherwise, the value should be `NO_REGS'. The register
318 letter `r', corresponding to class `GENERAL_REGS', will not be
319 passed to this macro; you do not need to handle it. */
321 enum reg_class
322 avr_reg_class_from_letter (int c)
324 switch (c)
326 case 't' : return R0_REG;
327 case 'b' : return BASE_POINTER_REGS;
328 case 'e' : return POINTER_REGS;
329 case 'w' : return ADDW_REGS;
330 case 'd' : return LD_REGS;
331 case 'l' : return NO_LD_REGS;
332 case 'a' : return SIMPLE_LD_REGS;
333 case 'x' : return POINTER_X_REGS;
334 case 'y' : return POINTER_Y_REGS;
335 case 'z' : return POINTER_Z_REGS;
336 case 'q' : return STACK_REG;
337 default: break;
339 return NO_REGS;
342 /* Return nonzero if FUNC is a naked function. */
344 static int
345 avr_naked_function_p (tree func)
347 tree a;
349 if (TREE_CODE (func) != FUNCTION_DECL)
350 abort ();
352 a = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
353 return a != NULL_TREE;
356 /* Return nonzero if FUNC is an interrupt function as specified
357 by the "interrupt" attribute. */
359 static int
360 interrupt_function_p (tree func)
362 tree a;
364 if (TREE_CODE (func) != FUNCTION_DECL)
365 return 0;
367 a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
368 return a != NULL_TREE;
371 /* Return nonzero if FUNC is a signal function as specified
372 by the "signal" attribute. */
374 static int
375 signal_function_p (tree func)
377 tree a;
379 if (TREE_CODE (func) != FUNCTION_DECL)
380 return 0;
382 a = lookup_attribute ("signal", DECL_ATTRIBUTES (func));
383 return a != NULL_TREE;
386 /* Return the number of hard registers to push/pop in the prologue/epilogue
387 of the current function, and optionally store these registers in SET. */
389 static int
390 avr_regs_to_save (HARD_REG_SET *set)
392 int reg, count;
393 int int_or_sig_p = (interrupt_function_p (current_function_decl)
394 || signal_function_p (current_function_decl));
395 int leaf_func_p = leaf_function_p ();
397 if (set)
398 CLEAR_HARD_REG_SET (*set);
399 count = 0;
401 /* No need to save any registers if the function never returns. */
402 if (TREE_THIS_VOLATILE (current_function_decl))
403 return 0;
405 for (reg = 0; reg < 32; reg++)
407 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
408 any global register variables. */
409 if (fixed_regs[reg])
410 continue;
412 if ((int_or_sig_p && !leaf_func_p && call_used_regs[reg])
413 || (regs_ever_live[reg]
414 && (int_or_sig_p || !call_used_regs[reg])
415 && !(frame_pointer_needed
416 && (reg == REG_Y || reg == (REG_Y+1)))))
418 if (set)
419 SET_HARD_REG_BIT (*set, reg);
420 count++;
423 return count;
426 /* Compute offset between arg_pointer and frame_pointer. */
429 initial_elimination_offset (int from, int to)
431 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
432 return 0;
433 else
435 int offset = frame_pointer_needed ? 2 : 0;
437 offset += avr_regs_to_save (NULL);
438 return get_frame_size () + 2 + 1 + offset;
442 /* Return 1 if the function epilogue is just a single "ret". */
445 avr_simple_epilogue (void)
447 return (! frame_pointer_needed
448 && get_frame_size () == 0
449 && avr_regs_to_save (NULL) == 0
450 && ! interrupt_function_p (current_function_decl)
451 && ! signal_function_p (current_function_decl)
452 && ! avr_naked_function_p (current_function_decl)
453 && ! MAIN_NAME_P (DECL_NAME (current_function_decl))
454 && ! TREE_THIS_VOLATILE (current_function_decl));
457 /* This function checks sequence of live registers. */
459 static int
460 sequent_regs_live (void)
462 int reg;
463 int live_seq=0;
464 int cur_seq=0;
466 for (reg = 0; reg < 18; ++reg)
468 if (!call_used_regs[reg])
470 if (regs_ever_live[reg])
472 ++live_seq;
473 ++cur_seq;
475 else
476 cur_seq = 0;
480 if (!frame_pointer_needed)
482 if (regs_ever_live[REG_Y])
484 ++live_seq;
485 ++cur_seq;
487 else
488 cur_seq = 0;
490 if (regs_ever_live[REG_Y+1])
492 ++live_seq;
493 ++cur_seq;
495 else
496 cur_seq = 0;
498 else
500 cur_seq += 2;
501 live_seq += 2;
503 return (cur_seq == live_seq) ? live_seq : 0;
507 /* Output to FILE the asm instructions to adjust the frame pointer by
508 ADJ (r29:r28 -= ADJ;) which can be positive (prologue) or negative
509 (epilogue). Returns the number of instructions generated. */
511 static int
512 out_adj_frame_ptr (FILE *file, int adj)
514 int size = 0;
516 if (adj)
518 if (TARGET_TINY_STACK)
520 if (adj < -63 || adj > 63)
521 warning ("large frame pointer change (%d) with -mtiny-stack", adj);
523 /* The high byte (r29) doesn't change - prefer "subi" (1 cycle)
524 over "sbiw" (2 cycles, same size). */
526 fprintf (file, (AS2 (subi, r28, %d) CR_TAB), adj);
527 size++;
529 else if (adj < -63 || adj > 63)
531 fprintf (file, (AS2 (subi, r28, lo8(%d)) CR_TAB
532 AS2 (sbci, r29, hi8(%d)) CR_TAB),
533 adj, adj);
534 size += 2;
536 else if (adj < 0)
538 fprintf (file, (AS2 (adiw, r28, %d) CR_TAB), -adj);
539 size++;
541 else
543 fprintf (file, (AS2 (sbiw, r28, %d) CR_TAB), adj);
544 size++;
547 return size;
551 /* Output to FILE the asm instructions to copy r29:r28 to SPH:SPL,
552 handling various cases of interrupt enable flag state BEFORE and AFTER
553 (0=disabled, 1=enabled, -1=unknown/unchanged) and target_flags.
554 Returns the number of instructions generated. */
556 static int
557 out_set_stack_ptr (FILE *file, int before, int after)
559 int do_sph, do_cli, do_save, do_sei, lock_sph, size;
561 /* The logic here is so that -mno-interrupts actually means
562 "it is safe to write SPH in one instruction, then SPL in the
563 next instruction, without disabling interrupts first".
564 The after != -1 case (interrupt/signal) is not affected. */
566 do_sph = !TARGET_TINY_STACK;
567 lock_sph = do_sph && !TARGET_NO_INTERRUPTS;
568 do_cli = (before != 0 && (after == 0 || lock_sph));
569 do_save = (do_cli && before == -1 && after == -1);
570 do_sei = ((do_cli || before != 1) && after == 1);
571 size = 1;
573 if (do_save)
575 fprintf (file, AS2 (in, __tmp_reg__, __SREG__) CR_TAB);
576 size++;
579 if (do_cli)
581 fprintf (file, "cli" CR_TAB);
582 size++;
585 /* Do SPH first - maybe this will disable interrupts for one instruction
586 someday (a suggestion has been sent to avr@atmel.com for consideration
587 in future devices - that would make -mno-interrupts always safe). */
588 if (do_sph)
590 fprintf (file, AS2 (out, __SP_H__, r29) CR_TAB);
591 size++;
594 /* Set/restore the I flag now - interrupts will be really enabled only
595 after the next instruction. This is not clearly documented, but
596 believed to be true for all AVR devices. */
597 if (do_save)
599 fprintf (file, AS2 (out, __SREG__, __tmp_reg__) CR_TAB);
600 size++;
602 else if (do_sei)
604 fprintf (file, "sei" CR_TAB);
605 size++;
608 fprintf (file, AS2 (out, __SP_L__, r28) "\n");
610 return size;
614 /* Output function prologue. */
616 static void
617 avr_output_function_prologue (FILE *file, HOST_WIDE_INT size)
619 int reg;
620 int interrupt_func_p;
621 int signal_func_p;
622 int main_p;
623 int live_seq;
624 int minimize;
626 last_insn_address = 0;
627 jump_tables_size = 0;
628 prologue_size = 0;
629 fprintf (file, "/* prologue: frame size=" HOST_WIDE_INT_PRINT_DEC " */\n",
630 size);
632 if (avr_naked_function_p (current_function_decl))
634 fputs ("/* prologue: naked */\n", file);
635 goto out;
638 interrupt_func_p = interrupt_function_p (current_function_decl);
639 signal_func_p = signal_function_p (current_function_decl);
640 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
641 live_seq = sequent_regs_live ();
642 minimize = (TARGET_CALL_PROLOGUES
643 && !interrupt_func_p && !signal_func_p && live_seq);
645 if (interrupt_func_p)
647 fprintf (file,"\tsei\n");
648 ++prologue_size;
650 if (interrupt_func_p || signal_func_p)
652 fprintf (file, "\t"
653 AS1 (push,__zero_reg__) CR_TAB
654 AS1 (push,__tmp_reg__) CR_TAB
655 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
656 AS1 (push,__tmp_reg__) CR_TAB
657 AS1 (clr,__zero_reg__) "\n");
658 prologue_size += 5;
660 if (main_p)
662 fprintf (file, ("\t"
663 AS1 (ldi,r28) ",lo8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
664 AS1 (ldi,r29) ",hi8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
665 AS2 (out,__SP_H__,r29) CR_TAB
666 AS2 (out,__SP_L__,r28) "\n"),
667 avr_init_stack, size, avr_init_stack, size);
669 prologue_size += 4;
671 else if (minimize && (frame_pointer_needed || live_seq > 6))
673 const char *cfun_name = current_function_name ();
674 fprintf (file, ("\t"
675 AS1 (ldi, r26) ",lo8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
676 AS1 (ldi, r27) ",hi8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB), size, size);
678 fprintf (file, (AS2 (ldi, r30, pm_lo8(.L_%s_body)) CR_TAB
679 AS2 (ldi, r31, pm_hi8(.L_%s_body)) CR_TAB),
680 cfun_name, cfun_name);
682 prologue_size += 4;
684 if (AVR_MEGA)
686 fprintf (file, AS1 (jmp,__prologue_saves__+%d) "\n",
687 (18 - live_seq) * 2);
688 prologue_size += 2;
690 else
692 fprintf (file, AS1 (rjmp,__prologue_saves__+%d) "\n",
693 (18 - live_seq) * 2);
694 ++prologue_size;
696 fprintf (file, ".L_%s_body:\n", cfun_name);
698 else
700 HARD_REG_SET set;
702 prologue_size += avr_regs_to_save (&set);
703 for (reg = 0; reg < 32; ++reg)
705 if (TEST_HARD_REG_BIT (set, reg))
707 fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
710 if (frame_pointer_needed)
712 fprintf (file, "\t"
713 AS1 (push,r28) CR_TAB
714 AS1 (push,r29) CR_TAB
715 AS2 (in,r28,__SP_L__) CR_TAB
716 AS2 (in,r29,__SP_H__) "\n");
717 prologue_size += 4;
718 if (size)
720 fputs ("\t", file);
721 prologue_size += out_adj_frame_ptr (file, size);
723 if (interrupt_func_p)
725 prologue_size += out_set_stack_ptr (file, 1, 1);
727 else if (signal_func_p)
729 prologue_size += out_set_stack_ptr (file, 0, 0);
731 else
733 prologue_size += out_set_stack_ptr (file, -1, -1);
739 out:
740 fprintf (file, "/* prologue end (size=%d) */\n", prologue_size);
743 /* Output function epilogue. */
745 static void
746 avr_output_function_epilogue (FILE *file, HOST_WIDE_INT size)
748 int reg;
749 int interrupt_func_p;
750 int signal_func_p;
751 int main_p;
752 int function_size;
753 int live_seq;
754 int minimize;
755 rtx last = get_last_nonnote_insn ();
757 function_size = jump_tables_size;
758 if (last)
760 rtx first = get_first_nonnote_insn ();
761 function_size += (INSN_ADDRESSES (INSN_UID (last)) -
762 INSN_ADDRESSES (INSN_UID (first)));
763 function_size += get_attr_length (last);
766 fprintf (file, "/* epilogue: frame size=" HOST_WIDE_INT_PRINT_DEC " */\n", size);
767 epilogue_size = 0;
769 if (avr_naked_function_p (current_function_decl))
771 fputs ("/* epilogue: naked */\n", file);
772 goto out;
775 if (last && GET_CODE (last) == BARRIER)
777 fputs ("/* epilogue: noreturn */\n", file);
778 goto out;
781 interrupt_func_p = interrupt_function_p (current_function_decl);
782 signal_func_p = signal_function_p (current_function_decl);
783 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
784 live_seq = sequent_regs_live ();
785 minimize = (TARGET_CALL_PROLOGUES
786 && !interrupt_func_p && !signal_func_p && live_seq);
788 if (main_p)
790 /* Return value from main() is already in the correct registers
791 (r25:r24) as the exit() argument. */
792 if (AVR_MEGA)
794 fputs ("\t" AS1 (jmp,exit) "\n", file);
795 epilogue_size += 2;
797 else
799 fputs ("\t" AS1 (rjmp,exit) "\n", file);
800 ++epilogue_size;
803 else if (minimize && (frame_pointer_needed || live_seq > 4))
805 fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
806 ++epilogue_size;
807 if (frame_pointer_needed)
809 epilogue_size += out_adj_frame_ptr (file, -size);
811 else
813 fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
814 AS2 (in , r29, __SP_H__) CR_TAB));
815 epilogue_size += 2;
818 if (AVR_MEGA)
820 fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
821 (18 - live_seq) * 2);
822 epilogue_size += 2;
824 else
826 fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
827 (18 - live_seq) * 2);
828 ++epilogue_size;
831 else
833 HARD_REG_SET set;
835 if (frame_pointer_needed)
837 if (size)
839 fputs ("\t", file);
840 epilogue_size += out_adj_frame_ptr (file, -size);
842 if (interrupt_func_p || signal_func_p)
844 epilogue_size += out_set_stack_ptr (file, -1, 0);
846 else
848 epilogue_size += out_set_stack_ptr (file, -1, -1);
851 fprintf (file, "\t"
852 AS1 (pop,r29) CR_TAB
853 AS1 (pop,r28) "\n");
854 epilogue_size += 2;
857 epilogue_size += avr_regs_to_save (&set);
858 for (reg = 31; reg >= 0; --reg)
860 if (TEST_HARD_REG_BIT (set, reg))
862 fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
866 if (interrupt_func_p || signal_func_p)
868 fprintf (file, "\t"
869 AS1 (pop,__tmp_reg__) CR_TAB
870 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
871 AS1 (pop,__tmp_reg__) CR_TAB
872 AS1 (pop,__zero_reg__) "\n");
873 epilogue_size += 4;
874 fprintf (file, "\treti\n");
876 else
877 fprintf (file, "\tret\n");
878 ++epilogue_size;
881 out:
882 fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
883 fprintf (file, "/* function %s size %d (%d) */\n", current_function_name (),
884 prologue_size + function_size + epilogue_size, function_size);
885 commands_in_file += prologue_size + function_size + epilogue_size;
886 commands_in_prologues += prologue_size;
887 commands_in_epilogues += epilogue_size;
891 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
892 machine for a memory operand of mode MODE. */
895 legitimate_address_p (enum machine_mode mode, rtx x, int strict)
897 enum reg_class r = NO_REGS;
899 if (TARGET_ALL_DEBUG)
901 fprintf (stderr, "mode: (%s) %s %s %s %s:",
902 GET_MODE_NAME(mode),
903 strict ? "(strict)": "",
904 reload_completed ? "(reload_completed)": "",
905 reload_in_progress ? "(reload_in_progress)": "",
906 reg_renumber ? "(reg_renumber)" : "");
907 if (GET_CODE (x) == PLUS
908 && REG_P (XEXP (x, 0))
909 && GET_CODE (XEXP (x, 1)) == CONST_INT
910 && INTVAL (XEXP (x, 1)) >= 0
911 && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
912 && reg_renumber
914 fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
915 true_regnum (XEXP (x, 0)));
916 debug_rtx (x);
918 if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
919 : REG_OK_FOR_BASE_NOSTRICT_P (x)))
920 r = POINTER_REGS;
921 else if (CONSTANT_ADDRESS_P (x))
922 r = ALL_REGS;
923 else if (GET_CODE (x) == PLUS
924 && REG_P (XEXP (x, 0))
925 && GET_CODE (XEXP (x, 1)) == CONST_INT
926 && INTVAL (XEXP (x, 1)) >= 0)
928 int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
929 if (fit)
931 if (! strict
932 || REGNO (XEXP (x,0)) == REG_Y
933 || REGNO (XEXP (x,0)) == REG_Z)
934 r = BASE_POINTER_REGS;
935 if (XEXP (x,0) == frame_pointer_rtx
936 || XEXP (x,0) == arg_pointer_rtx)
937 r = BASE_POINTER_REGS;
939 else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
940 r = POINTER_Y_REGS;
942 else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
943 && REG_P (XEXP (x, 0))
944 && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
945 : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
947 r = POINTER_REGS;
949 if (TARGET_ALL_DEBUG)
951 fprintf (stderr, " ret = %c\n", r);
953 return r == NO_REGS ? 0 : (int)r;
956 /* Attempts to replace X with a valid
957 memory address for an operand of mode MODE */
960 legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
962 x = oldx;
963 if (TARGET_ALL_DEBUG)
965 fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
966 debug_rtx (oldx);
969 if (GET_CODE (oldx) == PLUS
970 && REG_P (XEXP (oldx,0)))
972 if (REG_P (XEXP (oldx,1)))
973 x = force_reg (GET_MODE (oldx), oldx);
974 else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
976 int offs = INTVAL (XEXP (oldx,1));
977 if (frame_pointer_rtx != XEXP (oldx,0))
978 if (offs > MAX_LD_OFFSET (mode))
980 if (TARGET_ALL_DEBUG)
981 fprintf (stderr, "force_reg (big offset)\n");
982 x = force_reg (GET_MODE (oldx), oldx);
986 return x;
990 /* Return a pointer register name as a string. */
992 static const char *
993 ptrreg_to_str (int regno)
995 switch (regno)
997 case REG_X: return "X";
998 case REG_Y: return "Y";
999 case REG_Z: return "Z";
1000 default:
1001 abort ();
1003 return NULL;
1006 /* Return the condition name as a string.
1007 Used in conditional jump constructing */
1009 static const char *
1010 cond_string (enum rtx_code code)
1012 switch (code)
1014 case NE:
1015 return "ne";
1016 case EQ:
1017 return "eq";
1018 case GE:
1019 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1020 return "pl";
1021 else
1022 return "ge";
1023 case LT:
1024 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1025 return "mi";
1026 else
1027 return "lt";
1028 case GEU:
1029 return "sh";
1030 case LTU:
1031 return "lo";
1032 default:
1033 abort ();
1037 /* Output ADDR to FILE as address. */
1039 void
1040 print_operand_address (FILE *file, rtx addr)
1042 switch (GET_CODE (addr))
1044 case REG:
1045 fprintf (file, ptrreg_to_str (REGNO (addr)));
1046 break;
1048 case PRE_DEC:
1049 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1050 break;
1052 case POST_INC:
1053 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1054 break;
1056 default:
1057 if (CONSTANT_ADDRESS_P (addr)
1058 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (addr))
1059 || GET_CODE (addr) == LABEL_REF))
1061 fprintf (file, "pm(");
1062 output_addr_const (file,addr);
1063 fprintf (file ,")");
1065 else
1066 output_addr_const (file, addr);
1071 /* Output X as assembler operand to file FILE. */
1073 void
1074 print_operand (FILE *file, rtx x, int code)
1076 int abcd = 0;
1078 if (code >= 'A' && code <= 'D')
1079 abcd = code - 'A';
1081 if (code == '~')
1083 if (!AVR_MEGA)
1084 fputc ('r', file);
1086 else if (REG_P (x))
1088 if (x == zero_reg_rtx)
1089 fprintf (file, "__zero_reg__");
1090 else
1091 fprintf (file, reg_names[true_regnum (x) + abcd]);
1093 else if (GET_CODE (x) == CONST_INT)
1094 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd);
1095 else if (GET_CODE (x) == MEM)
1097 rtx addr = XEXP (x,0);
1099 if (CONSTANT_P (addr) && abcd)
1101 fputc ('(', file);
1102 output_address (addr);
1103 fprintf (file, ")+%d", abcd);
1105 else if (code == 'o')
1107 if (GET_CODE (addr) != PLUS)
1108 fatal_insn ("bad address, not (reg+disp):", addr);
1110 print_operand (file, XEXP (addr, 1), 0);
1112 else if (GET_CODE (addr) == PLUS)
1114 print_operand_address (file, XEXP (addr,0));
1115 if (REGNO (XEXP (addr, 0)) == REG_X)
1116 fatal_insn ("internal compiler error. Bad address:"
1117 ,addr);
1118 fputc ('+', file);
1119 print_operand (file, XEXP (addr,1), code);
1121 else
1122 print_operand_address (file, addr);
1124 else if (GET_CODE (x) == CONST_DOUBLE)
1126 long val;
1127 REAL_VALUE_TYPE rv;
1128 if (GET_MODE (x) != SFmode)
1129 fatal_insn ("internal compiler error. Unknown mode:", x);
1130 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1131 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1132 fprintf (file, "0x%lx", val);
1134 else if (code == 'j')
1135 fputs (cond_string (GET_CODE (x)), file);
1136 else if (code == 'k')
1137 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
1138 else
1139 print_operand_address (file, x);
1142 /* Recognize operand OP of mode MODE used in call instructions. */
1145 call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1147 if (GET_CODE (op) == MEM)
1149 rtx inside = XEXP (op, 0);
1150 if (register_operand (inside, Pmode))
1151 return 1;
1152 if (CONSTANT_ADDRESS_P (inside))
1153 return 1;
1155 return 0;
1158 /* Update the condition code in the INSN. */
1160 void
1161 notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
1163 rtx set;
1165 switch (get_attr_cc (insn))
1167 case CC_NONE:
1168 /* Insn does not affect CC at all. */
1169 break;
1171 case CC_SET_N:
1172 CC_STATUS_INIT;
1173 break;
1175 case CC_SET_ZN:
1176 set = single_set (insn);
1177 CC_STATUS_INIT;
1178 if (set)
1180 cc_status.flags |= CC_NO_OVERFLOW;
1181 cc_status.value1 = SET_DEST (set);
1183 break;
1185 case CC_SET_CZN:
1186 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1187 The V flag may or may not be known but that's ok because
1188 alter_cond will change tests to use EQ/NE. */
1189 set = single_set (insn);
1190 CC_STATUS_INIT;
1191 if (set)
1193 cc_status.value1 = SET_DEST (set);
1194 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1196 break;
1198 case CC_COMPARE:
1199 set = single_set (insn);
1200 CC_STATUS_INIT;
1201 if (set)
1202 cc_status.value1 = SET_SRC (set);
1203 break;
1205 case CC_CLOBBER:
1206 /* Insn doesn't leave CC in a usable state. */
1207 CC_STATUS_INIT;
1209 /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1210 set = single_set (insn);
1211 if (set)
1213 rtx src = SET_SRC (set);
1215 if (GET_CODE (src) == ASHIFTRT
1216 && GET_MODE (src) == QImode)
1218 rtx x = XEXP (src, 1);
1220 if (GET_CODE (x) == CONST_INT
1221 && INTVAL (x) != 6)
1223 cc_status.value1 = SET_DEST (set);
1224 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1228 break;
1232 /* Return maximum number of consecutive registers of
1233 class CLASS needed to hold a value of mode MODE. */
1236 class_max_nregs (enum reg_class class ATTRIBUTE_UNUSED,enum machine_mode mode)
1238 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1241 /* Choose mode for jump insn:
1242 1 - relative jump in range -63 <= x <= 62 ;
1243 2 - relative jump in range -2046 <= x <= 2045 ;
1244 3 - absolute jump (only for ATmega[16]03). */
1247 avr_jump_mode (rtx x, rtx insn)
1249 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1250 ? XEXP (x, 0) : x));
1251 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1252 int jump_distance = cur_addr - dest_addr;
1254 if (-63 <= jump_distance && jump_distance <= 62)
1255 return 1;
1256 else if (-2046 <= jump_distance && jump_distance <= 2045)
1257 return 2;
1258 else if (AVR_MEGA)
1259 return 3;
1261 return 2;
1264 /* return an AVR condition jump commands.
1265 X is a comparison RTX.
1266 LEN is a number returned by avr_jump_mode function.
1267 if REVERSE nonzero then condition code in X must be reversed. */
1269 const char *
1270 ret_cond_branch (rtx x, int len, int reverse)
1272 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1274 switch (cond)
1276 case GT:
1277 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1278 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1279 AS1 (brpl,%0)) :
1280 len == 2 ? (AS1 (breq,.+4) CR_TAB
1281 AS1 (brmi,.+2) CR_TAB
1282 AS1 (rjmp,%0)) :
1283 (AS1 (breq,.+6) CR_TAB
1284 AS1 (brmi,.+4) CR_TAB
1285 AS1 (jmp,%0)));
1287 else
1288 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1289 AS1 (brge,%0)) :
1290 len == 2 ? (AS1 (breq,.+4) CR_TAB
1291 AS1 (brlt,.+2) CR_TAB
1292 AS1 (rjmp,%0)) :
1293 (AS1 (breq,.+6) CR_TAB
1294 AS1 (brlt,.+4) CR_TAB
1295 AS1 (jmp,%0)));
1296 case GTU:
1297 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1298 AS1 (brsh,%0)) :
1299 len == 2 ? (AS1 (breq,.+4) CR_TAB
1300 AS1 (brlo,.+2) CR_TAB
1301 AS1 (rjmp,%0)) :
1302 (AS1 (breq,.+6) CR_TAB
1303 AS1 (brlo,.+4) CR_TAB
1304 AS1 (jmp,%0)));
1305 case LE:
1306 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1307 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1308 AS1 (brmi,%0)) :
1309 len == 2 ? (AS1 (breq,.+2) CR_TAB
1310 AS1 (brpl,.+2) CR_TAB
1311 AS1 (rjmp,%0)) :
1312 (AS1 (breq,.+2) CR_TAB
1313 AS1 (brpl,.+4) CR_TAB
1314 AS1 (jmp,%0)));
1315 else
1316 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1317 AS1 (brlt,%0)) :
1318 len == 2 ? (AS1 (breq,.+2) CR_TAB
1319 AS1 (brge,.+2) CR_TAB
1320 AS1 (rjmp,%0)) :
1321 (AS1 (breq,.+2) CR_TAB
1322 AS1 (brge,.+4) CR_TAB
1323 AS1 (jmp,%0)));
1324 case LEU:
1325 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1326 AS1 (brlo,%0)) :
1327 len == 2 ? (AS1 (breq,.+2) CR_TAB
1328 AS1 (brsh,.+2) CR_TAB
1329 AS1 (rjmp,%0)) :
1330 (AS1 (breq,.+2) CR_TAB
1331 AS1 (brsh,.+4) CR_TAB
1332 AS1 (jmp,%0)));
1333 default:
1334 if (reverse)
1336 switch (len)
1338 case 1:
1339 return AS1 (br%k1,%0);
1340 case 2:
1341 return (AS1 (br%j1,.+2) CR_TAB
1342 AS1 (rjmp,%0));
1343 default:
1344 return (AS1 (br%j1,.+4) CR_TAB
1345 AS1 (jmp,%0));
1348 else
1350 switch (len)
1352 case 1:
1353 return AS1 (br%j1,%0);
1354 case 2:
1355 return (AS1 (br%k1,.+2) CR_TAB
1356 AS1 (rjmp,%0));
1357 default:
1358 return (AS1 (br%k1,.+4) CR_TAB
1359 AS1 (jmp,%0));
1363 return "";
1366 /* Predicate function for immediate operand which fits to byte (8bit) */
1369 byte_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1371 return (GET_CODE (op) == CONST_INT
1372 && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1375 /* Output all insn addresses and their sizes into the assembly language
1376 output file. This is helpful for debugging whether the length attributes
1377 in the md file are correct.
1378 Output insn cost for next insn. */
1380 void
1381 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
1382 int num_operands ATTRIBUTE_UNUSED)
1384 int uid = INSN_UID (insn);
1386 if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1388 fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1389 INSN_ADDRESSES (uid),
1390 INSN_ADDRESSES (uid) - last_insn_address,
1391 rtx_cost (PATTERN (insn), INSN));
1393 last_insn_address = INSN_ADDRESSES (uid);
1396 /* Return 0 if undefined, 1 if always true or always false. */
1399 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE operator, rtx x)
1401 unsigned int max = (mode == QImode ? 0xff :
1402 mode == HImode ? 0xffff :
1403 mode == SImode ? 0xffffffff : 0);
1404 if (max && operator && GET_CODE (x) == CONST_INT)
1406 if (unsigned_condition (operator) != operator)
1407 max >>= 1;
1409 if (max != (INTVAL (x) & max)
1410 && INTVAL (x) != 0xff)
1411 return 1;
1413 return 0;
1417 /* Returns nonzero if REGNO is the number of a hard
1418 register in which function arguments are sometimes passed. */
1421 function_arg_regno_p(int r)
1423 return (r >= 8 && r <= 25);
1426 /* Initializing the variable cum for the state at the beginning
1427 of the argument list. */
1429 void
1430 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
1431 tree fndecl ATTRIBUTE_UNUSED)
1433 cum->nregs = 18;
1434 cum->regno = FIRST_CUM_REG;
1435 if (!libname && fntype)
1437 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1438 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1439 != void_type_node));
1440 if (stdarg)
1441 cum->nregs = 0;
1445 /* Returns the number of registers to allocate for a function argument. */
1447 static int
1448 avr_num_arg_regs (enum machine_mode mode, tree type)
1450 int size;
1452 if (mode == BLKmode)
1453 size = int_size_in_bytes (type);
1454 else
1455 size = GET_MODE_SIZE (mode);
1457 /* Align all function arguments to start in even-numbered registers.
1458 Odd-sized arguments leave holes above them. */
1460 return (size + 1) & ~1;
1463 /* Controls whether a function argument is passed
1464 in a register, and which register. */
1467 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1468 int named ATTRIBUTE_UNUSED)
1470 int bytes = avr_num_arg_regs (mode, type);
1472 if (cum->nregs && bytes <= cum->nregs)
1473 return gen_rtx_REG (mode, cum->regno - bytes);
1475 return NULL_RTX;
1478 /* Update the summarizer variable CUM to advance past an argument
1479 in the argument list. */
1481 void
1482 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1483 int named ATTRIBUTE_UNUSED)
1485 int bytes = avr_num_arg_regs (mode, type);
1487 cum->nregs -= bytes;
1488 cum->regno -= bytes;
1490 if (cum->nregs <= 0)
1492 cum->nregs = 0;
1493 cum->regno = FIRST_CUM_REG;
1497 /***********************************************************************
1498 Functions for outputting various mov's for a various modes
1499 ************************************************************************/
1500 const char *
1501 output_movqi (rtx insn, rtx operands[], int *l)
1503 int dummy;
1504 rtx dest = operands[0];
1505 rtx src = operands[1];
1506 int *real_l = l;
1508 if (!l)
1509 l = &dummy;
1511 *l = 1;
1513 if (register_operand (dest, QImode))
1515 if (register_operand (src, QImode)) /* mov r,r */
1517 if (test_hard_reg_class (STACK_REG, dest))
1518 return AS2 (out,%0,%1);
1519 else if (test_hard_reg_class (STACK_REG, src))
1520 return AS2 (in,%0,%1);
1522 return AS2 (mov,%0,%1);
1524 else if (CONSTANT_P (src))
1526 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1527 return AS2 (ldi,%0,lo8(%1));
1529 if (GET_CODE (src) == CONST_INT)
1531 if (src == const0_rtx) /* mov r,L */
1532 return AS1 (clr,%0);
1533 else if (src == const1_rtx)
1535 *l = 2;
1536 return (AS1 (clr,%0) CR_TAB
1537 AS1 (inc,%0));
1539 else if (src == constm1_rtx)
1541 /* Immediate constants -1 to any register */
1542 *l = 2;
1543 return (AS1 (clr,%0) CR_TAB
1544 AS1 (dec,%0));
1546 else
1548 int bit_nr = exact_log2 (INTVAL (src));
1550 if (bit_nr >= 0)
1552 *l = 3;
1553 if (!real_l)
1554 output_asm_insn ((AS1 (clr,%0) CR_TAB
1555 "set"), operands);
1556 if (!real_l)
1557 avr_output_bld (operands, bit_nr);
1559 return "";
1564 /* Last resort, larger than loading from memory. */
1565 *l = 4;
1566 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1567 AS2 (ldi,r31,lo8(%1)) CR_TAB
1568 AS2 (mov,%0,r31) CR_TAB
1569 AS2 (mov,r31,__tmp_reg__));
1571 else if (GET_CODE (src) == MEM)
1572 return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1574 else if (GET_CODE (dest) == MEM)
1576 const char *template;
1578 if (src == const0_rtx)
1579 operands[1] = zero_reg_rtx;
1581 template = out_movqi_mr_r (insn, operands, real_l);
1583 if (!real_l)
1584 output_asm_insn (template, operands);
1586 operands[1] = src;
1588 return "";
1592 const char *
1593 output_movhi (rtx insn, rtx operands[], int *l)
1595 int dummy;
1596 rtx dest = operands[0];
1597 rtx src = operands[1];
1598 int *real_l = l;
1600 if (!l)
1601 l = &dummy;
1603 if (register_operand (dest, HImode))
1605 if (register_operand (src, HImode)) /* mov r,r */
1607 if (test_hard_reg_class (STACK_REG, dest))
1609 if (TARGET_TINY_STACK)
1611 *l = 1;
1612 return AS2 (out,__SP_L__,%A1);
1614 else if (TARGET_NO_INTERRUPTS)
1616 *l = 2;
1617 return (AS2 (out,__SP_H__,%B1) CR_TAB
1618 AS2 (out,__SP_L__,%A1));
1621 *l = 5;
1622 return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB
1623 "cli" CR_TAB
1624 AS2 (out,__SP_H__,%B1) CR_TAB
1625 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1626 AS2 (out,__SP_L__,%A1));
1628 else if (test_hard_reg_class (STACK_REG, src))
1630 *l = 2;
1631 return (AS2 (in,%A0,__SP_L__) CR_TAB
1632 AS2 (in,%B0,__SP_H__));
1635 if (AVR_ENHANCED)
1637 *l = 1;
1638 return (AS2 (movw,%0,%1));
1641 if (true_regnum (dest) > true_regnum (src))
1643 *l = 2;
1644 return (AS2 (mov,%B0,%B1) CR_TAB
1645 AS2 (mov,%A0,%A1));
1647 else
1649 *l = 2;
1650 return (AS2 (mov,%A0,%A1) CR_TAB
1651 AS2 (mov,%B0,%B1));
1654 else if (CONSTANT_P (src))
1656 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1658 *l = 2;
1659 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1660 AS2 (ldi,%B0,hi8(%1)));
1663 if (GET_CODE (src) == CONST_INT)
1665 if (src == const0_rtx) /* mov r,L */
1667 *l = 2;
1668 return (AS1 (clr,%A0) CR_TAB
1669 AS1 (clr,%B0));
1671 else if (src == const1_rtx)
1673 *l = 3;
1674 return (AS1 (clr,%A0) CR_TAB
1675 AS1 (clr,%B0) CR_TAB
1676 AS1 (inc,%A0));
1678 else if (src == constm1_rtx)
1680 /* Immediate constants -1 to any register */
1681 *l = 3;
1682 return (AS1 (clr,%0) CR_TAB
1683 AS1 (dec,%A0) CR_TAB
1684 AS2 (mov,%B0,%A0));
1686 else
1688 int bit_nr = exact_log2 (INTVAL (src));
1690 if (bit_nr >= 0)
1692 *l = 4;
1693 if (!real_l)
1694 output_asm_insn ((AS1 (clr,%A0) CR_TAB
1695 AS1 (clr,%B0) CR_TAB
1696 "set"), operands);
1697 if (!real_l)
1698 avr_output_bld (operands, bit_nr);
1700 return "";
1704 if ((INTVAL (src) & 0xff) == 0)
1706 *l = 5;
1707 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1708 AS1 (clr,%A0) CR_TAB
1709 AS2 (ldi,r31,hi8(%1)) CR_TAB
1710 AS2 (mov,%B0,r31) CR_TAB
1711 AS2 (mov,r31,__tmp_reg__));
1713 else if ((INTVAL (src) & 0xff00) == 0)
1715 *l = 5;
1716 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1717 AS2 (ldi,r31,lo8(%1)) CR_TAB
1718 AS2 (mov,%A0,r31) CR_TAB
1719 AS1 (clr,%B0) CR_TAB
1720 AS2 (mov,r31,__tmp_reg__));
1724 /* Last resort, equal to loading from memory. */
1725 *l = 6;
1726 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1727 AS2 (ldi,r31,lo8(%1)) CR_TAB
1728 AS2 (mov,%A0,r31) CR_TAB
1729 AS2 (ldi,r31,hi8(%1)) CR_TAB
1730 AS2 (mov,%B0,r31) CR_TAB
1731 AS2 (mov,r31,__tmp_reg__));
1733 else if (GET_CODE (src) == MEM)
1734 return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1736 else if (GET_CODE (dest) == MEM)
1738 const char *template;
1740 if (src == const0_rtx)
1741 operands[1] = zero_reg_rtx;
1743 template = out_movhi_mr_r (insn, operands, real_l);
1745 if (!real_l)
1746 output_asm_insn (template, operands);
1748 operands[1] = src;
1749 return "";
1751 fatal_insn ("invalid insn:", insn);
1752 return "";
1755 const char *
1756 out_movqi_r_mr (rtx insn, rtx op[], int *l)
1758 rtx dest = op[0];
1759 rtx src = op[1];
1760 rtx x = XEXP (src, 0);
1761 int dummy;
1763 if (!l)
1764 l = &dummy;
1766 if (CONSTANT_ADDRESS_P (x))
1768 if (avr_io_address_p (x, 1))
1770 *l = 1;
1771 return AS2 (in,%0,%1-0x20);
1773 *l = 2;
1774 return AS2 (lds,%0,%1);
1776 /* memory access by reg+disp */
1777 else if (GET_CODE (x) == PLUS
1778 && REG_P (XEXP (x,0))
1779 && GET_CODE (XEXP (x,1)) == CONST_INT)
1781 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1783 int disp = INTVAL (XEXP (x,1));
1784 if (REGNO (XEXP (x,0)) != REG_Y)
1785 fatal_insn ("incorrect insn:",insn);
1787 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1788 return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
1789 AS2 (ldd,%0,Y+63) CR_TAB
1790 AS2 (sbiw,r28,%o1-63));
1792 return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1793 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1794 AS2 (ld,%0,Y) CR_TAB
1795 AS2 (subi,r28,lo8(%o1)) CR_TAB
1796 AS2 (sbci,r29,hi8(%o1)));
1798 else if (REGNO (XEXP (x,0)) == REG_X)
1800 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1801 it but I have this situation with extremal optimizing options. */
1802 if (reg_overlap_mentioned_p (dest, XEXP (x,0))
1803 || reg_unused_after (insn, XEXP (x,0)))
1804 return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
1805 AS2 (ld,%0,X));
1807 return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
1808 AS2 (ld,%0,X) CR_TAB
1809 AS2 (sbiw,r26,%o1));
1811 *l = 1;
1812 return AS2 (ldd,%0,%1);
1814 *l = 1;
1815 return AS2 (ld,%0,%1);
1818 const char *
1819 out_movhi_r_mr (rtx insn, rtx op[], int *l)
1821 rtx dest = op[0];
1822 rtx src = op[1];
1823 rtx base = XEXP (src, 0);
1824 int reg_dest = true_regnum (dest);
1825 int reg_base = true_regnum (base);
1826 int tmp;
1828 if (!l)
1829 l = &tmp;
1831 if (reg_base > 0)
1833 if (reg_dest == reg_base) /* R = (R) */
1835 *l = 3;
1836 return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1837 AS2 (ld,%B0,%1) CR_TAB
1838 AS2 (mov,%A0,__tmp_reg__));
1840 else if (reg_base == REG_X) /* (R26) */
1842 if (reg_unused_after (insn, base))
1844 *l = 2;
1845 return (AS2 (ld,%A0,X+) CR_TAB
1846 AS2 (ld,%B0,X));
1848 *l = 3;
1849 return (AS2 (ld,%A0,X+) CR_TAB
1850 AS2 (ld,%B0,X) CR_TAB
1851 AS2 (sbiw,r26,1));
1853 else /* (R) */
1855 *l = 2;
1856 return (AS2 (ld,%A0,%1) CR_TAB
1857 AS2 (ldd,%B0,%1+1));
1860 else if (GET_CODE (base) == PLUS) /* (R + i) */
1862 int disp = INTVAL (XEXP (base, 1));
1863 int reg_base = true_regnum (XEXP (base, 0));
1865 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
1867 if (REGNO (XEXP (base, 0)) != REG_Y)
1868 fatal_insn ("incorrect insn:",insn);
1870 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1871 return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
1872 AS2 (ldd,%A0,Y+62) CR_TAB
1873 AS2 (ldd,%B0,Y+63) CR_TAB
1874 AS2 (sbiw,r28,%o1-62));
1876 return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1877 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1878 AS2 (ld,%A0,Y) CR_TAB
1879 AS2 (ldd,%B0,Y+1) CR_TAB
1880 AS2 (subi,r28,lo8(%o1)) CR_TAB
1881 AS2 (sbci,r29,hi8(%o1)));
1883 if (reg_base == REG_X)
1885 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1886 it but I have this situation with extremal
1887 optimization options. */
1889 *l = 4;
1890 if (reg_base == reg_dest)
1891 return (AS2 (adiw,r26,%o1) CR_TAB
1892 AS2 (ld,__tmp_reg__,X+) CR_TAB
1893 AS2 (ld,%B0,X) CR_TAB
1894 AS2 (mov,%A0,__tmp_reg__));
1896 return (AS2 (adiw,r26,%o1) CR_TAB
1897 AS2 (ld,%A0,X+) CR_TAB
1898 AS2 (ld,%B0,X) CR_TAB
1899 AS2 (sbiw,r26,%o1+1));
1902 if (reg_base == reg_dest)
1904 *l = 3;
1905 return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
1906 AS2 (ldd,%B0,%B1) CR_TAB
1907 AS2 (mov,%A0,__tmp_reg__));
1910 *l = 2;
1911 return (AS2 (ldd,%A0,%A1) CR_TAB
1912 AS2 (ldd,%B0,%B1));
1914 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
1916 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1917 fatal_insn ("incorrect insn:", insn);
1919 *l = 2;
1920 return (AS2 (ld,%B0,%1) CR_TAB
1921 AS2 (ld,%A0,%1));
1923 else if (GET_CODE (base) == POST_INC) /* (R++) */
1925 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1926 fatal_insn ("incorrect insn:", insn);
1928 *l = 2;
1929 return (AS2 (ld,%A0,%1) CR_TAB
1930 AS2 (ld,%B0,%1));
1932 else if (CONSTANT_ADDRESS_P (base))
1934 if (avr_io_address_p (base, 2))
1936 *l = 2;
1937 return (AS2 (in,%A0,%A1-0x20) CR_TAB
1938 AS2 (in,%B0,%B1-0x20));
1940 *l = 4;
1941 return (AS2 (lds,%A0,%A1) CR_TAB
1942 AS2 (lds,%B0,%B1));
1945 fatal_insn ("unknown move insn:",insn);
1946 return "";
1949 const char *
1950 out_movsi_r_mr (rtx insn, rtx op[], int *l)
1952 rtx dest = op[0];
1953 rtx src = op[1];
1954 rtx base = XEXP (src, 0);
1955 int reg_dest = true_regnum (dest);
1956 int reg_base = true_regnum (base);
1957 int tmp;
1959 if (!l)
1960 l = &tmp;
1962 if (reg_base > 0)
1964 if (reg_base == REG_X) /* (R26) */
1966 if (reg_dest == REG_X)
1967 /* "ld r26,-X" is undefined */
1968 return *l=7, (AS2 (adiw,r26,3) CR_TAB
1969 AS2 (ld,r29,X) CR_TAB
1970 AS2 (ld,r28,-X) CR_TAB
1971 AS2 (ld,__tmp_reg__,-X) CR_TAB
1972 AS2 (sbiw,r26,1) CR_TAB
1973 AS2 (ld,r26,X) CR_TAB
1974 AS2 (mov,r27,__tmp_reg__));
1975 else if (reg_dest == REG_X - 2)
1976 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
1977 AS2 (ld,%B0,X+) CR_TAB
1978 AS2 (ld,__tmp_reg__,X+) CR_TAB
1979 AS2 (ld,%D0,X) CR_TAB
1980 AS2 (mov,%C0,__tmp_reg__));
1981 else if (reg_unused_after (insn, base))
1982 return *l=4, (AS2 (ld,%A0,X+) CR_TAB
1983 AS2 (ld,%B0,X+) CR_TAB
1984 AS2 (ld,%C0,X+) CR_TAB
1985 AS2 (ld,%D0,X));
1986 else
1987 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
1988 AS2 (ld,%B0,X+) CR_TAB
1989 AS2 (ld,%C0,X+) CR_TAB
1990 AS2 (ld,%D0,X) CR_TAB
1991 AS2 (sbiw,r26,3));
1993 else
1995 if (reg_dest == reg_base)
1996 return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
1997 AS2 (ldd,%C0,%1+2) CR_TAB
1998 AS2 (ldd,__tmp_reg__,%1+1) CR_TAB
1999 AS2 (ld,%A0,%1) CR_TAB
2000 AS2 (mov,%B0,__tmp_reg__));
2001 else if (reg_base == reg_dest + 2)
2002 return *l=5, (AS2 (ld ,%A0,%1) CR_TAB
2003 AS2 (ldd,%B0,%1+1) CR_TAB
2004 AS2 (ldd,__tmp_reg__,%1+2) CR_TAB
2005 AS2 (ldd,%D0,%1+3) CR_TAB
2006 AS2 (mov,%C0,__tmp_reg__));
2007 else
2008 return *l=4, (AS2 (ld ,%A0,%1) CR_TAB
2009 AS2 (ldd,%B0,%1+1) CR_TAB
2010 AS2 (ldd,%C0,%1+2) CR_TAB
2011 AS2 (ldd,%D0,%1+3));
2014 else if (GET_CODE (base) == PLUS) /* (R + i) */
2016 int disp = INTVAL (XEXP (base, 1));
2018 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2020 if (REGNO (XEXP (base, 0)) != REG_Y)
2021 fatal_insn ("incorrect insn:",insn);
2023 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2024 return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2025 AS2 (ldd,%A0,Y+60) CR_TAB
2026 AS2 (ldd,%B0,Y+61) CR_TAB
2027 AS2 (ldd,%C0,Y+62) CR_TAB
2028 AS2 (ldd,%D0,Y+63) CR_TAB
2029 AS2 (sbiw,r28,%o1-60));
2031 return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2032 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2033 AS2 (ld,%A0,Y) CR_TAB
2034 AS2 (ldd,%B0,Y+1) CR_TAB
2035 AS2 (ldd,%C0,Y+2) CR_TAB
2036 AS2 (ldd,%D0,Y+3) CR_TAB
2037 AS2 (subi,r28,lo8(%o1)) CR_TAB
2038 AS2 (sbci,r29,hi8(%o1)));
2041 reg_base = true_regnum (XEXP (base, 0));
2042 if (reg_base == REG_X)
2044 /* R = (X + d) */
2045 if (reg_dest == REG_X)
2047 *l = 7;
2048 /* "ld r26,-X" is undefined */
2049 return (AS2 (adiw,r26,%o1+3) CR_TAB
2050 AS2 (ld,r29,X) CR_TAB
2051 AS2 (ld,r28,-X) CR_TAB
2052 AS2 (ld,__tmp_reg__,-X) CR_TAB
2053 AS2 (sbiw,r26,1) CR_TAB
2054 AS2 (ld,r26,X) CR_TAB
2055 AS2 (mov,r27,__tmp_reg__));
2057 *l = 6;
2058 if (reg_dest == REG_X - 2)
2059 return (AS2 (adiw,r26,%o1) CR_TAB
2060 AS2 (ld,r24,X+) CR_TAB
2061 AS2 (ld,r25,X+) CR_TAB
2062 AS2 (ld,__tmp_reg__,X+) CR_TAB
2063 AS2 (ld,r27,X) CR_TAB
2064 AS2 (mov,r26,__tmp_reg__));
2066 return (AS2 (adiw,r26,%o1) CR_TAB
2067 AS2 (ld,%A0,X+) CR_TAB
2068 AS2 (ld,%B0,X+) CR_TAB
2069 AS2 (ld,%C0,X+) CR_TAB
2070 AS2 (ld,%D0,X) CR_TAB
2071 AS2 (sbiw,r26,%o1+3));
2073 if (reg_dest == reg_base)
2074 return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2075 AS2 (ldd,%C0,%C1) CR_TAB
2076 AS2 (ldd,__tmp_reg__,%B1) CR_TAB
2077 AS2 (ldd,%A0,%A1) CR_TAB
2078 AS2 (mov,%B0,__tmp_reg__));
2079 else if (reg_dest == reg_base - 2)
2080 return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2081 AS2 (ldd,%B0,%B1) CR_TAB
2082 AS2 (ldd,__tmp_reg__,%C1) CR_TAB
2083 AS2 (ldd,%D0,%D1) CR_TAB
2084 AS2 (mov,%C0,__tmp_reg__));
2085 return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2086 AS2 (ldd,%B0,%B1) CR_TAB
2087 AS2 (ldd,%C0,%C1) CR_TAB
2088 AS2 (ldd,%D0,%D1));
2090 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2091 return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2092 AS2 (ld,%C0,%1) CR_TAB
2093 AS2 (ld,%B0,%1) CR_TAB
2094 AS2 (ld,%A0,%1));
2095 else if (GET_CODE (base) == POST_INC) /* (R++) */
2096 return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2097 AS2 (ld,%B0,%1) CR_TAB
2098 AS2 (ld,%C0,%1) CR_TAB
2099 AS2 (ld,%D0,%1));
2100 else if (CONSTANT_ADDRESS_P (base))
2101 return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2102 AS2 (lds,%B0,%B1) CR_TAB
2103 AS2 (lds,%C0,%C1) CR_TAB
2104 AS2 (lds,%D0,%D1));
2106 fatal_insn ("unknown move insn:",insn);
2107 return "";
2110 const char *
2111 out_movsi_mr_r (rtx insn, rtx op[], int *l)
2113 rtx dest = op[0];
2114 rtx src = op[1];
2115 rtx base = XEXP (dest, 0);
2116 int reg_base = true_regnum (base);
2117 int reg_src = true_regnum (src);
2118 int tmp;
2120 if (!l)
2121 l = &tmp;
2123 if (CONSTANT_ADDRESS_P (base))
2124 return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2125 AS2 (sts,%B0,%B1) CR_TAB
2126 AS2 (sts,%C0,%C1) CR_TAB
2127 AS2 (sts,%D0,%D1));
2128 if (reg_base > 0) /* (r) */
2130 if (reg_base == REG_X) /* (R26) */
2132 if (reg_src == REG_X)
2134 /* "st X+,r26" is undefined */
2135 if (reg_unused_after (insn, base))
2136 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2137 AS2 (st,X,r26) CR_TAB
2138 AS2 (adiw,r26,1) CR_TAB
2139 AS2 (st,X+,__tmp_reg__) CR_TAB
2140 AS2 (st,X+,r28) CR_TAB
2141 AS2 (st,X,r29));
2142 else
2143 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2144 AS2 (st,X,r26) CR_TAB
2145 AS2 (adiw,r26,1) CR_TAB
2146 AS2 (st,X+,__tmp_reg__) CR_TAB
2147 AS2 (st,X+,r28) CR_TAB
2148 AS2 (st,X,r29) CR_TAB
2149 AS2 (sbiw,r26,3));
2151 else if (reg_base == reg_src + 2)
2153 if (reg_unused_after (insn, base))
2154 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2155 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2156 AS2 (st,%0+,%A1) CR_TAB
2157 AS2 (st,%0+,%B1) CR_TAB
2158 AS2 (st,%0+,__zero_reg__) CR_TAB
2159 AS2 (st,%0,__tmp_reg__) CR_TAB
2160 AS1 (clr,__zero_reg__));
2161 else
2162 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2163 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2164 AS2 (st,%0+,%A1) CR_TAB
2165 AS2 (st,%0+,%B1) CR_TAB
2166 AS2 (st,%0+,__zero_reg__) CR_TAB
2167 AS2 (st,%0,__tmp_reg__) CR_TAB
2168 AS1 (clr,__zero_reg__) CR_TAB
2169 AS2 (sbiw,r26,3));
2171 return *l=5, (AS2 (st,%0+,%A1) CR_TAB
2172 AS2 (st,%0+,%B1) CR_TAB
2173 AS2 (st,%0+,%C1) CR_TAB
2174 AS2 (st,%0,%D1) CR_TAB
2175 AS2 (sbiw,r26,3));
2177 else
2178 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2179 AS2 (std,%0+1,%B1) CR_TAB
2180 AS2 (std,%0+2,%C1) CR_TAB
2181 AS2 (std,%0+3,%D1));
2183 else if (GET_CODE (base) == PLUS) /* (R + i) */
2185 int disp = INTVAL (XEXP (base, 1));
2186 reg_base = REGNO (XEXP (base, 0));
2187 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2189 if (reg_base != REG_Y)
2190 fatal_insn ("incorrect insn:",insn);
2192 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2193 return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2194 AS2 (std,Y+60,%A1) CR_TAB
2195 AS2 (std,Y+61,%B1) CR_TAB
2196 AS2 (std,Y+62,%C1) CR_TAB
2197 AS2 (std,Y+63,%D1) CR_TAB
2198 AS2 (sbiw,r28,%o0-60));
2200 return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2201 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2202 AS2 (st,Y,%A1) CR_TAB
2203 AS2 (std,Y+1,%B1) CR_TAB
2204 AS2 (std,Y+2,%C1) CR_TAB
2205 AS2 (std,Y+3,%D1) CR_TAB
2206 AS2 (subi,r28,lo8(%o0)) CR_TAB
2207 AS2 (sbci,r29,hi8(%o0)));
2209 if (reg_base == REG_X)
2211 /* (X + d) = R */
2212 if (reg_src == REG_X)
2214 *l = 9;
2215 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2216 AS2 (mov,__zero_reg__,r27) CR_TAB
2217 AS2 (adiw,r26,%o0) CR_TAB
2218 AS2 (st,X+,__tmp_reg__) CR_TAB
2219 AS2 (st,X+,__zero_reg__) CR_TAB
2220 AS2 (st,X+,r28) CR_TAB
2221 AS2 (st,X,r29) CR_TAB
2222 AS1 (clr,__zero_reg__) CR_TAB
2223 AS2 (sbiw,r26,%o0+3));
2225 else if (reg_src == REG_X - 2)
2227 *l = 9;
2228 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2229 AS2 (mov,__zero_reg__,r27) CR_TAB
2230 AS2 (adiw,r26,%o0) CR_TAB
2231 AS2 (st,X+,r24) CR_TAB
2232 AS2 (st,X+,r25) CR_TAB
2233 AS2 (st,X+,__tmp_reg__) CR_TAB
2234 AS2 (st,X,__zero_reg__) CR_TAB
2235 AS1 (clr,__zero_reg__) CR_TAB
2236 AS2 (sbiw,r26,%o0+3));
2238 *l = 6;
2239 return (AS2 (adiw,r26,%o0) CR_TAB
2240 AS2 (st,X+,%A1) CR_TAB
2241 AS2 (st,X+,%B1) CR_TAB
2242 AS2 (st,X+,%C1) CR_TAB
2243 AS2 (st,X,%D1) CR_TAB
2244 AS2 (sbiw,r26,%o0+3));
2246 return *l=4, (AS2 (std,%A0,%A1) CR_TAB
2247 AS2 (std,%B0,%B1) CR_TAB
2248 AS2 (std,%C0,%C1) CR_TAB
2249 AS2 (std,%D0,%D1));
2251 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2252 return *l=4, (AS2 (st,%0,%D1) CR_TAB
2253 AS2 (st,%0,%C1) CR_TAB
2254 AS2 (st,%0,%B1) CR_TAB
2255 AS2 (st,%0,%A1));
2256 else if (GET_CODE (base) == POST_INC) /* (R++) */
2257 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2258 AS2 (st,%0,%B1) CR_TAB
2259 AS2 (st,%0,%C1) CR_TAB
2260 AS2 (st,%0,%D1));
2261 fatal_insn ("unknown move insn:",insn);
2262 return "";
2265 const char *
2266 output_movsisf(rtx insn, rtx operands[], int *l)
2268 int dummy;
2269 rtx dest = operands[0];
2270 rtx src = operands[1];
2271 int *real_l = l;
2273 if (!l)
2274 l = &dummy;
2276 if (register_operand (dest, VOIDmode))
2278 if (register_operand (src, VOIDmode)) /* mov r,r */
2280 if (true_regnum (dest) > true_regnum (src))
2282 if (AVR_ENHANCED)
2284 *l = 2;
2285 return (AS2 (movw,%C0,%C1) CR_TAB
2286 AS2 (movw,%A0,%A1));
2288 *l = 4;
2289 return (AS2 (mov,%D0,%D1) CR_TAB
2290 AS2 (mov,%C0,%C1) CR_TAB
2291 AS2 (mov,%B0,%B1) CR_TAB
2292 AS2 (mov,%A0,%A1));
2294 else
2296 if (AVR_ENHANCED)
2298 *l = 2;
2299 return (AS2 (movw,%A0,%A1) CR_TAB
2300 AS2 (movw,%C0,%C1));
2302 *l = 4;
2303 return (AS2 (mov,%A0,%A1) CR_TAB
2304 AS2 (mov,%B0,%B1) CR_TAB
2305 AS2 (mov,%C0,%C1) CR_TAB
2306 AS2 (mov,%D0,%D1));
2309 else if (CONSTANT_P (src))
2311 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2313 *l = 4;
2314 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
2315 AS2 (ldi,%B0,hi8(%1)) CR_TAB
2316 AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2317 AS2 (ldi,%D0,hhi8(%1)));
2320 if (GET_CODE (src) == CONST_INT)
2322 const char *const clr_op0 =
2323 AVR_ENHANCED ? (AS1 (clr,%A0) CR_TAB
2324 AS1 (clr,%B0) CR_TAB
2325 AS2 (movw,%C0,%A0))
2326 : (AS1 (clr,%A0) CR_TAB
2327 AS1 (clr,%B0) CR_TAB
2328 AS1 (clr,%C0) CR_TAB
2329 AS1 (clr,%D0));
2331 if (src == const0_rtx) /* mov r,L */
2333 *l = AVR_ENHANCED ? 3 : 4;
2334 return clr_op0;
2336 else if (src == const1_rtx)
2338 if (!real_l)
2339 output_asm_insn (clr_op0, operands);
2340 *l = AVR_ENHANCED ? 4 : 5;
2341 return AS1 (inc,%A0);
2343 else if (src == constm1_rtx)
2345 /* Immediate constants -1 to any register */
2346 if (AVR_ENHANCED)
2348 *l = 4;
2349 return (AS1 (clr,%A0) CR_TAB
2350 AS1 (dec,%A0) CR_TAB
2351 AS2 (mov,%B0,%A0) CR_TAB
2352 AS2 (movw,%C0,%A0));
2354 *l = 5;
2355 return (AS1 (clr,%A0) CR_TAB
2356 AS1 (dec,%A0) CR_TAB
2357 AS2 (mov,%B0,%A0) CR_TAB
2358 AS2 (mov,%C0,%A0) CR_TAB
2359 AS2 (mov,%D0,%A0));
2361 else
2363 int bit_nr = exact_log2 (INTVAL (src));
2365 if (bit_nr >= 0)
2367 *l = AVR_ENHANCED ? 5 : 6;
2368 if (!real_l)
2370 output_asm_insn (clr_op0, operands);
2371 output_asm_insn ("set", operands);
2373 if (!real_l)
2374 avr_output_bld (operands, bit_nr);
2376 return "";
2381 /* Last resort, better than loading from memory. */
2382 *l = 10;
2383 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2384 AS2 (ldi,r31,lo8(%1)) CR_TAB
2385 AS2 (mov,%A0,r31) CR_TAB
2386 AS2 (ldi,r31,hi8(%1)) CR_TAB
2387 AS2 (mov,%B0,r31) CR_TAB
2388 AS2 (ldi,r31,hlo8(%1)) CR_TAB
2389 AS2 (mov,%C0,r31) CR_TAB
2390 AS2 (ldi,r31,hhi8(%1)) CR_TAB
2391 AS2 (mov,%D0,r31) CR_TAB
2392 AS2 (mov,r31,__tmp_reg__));
2394 else if (GET_CODE (src) == MEM)
2395 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2397 else if (GET_CODE (dest) == MEM)
2399 const char *template;
2401 if (src == const0_rtx)
2402 operands[1] = zero_reg_rtx;
2404 template = out_movsi_mr_r (insn, operands, real_l);
2406 if (!real_l)
2407 output_asm_insn (template, operands);
2409 operands[1] = src;
2410 return "";
2412 fatal_insn ("invalid insn:", insn);
2413 return "";
2416 const char *
2417 out_movqi_mr_r (rtx insn, rtx op[], int *l)
2419 rtx dest = op[0];
2420 rtx src = op[1];
2421 rtx x = XEXP (dest, 0);
2422 int dummy;
2424 if (!l)
2425 l = &dummy;
2427 if (CONSTANT_ADDRESS_P (x))
2429 if (avr_io_address_p (x, 1))
2431 *l = 1;
2432 return AS2 (out,%0-0x20,%1);
2434 *l = 2;
2435 return AS2 (sts,%0,%1);
2437 /* memory access by reg+disp */
2438 else if (GET_CODE (x) == PLUS
2439 && REG_P (XEXP (x,0))
2440 && GET_CODE (XEXP (x,1)) == CONST_INT)
2442 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2444 int disp = INTVAL (XEXP (x,1));
2445 if (REGNO (XEXP (x,0)) != REG_Y)
2446 fatal_insn ("incorrect insn:",insn);
2448 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2449 return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2450 AS2 (std,Y+63,%1) CR_TAB
2451 AS2 (sbiw,r28,%o0-63));
2453 return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2454 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2455 AS2 (st,Y,%1) CR_TAB
2456 AS2 (subi,r28,lo8(%o0)) CR_TAB
2457 AS2 (sbci,r29,hi8(%o0)));
2459 else if (REGNO (XEXP (x,0)) == REG_X)
2461 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2463 if (reg_unused_after (insn, XEXP (x,0)))
2464 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2465 AS2 (adiw,r26,%o0) CR_TAB
2466 AS2 (st,X,__tmp_reg__));
2468 return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2469 AS2 (adiw,r26,%o0) CR_TAB
2470 AS2 (st,X,__tmp_reg__) CR_TAB
2471 AS2 (sbiw,r26,%o0));
2473 else
2475 if (reg_unused_after (insn, XEXP (x,0)))
2476 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2477 AS2 (st,X,%1));
2479 return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2480 AS2 (st,X,%1) CR_TAB
2481 AS2 (sbiw,r26,%o0));
2484 *l = 1;
2485 return AS2 (std,%0,%1);
2487 *l = 1;
2488 return AS2 (st,%0,%1);
2491 const char *
2492 out_movhi_mr_r (rtx insn, rtx op[], int *l)
2494 rtx dest = op[0];
2495 rtx src = op[1];
2496 rtx base = XEXP (dest, 0);
2497 int reg_base = true_regnum (base);
2498 int reg_src = true_regnum (src);
2499 int tmp;
2500 if (!l)
2501 l = &tmp;
2502 if (CONSTANT_ADDRESS_P (base))
2504 if (avr_io_address_p (base, 2))
2506 *l = 2;
2507 return (AS2 (out,%B0-0x20,%B1) CR_TAB
2508 AS2 (out,%A0-0x20,%A1));
2510 return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2511 AS2 (sts,%A0,%A1));
2513 if (reg_base > 0)
2515 if (reg_base == REG_X)
2517 if (reg_src == REG_X)
2519 /* "st X+,r26" is undefined */
2520 if (reg_unused_after (insn, src))
2521 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2522 AS2 (st,X,r26) CR_TAB
2523 AS2 (adiw,r26,1) CR_TAB
2524 AS2 (st,X,__tmp_reg__));
2525 else
2526 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2527 AS2 (st,X,r26) CR_TAB
2528 AS2 (adiw,r26,1) CR_TAB
2529 AS2 (st,X,__tmp_reg__) CR_TAB
2530 AS2 (sbiw,r26,1));
2532 else
2534 if (reg_unused_after (insn, base))
2535 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2536 AS2 (st,X,%B1));
2537 else
2538 return *l=3, (AS2 (st ,X+,%A1) CR_TAB
2539 AS2 (st ,X,%B1) CR_TAB
2540 AS2 (sbiw,r26,1));
2543 else
2544 return *l=2, (AS2 (st ,%0,%A1) CR_TAB
2545 AS2 (std,%0+1,%B1));
2547 else if (GET_CODE (base) == PLUS)
2549 int disp = INTVAL (XEXP (base, 1));
2550 reg_base = REGNO (XEXP (base, 0));
2551 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2553 if (reg_base != REG_Y)
2554 fatal_insn ("incorrect insn:",insn);
2556 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2557 return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2558 AS2 (std,Y+62,%A1) CR_TAB
2559 AS2 (std,Y+63,%B1) CR_TAB
2560 AS2 (sbiw,r28,%o0-62));
2562 return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2563 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2564 AS2 (st,Y,%A1) CR_TAB
2565 AS2 (std,Y+1,%B1) CR_TAB
2566 AS2 (subi,r28,lo8(%o0)) CR_TAB
2567 AS2 (sbci,r29,hi8(%o0)));
2569 if (reg_base == REG_X)
2571 /* (X + d) = R */
2572 if (reg_src == REG_X)
2574 *l = 7;
2575 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2576 AS2 (mov,__zero_reg__,r27) CR_TAB
2577 AS2 (adiw,r26,%o0) CR_TAB
2578 AS2 (st,X+,__tmp_reg__) CR_TAB
2579 AS2 (st,X,__zero_reg__) CR_TAB
2580 AS1 (clr,__zero_reg__) CR_TAB
2581 AS2 (sbiw,r26,%o0+1));
2583 *l = 4;
2584 return (AS2 (adiw,r26,%o0) CR_TAB
2585 AS2 (st,X+,%A1) CR_TAB
2586 AS2 (st,X,%B1) CR_TAB
2587 AS2 (sbiw,r26,%o0+1));
2589 return *l=2, (AS2 (std,%A0,%A1) CR_TAB
2590 AS2 (std,%B0,%B1));
2592 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2593 return *l=2, (AS2 (st,%0,%B1) CR_TAB
2594 AS2 (st,%0,%A1));
2595 else if (GET_CODE (base) == POST_INC) /* (R++) */
2596 return *l=2, (AS2 (st,%0,%A1) CR_TAB
2597 AS2 (st,%0,%B1));
2598 fatal_insn ("unknown move insn:",insn);
2599 return "";
2602 /* Return 1 if frame pointer for current function required. */
2605 frame_pointer_required_p (void)
2607 return (current_function_calls_alloca
2608 || current_function_args_info.nregs == 0
2609 || get_frame_size () > 0);
2612 /* Returns the condition of compare insn INSN, or UNKNOWN. */
2614 static RTX_CODE
2615 compare_condition (rtx insn)
2617 rtx next = next_real_insn (insn);
2618 RTX_CODE cond = UNKNOWN;
2619 if (next && GET_CODE (next) == JUMP_INSN)
2621 rtx pat = PATTERN (next);
2622 rtx src = SET_SRC (pat);
2623 rtx t = XEXP (src, 0);
2624 cond = GET_CODE (t);
2626 return cond;
2629 /* Returns nonzero if INSN is a tst insn that only tests the sign. */
2631 static int
2632 compare_sign_p (rtx insn)
2634 RTX_CODE cond = compare_condition (insn);
2635 return (cond == GE || cond == LT);
2638 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
2639 that needs to be swapped (GT, GTU, LE, LEU). */
2642 compare_diff_p (rtx insn)
2644 RTX_CODE cond = compare_condition (insn);
2645 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2648 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition. */
2651 compare_eq_p (rtx insn)
2653 RTX_CODE cond = compare_condition (insn);
2654 return (cond == EQ || cond == NE);
2658 /* Output test instruction for HImode. */
2660 const char *
2661 out_tsthi (rtx insn, int *l)
2663 if (compare_sign_p (insn))
2665 if (l) *l = 1;
2666 return AS1 (tst,%B0);
2668 if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
2669 && compare_eq_p (insn))
2671 /* Faster than sbiw if we can clobber the operand. */
2672 if (l) *l = 1;
2673 return AS2 (or,%A0,%B0);
2675 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2677 if (l) *l = 1;
2678 return AS2 (sbiw,%0,0);
2680 if (l) *l = 2;
2681 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2682 AS2 (cpc,%B0,__zero_reg__));
2686 /* Output test instruction for SImode. */
2688 const char *
2689 out_tstsi (rtx insn, int *l)
2691 if (compare_sign_p (insn))
2693 if (l) *l = 1;
2694 return AS1 (tst,%D0);
2696 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2698 if (l) *l = 3;
2699 return (AS2 (sbiw,%A0,0) CR_TAB
2700 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2701 AS2 (cpc,%D0,__zero_reg__));
2703 if (l) *l = 4;
2704 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2705 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2706 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2707 AS2 (cpc,%D0,__zero_reg__));
2711 /* Generate asm equivalent for various shifts.
2712 Shift count is a CONST_INT, MEM or REG.
2713 This only handles cases that are not already
2714 carefully hand-optimized in ?sh??i3_out. */
2716 void
2717 out_shift_with_cnt (const char *template, rtx insn, rtx operands[],
2718 int *len, int t_len)
2720 rtx op[10];
2721 char str[500];
2722 int second_label = 1;
2723 int saved_in_tmp = 0;
2724 int use_zero_reg = 0;
2726 op[0] = operands[0];
2727 op[1] = operands[1];
2728 op[2] = operands[2];
2729 op[3] = operands[3];
2730 str[0] = 0;
2732 if (len)
2733 *len = 1;
2735 if (GET_CODE (operands[2]) == CONST_INT)
2737 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2738 int count = INTVAL (operands[2]);
2739 int max_len = 10; /* If larger than this, always use a loop. */
2741 if (count < 8 && !scratch)
2742 use_zero_reg = 1;
2744 if (optimize_size)
2745 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
2747 if (t_len * count <= max_len)
2749 /* Output shifts inline with no loop - faster. */
2750 if (len)
2751 *len = t_len * count;
2752 else
2754 while (count-- > 0)
2755 output_asm_insn (template, op);
2758 return;
2761 if (scratch)
2763 if (!len)
2764 strcat (str, AS2 (ldi,%3,%2));
2766 else if (use_zero_reg)
2768 /* Hack to save one word: use __zero_reg__ as loop counter.
2769 Set one bit, then shift in a loop until it is 0 again. */
2771 op[3] = zero_reg_rtx;
2772 if (len)
2773 *len = 2;
2774 else
2775 strcat (str, ("set" CR_TAB
2776 AS2 (bld,%3,%2-1)));
2778 else
2780 /* No scratch register available, use one from LD_REGS (saved in
2781 __tmp_reg__) that doesn't overlap with registers to shift. */
2783 op[3] = gen_rtx_REG (QImode,
2784 ((true_regnum (operands[0]) - 1) & 15) + 16);
2785 op[4] = tmp_reg_rtx;
2786 saved_in_tmp = 1;
2788 if (len)
2789 *len = 3; /* Includes "mov %3,%4" after the loop. */
2790 else
2791 strcat (str, (AS2 (mov,%4,%3) CR_TAB
2792 AS2 (ldi,%3,%2)));
2795 second_label = 0;
2797 else if (GET_CODE (operands[2]) == MEM)
2799 rtx op_mov[10];
2801 op[3] = op_mov[0] = tmp_reg_rtx;
2802 op_mov[1] = op[2];
2804 if (len)
2805 out_movqi_r_mr (insn, op_mov, len);
2806 else
2807 output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2809 else if (register_operand (operands[2], QImode))
2811 if (reg_unused_after (insn, operands[2]))
2812 op[3] = op[2];
2813 else
2815 op[3] = tmp_reg_rtx;
2816 if (!len)
2817 strcat (str, (AS2 (mov,%3,%2) CR_TAB));
2820 else
2821 fatal_insn ("bad shift insn:", insn);
2823 if (second_label)
2825 if (len)
2826 ++*len;
2827 else
2828 strcat (str, AS1 (rjmp,2f));
2831 if (len)
2832 *len += t_len + 2; /* template + dec + brXX */
2833 else
2835 strcat (str, "\n1:\t");
2836 strcat (str, template);
2837 strcat (str, second_label ? "\n2:\t" : "\n\t");
2838 strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
2839 strcat (str, CR_TAB);
2840 strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
2841 if (saved_in_tmp)
2842 strcat (str, (CR_TAB AS2 (mov,%3,%4)));
2843 output_asm_insn (str, op);
2848 /* 8bit shift left ((char)x << i) */
2850 const char *
2851 ashlqi3_out (rtx insn, rtx operands[], int *len)
2853 if (GET_CODE (operands[2]) == CONST_INT)
2855 int k;
2857 if (!len)
2858 len = &k;
2860 switch (INTVAL (operands[2]))
2862 default:
2863 *len = 1;
2864 return AS1 (clr,%0);
2866 case 1:
2867 *len = 1;
2868 return AS1 (lsl,%0);
2870 case 2:
2871 *len = 2;
2872 return (AS1 (lsl,%0) CR_TAB
2873 AS1 (lsl,%0));
2875 case 3:
2876 *len = 3;
2877 return (AS1 (lsl,%0) CR_TAB
2878 AS1 (lsl,%0) CR_TAB
2879 AS1 (lsl,%0));
2881 case 4:
2882 if (test_hard_reg_class (LD_REGS, operands[0]))
2884 *len = 2;
2885 return (AS1 (swap,%0) CR_TAB
2886 AS2 (andi,%0,0xf0));
2888 *len = 4;
2889 return (AS1 (lsl,%0) CR_TAB
2890 AS1 (lsl,%0) CR_TAB
2891 AS1 (lsl,%0) CR_TAB
2892 AS1 (lsl,%0));
2894 case 5:
2895 if (test_hard_reg_class (LD_REGS, operands[0]))
2897 *len = 3;
2898 return (AS1 (swap,%0) CR_TAB
2899 AS1 (lsl,%0) CR_TAB
2900 AS2 (andi,%0,0xe0));
2902 *len = 5;
2903 return (AS1 (lsl,%0) CR_TAB
2904 AS1 (lsl,%0) CR_TAB
2905 AS1 (lsl,%0) CR_TAB
2906 AS1 (lsl,%0) CR_TAB
2907 AS1 (lsl,%0));
2909 case 6:
2910 if (test_hard_reg_class (LD_REGS, operands[0]))
2912 *len = 4;
2913 return (AS1 (swap,%0) CR_TAB
2914 AS1 (lsl,%0) CR_TAB
2915 AS1 (lsl,%0) CR_TAB
2916 AS2 (andi,%0,0xc0));
2918 *len = 6;
2919 return (AS1 (lsl,%0) CR_TAB
2920 AS1 (lsl,%0) CR_TAB
2921 AS1 (lsl,%0) CR_TAB
2922 AS1 (lsl,%0) CR_TAB
2923 AS1 (lsl,%0) CR_TAB
2924 AS1 (lsl,%0));
2926 case 7:
2927 *len = 3;
2928 return (AS1 (ror,%0) CR_TAB
2929 AS1 (clr,%0) CR_TAB
2930 AS1 (ror,%0));
2933 else if (CONSTANT_P (operands[2]))
2934 fatal_insn ("internal compiler error. Incorrect shift:", insn);
2936 out_shift_with_cnt (AS1 (lsl,%0),
2937 insn, operands, len, 1);
2938 return "";
2942 /* 16bit shift left ((short)x << i) */
2944 const char *
2945 ashlhi3_out (rtx insn, rtx operands[], int *len)
2947 if (GET_CODE (operands[2]) == CONST_INT)
2949 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2950 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
2951 int k;
2952 int *t = len;
2954 if (!len)
2955 len = &k;
2957 switch (INTVAL (operands[2]))
2959 case 4:
2960 if (optimize_size && scratch)
2961 break; /* 5 */
2962 if (ldi_ok)
2964 *len = 6;
2965 return (AS1 (swap,%A0) CR_TAB
2966 AS1 (swap,%B0) CR_TAB
2967 AS2 (andi,%B0,0xf0) CR_TAB
2968 AS2 (eor,%B0,%A0) CR_TAB
2969 AS2 (andi,%A0,0xf0) CR_TAB
2970 AS2 (eor,%B0,%A0));
2972 if (scratch)
2974 *len = 7;
2975 return (AS1 (swap,%A0) CR_TAB
2976 AS1 (swap,%B0) CR_TAB
2977 AS2 (ldi,%3,0xf0) CR_TAB
2978 AS2 (and,%B0,%3) CR_TAB
2979 AS2 (eor,%B0,%A0) CR_TAB
2980 AS2 (and,%A0,%3) CR_TAB
2981 AS2 (eor,%B0,%A0));
2983 break; /* optimize_size ? 6 : 8 */
2985 case 5:
2986 if (optimize_size)
2987 break; /* scratch ? 5 : 6 */
2988 if (ldi_ok)
2990 *len = 8;
2991 return (AS1 (lsl,%A0) CR_TAB
2992 AS1 (rol,%B0) CR_TAB
2993 AS1 (swap,%A0) CR_TAB
2994 AS1 (swap,%B0) CR_TAB
2995 AS2 (andi,%B0,0xf0) CR_TAB
2996 AS2 (eor,%B0,%A0) CR_TAB
2997 AS2 (andi,%A0,0xf0) CR_TAB
2998 AS2 (eor,%B0,%A0));
3000 if (scratch)
3002 *len = 9;
3003 return (AS1 (lsl,%A0) CR_TAB
3004 AS1 (rol,%B0) CR_TAB
3005 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; /* 10 */
3015 case 6:
3016 if (optimize_size)
3017 break; /* scratch ? 5 : 6 */
3018 *len = 9;
3019 return (AS1 (clr,__tmp_reg__) CR_TAB
3020 AS1 (lsr,%B0) CR_TAB
3021 AS1 (ror,%A0) CR_TAB
3022 AS1 (ror,__tmp_reg__) CR_TAB
3023 AS1 (lsr,%B0) CR_TAB
3024 AS1 (ror,%A0) CR_TAB
3025 AS1 (ror,__tmp_reg__) CR_TAB
3026 AS2 (mov,%B0,%A0) CR_TAB
3027 AS2 (mov,%A0,__tmp_reg__));
3029 case 7:
3030 *len = 5;
3031 return (AS1 (lsr,%B0) CR_TAB
3032 AS2 (mov,%B0,%A0) CR_TAB
3033 AS1 (clr,%A0) CR_TAB
3034 AS1 (ror,%B0) CR_TAB
3035 AS1 (ror,%A0));
3037 case 8:
3038 if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
3039 return *len = 1, AS1 (clr,%A0);
3040 else
3041 return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3042 AS1 (clr,%A0));
3044 case 9:
3045 *len = 3;
3046 return (AS2 (mov,%B0,%A0) CR_TAB
3047 AS1 (clr,%A0) CR_TAB
3048 AS1 (lsl,%B0));
3050 case 10:
3051 *len = 4;
3052 return (AS2 (mov,%B0,%A0) CR_TAB
3053 AS1 (clr,%A0) CR_TAB
3054 AS1 (lsl,%B0) CR_TAB
3055 AS1 (lsl,%B0));
3057 case 11:
3058 *len = 5;
3059 return (AS2 (mov,%B0,%A0) CR_TAB
3060 AS1 (clr,%A0) CR_TAB
3061 AS1 (lsl,%B0) CR_TAB
3062 AS1 (lsl,%B0) CR_TAB
3063 AS1 (lsl,%B0));
3065 case 12:
3066 if (ldi_ok)
3068 *len = 4;
3069 return (AS2 (mov,%B0,%A0) CR_TAB
3070 AS1 (clr,%A0) CR_TAB
3071 AS1 (swap,%B0) CR_TAB
3072 AS2 (andi,%B0,0xf0));
3074 if (scratch)
3076 *len = 5;
3077 return (AS2 (mov,%B0,%A0) CR_TAB
3078 AS1 (clr,%A0) CR_TAB
3079 AS1 (swap,%B0) CR_TAB
3080 AS2 (ldi,%3,0xf0) CR_TAB
3081 AS2 (and,%B0,%3));
3083 *len = 6;
3084 return (AS2 (mov,%B0,%A0) CR_TAB
3085 AS1 (clr,%A0) CR_TAB
3086 AS1 (lsl,%B0) CR_TAB
3087 AS1 (lsl,%B0) CR_TAB
3088 AS1 (lsl,%B0) CR_TAB
3089 AS1 (lsl,%B0));
3091 case 13:
3092 if (ldi_ok)
3094 *len = 5;
3095 return (AS2 (mov,%B0,%A0) CR_TAB
3096 AS1 (clr,%A0) CR_TAB
3097 AS1 (swap,%B0) CR_TAB
3098 AS1 (lsl,%B0) CR_TAB
3099 AS2 (andi,%B0,0xe0));
3101 if (AVR_ENHANCED && scratch)
3103 *len = 5;
3104 return (AS2 (ldi,%3,0x20) CR_TAB
3105 AS2 (mul,%A0,%3) CR_TAB
3106 AS2 (mov,%B0,r0) CR_TAB
3107 AS1 (clr,%A0) CR_TAB
3108 AS1 (clr,__zero_reg__));
3110 if (optimize_size && scratch)
3111 break; /* 5 */
3112 if (scratch)
3114 *len = 6;
3115 return (AS2 (mov,%B0,%A0) CR_TAB
3116 AS1 (clr,%A0) CR_TAB
3117 AS1 (swap,%B0) CR_TAB
3118 AS1 (lsl,%B0) CR_TAB
3119 AS2 (ldi,%3,0xe0) CR_TAB
3120 AS2 (and,%B0,%3));
3122 if (AVR_ENHANCED)
3124 *len = 6;
3125 return ("set" CR_TAB
3126 AS2 (bld,r1,5) CR_TAB
3127 AS2 (mul,%A0,r1) CR_TAB
3128 AS2 (mov,%B0,r0) CR_TAB
3129 AS1 (clr,%A0) CR_TAB
3130 AS1 (clr,__zero_reg__));
3132 *len = 7;
3133 return (AS2 (mov,%B0,%A0) CR_TAB
3134 AS1 (clr,%A0) CR_TAB
3135 AS1 (lsl,%B0) CR_TAB
3136 AS1 (lsl,%B0) CR_TAB
3137 AS1 (lsl,%B0) CR_TAB
3138 AS1 (lsl,%B0) CR_TAB
3139 AS1 (lsl,%B0));
3141 case 14:
3142 if (AVR_ENHANCED && ldi_ok)
3144 *len = 5;
3145 return (AS2 (ldi,%B0,0x40) CR_TAB
3146 AS2 (mul,%A0,%B0) CR_TAB
3147 AS2 (mov,%B0,r0) CR_TAB
3148 AS1 (clr,%A0) CR_TAB
3149 AS1 (clr,__zero_reg__));
3151 if (AVR_ENHANCED && scratch)
3153 *len = 5;
3154 return (AS2 (ldi,%3,0x40) CR_TAB
3155 AS2 (mul,%A0,%3) CR_TAB
3156 AS2 (mov,%B0,r0) CR_TAB
3157 AS1 (clr,%A0) CR_TAB
3158 AS1 (clr,__zero_reg__));
3160 if (optimize_size && ldi_ok)
3162 *len = 5;
3163 return (AS2 (mov,%B0,%A0) CR_TAB
3164 AS2 (ldi,%A0,6) "\n1:\t"
3165 AS1 (lsl,%B0) CR_TAB
3166 AS1 (dec,%A0) CR_TAB
3167 AS1 (brne,1b));
3169 if (optimize_size && scratch)
3170 break; /* 5 */
3171 *len = 6;
3172 return (AS1 (clr,%B0) CR_TAB
3173 AS1 (lsr,%A0) CR_TAB
3174 AS1 (ror,%B0) CR_TAB
3175 AS1 (lsr,%A0) CR_TAB
3176 AS1 (ror,%B0) CR_TAB
3177 AS1 (clr,%A0));
3179 case 15:
3180 *len = 4;
3181 return (AS1 (clr,%B0) CR_TAB
3182 AS1 (lsr,%A0) CR_TAB
3183 AS1 (ror,%B0) CR_TAB
3184 AS1 (clr,%A0));
3186 len = t;
3188 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3189 AS1 (rol,%B0)),
3190 insn, operands, len, 2);
3191 return "";
3195 /* 32bit shift left ((long)x << i) */
3197 const char *
3198 ashlsi3_out (rtx insn, rtx operands[], int *len)
3200 if (GET_CODE (operands[2]) == CONST_INT)
3202 int k;
3203 int *t = len;
3205 if (!len)
3206 len = &k;
3208 switch (INTVAL (operands[2]))
3210 case 8:
3212 int reg0 = true_regnum (operands[0]);
3213 int reg1 = true_regnum (operands[1]);
3214 *len = 4;
3215 if (reg0 >= reg1)
3216 return (AS2 (mov,%D0,%C1) CR_TAB
3217 AS2 (mov,%C0,%B1) CR_TAB
3218 AS2 (mov,%B0,%A1) CR_TAB
3219 AS1 (clr,%A0));
3220 else if (reg0 + 1 == reg1)
3222 *len = 1;
3223 return AS1 (clr,%A0);
3225 else
3226 return (AS1 (clr,%A0) CR_TAB
3227 AS2 (mov,%B0,%A1) CR_TAB
3228 AS2 (mov,%C0,%B1) CR_TAB
3229 AS2 (mov,%D0,%C1));
3232 case 16:
3234 int reg0 = true_regnum (operands[0]);
3235 int reg1 = true_regnum (operands[1]);
3236 *len = 4;
3237 if (AVR_ENHANCED && (reg0 + 2 != reg1))
3239 *len = 3;
3240 return (AS2 (movw,%C0,%A1) CR_TAB
3241 AS1 (clr,%B0) CR_TAB
3242 AS1 (clr,%A0));
3244 if (reg0 + 1 >= reg1)
3245 return (AS2 (mov,%D0,%B1) CR_TAB
3246 AS2 (mov,%C0,%A1) CR_TAB
3247 AS1 (clr,%B0) CR_TAB
3248 AS1 (clr,%A0));
3249 if (reg0 + 2 == reg1)
3251 *len = 2;
3252 return (AS1 (clr,%B0) CR_TAB
3253 AS1 (clr,%A0));
3255 else
3256 return (AS2 (mov,%C0,%A1) CR_TAB
3257 AS2 (mov,%D0,%B1) CR_TAB
3258 AS1 (clr,%B0) CR_TAB
3259 AS1 (clr,%A0));
3262 case 24:
3263 *len = 4;
3264 if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
3265 return (AS2 (mov,%D0,%A1) CR_TAB
3266 AS1 (clr,%C0) CR_TAB
3267 AS1 (clr,%B0) CR_TAB
3268 AS1 (clr,%A0));
3269 else
3271 *len = 3;
3272 return (AS1 (clr,%C0) CR_TAB
3273 AS1 (clr,%B0) CR_TAB
3274 AS1 (clr,%A0));
3277 case 31:
3278 *len = 6;
3279 return (AS1 (clr,%D0) CR_TAB
3280 AS1 (lsr,%A0) CR_TAB
3281 AS1 (ror,%D0) CR_TAB
3282 AS1 (clr,%C0) CR_TAB
3283 AS1 (clr,%B0) CR_TAB
3284 AS1 (clr,%A0));
3286 len = t;
3288 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3289 AS1 (rol,%B0) CR_TAB
3290 AS1 (rol,%C0) CR_TAB
3291 AS1 (rol,%D0)),
3292 insn, operands, len, 4);
3293 return "";
3296 /* 8bit arithmetic shift right ((signed char)x >> i) */
3298 const char *
3299 ashrqi3_out (rtx insn, rtx operands[], int *len)
3301 if (GET_CODE (operands[2]) == CONST_INT)
3303 int k;
3305 if (!len)
3306 len = &k;
3308 switch (INTVAL (operands[2]))
3310 case 1:
3311 *len = 1;
3312 return AS1 (asr,%0);
3314 case 2:
3315 *len = 2;
3316 return (AS1 (asr,%0) CR_TAB
3317 AS1 (asr,%0));
3319 case 3:
3320 *len = 3;
3321 return (AS1 (asr,%0) CR_TAB
3322 AS1 (asr,%0) CR_TAB
3323 AS1 (asr,%0));
3325 case 4:
3326 *len = 4;
3327 return (AS1 (asr,%0) CR_TAB
3328 AS1 (asr,%0) CR_TAB
3329 AS1 (asr,%0) CR_TAB
3330 AS1 (asr,%0));
3332 case 5:
3333 *len = 5;
3334 return (AS1 (asr,%0) CR_TAB
3335 AS1 (asr,%0) CR_TAB
3336 AS1 (asr,%0) CR_TAB
3337 AS1 (asr,%0) CR_TAB
3338 AS1 (asr,%0));
3340 case 6:
3341 *len = 4;
3342 return (AS2 (bst,%0,6) CR_TAB
3343 AS1 (lsl,%0) CR_TAB
3344 AS2 (sbc,%0,%0) CR_TAB
3345 AS2 (bld,%0,0));
3347 default:
3348 case 7:
3349 *len = 2;
3350 return (AS1 (lsl,%0) CR_TAB
3351 AS2 (sbc,%0,%0));
3354 else if (CONSTANT_P (operands[2]))
3355 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3357 out_shift_with_cnt (AS1 (asr,%0),
3358 insn, operands, len, 1);
3359 return "";
3363 /* 16bit arithmetic shift right ((signed short)x >> i) */
3365 const char *
3366 ashrhi3_out (rtx insn, rtx operands[], int *len)
3368 if (GET_CODE (operands[2]) == CONST_INT)
3370 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3371 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3372 int k;
3373 int *t = len;
3375 if (!len)
3376 len = &k;
3378 switch (INTVAL (operands[2]))
3380 case 4:
3381 case 5:
3382 /* XXX try to optimize this too? */
3383 break;
3385 case 6:
3386 if (optimize_size)
3387 break; /* scratch ? 5 : 6 */
3388 *len = 8;
3389 return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3390 AS2 (mov,%A0,%B0) CR_TAB
3391 AS1 (lsl,__tmp_reg__) CR_TAB
3392 AS1 (rol,%A0) CR_TAB
3393 AS2 (sbc,%B0,%B0) CR_TAB
3394 AS1 (lsl,__tmp_reg__) CR_TAB
3395 AS1 (rol,%A0) CR_TAB
3396 AS1 (rol,%B0));
3398 case 7:
3399 *len = 4;
3400 return (AS1 (lsl,%A0) CR_TAB
3401 AS2 (mov,%A0,%B0) CR_TAB
3402 AS1 (rol,%A0) CR_TAB
3403 AS2 (sbc,%B0,%B0));
3405 case 8:
3407 int reg0 = true_regnum (operands[0]);
3408 int reg1 = true_regnum (operands[1]);
3410 if (reg0 == reg1)
3411 return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3412 AS1 (lsl,%B0) CR_TAB
3413 AS2 (sbc,%B0,%B0));
3414 else if (reg0 == reg1 + 1)
3415 return *len = 3, (AS1 (clr,%B0) CR_TAB
3416 AS2 (sbrc,%A0,7) CR_TAB
3417 AS1 (dec,%B0));
3419 return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3420 AS1 (clr,%B0) CR_TAB
3421 AS2 (sbrc,%A0,7) CR_TAB
3422 AS1 (dec,%B0));
3425 case 9:
3426 *len = 4;
3427 return (AS2 (mov,%A0,%B0) CR_TAB
3428 AS1 (lsl,%B0) CR_TAB
3429 AS2 (sbc,%B0,%B0) CR_TAB
3430 AS1 (asr,%A0));
3432 case 10:
3433 *len = 5;
3434 return (AS2 (mov,%A0,%B0) CR_TAB
3435 AS1 (lsl,%B0) CR_TAB
3436 AS2 (sbc,%B0,%B0) CR_TAB
3437 AS1 (asr,%A0) CR_TAB
3438 AS1 (asr,%A0));
3440 case 11:
3441 if (AVR_ENHANCED && ldi_ok)
3443 *len = 5;
3444 return (AS2 (ldi,%A0,0x20) CR_TAB
3445 AS2 (muls,%B0,%A0) CR_TAB
3446 AS2 (mov,%A0,r1) CR_TAB
3447 AS2 (sbc,%B0,%B0) CR_TAB
3448 AS1 (clr,__zero_reg__));
3450 if (optimize_size && scratch)
3451 break; /* 5 */
3452 *len = 6;
3453 return (AS2 (mov,%A0,%B0) CR_TAB
3454 AS1 (lsl,%B0) CR_TAB
3455 AS2 (sbc,%B0,%B0) CR_TAB
3456 AS1 (asr,%A0) CR_TAB
3457 AS1 (asr,%A0) CR_TAB
3458 AS1 (asr,%A0));
3460 case 12:
3461 if (AVR_ENHANCED && ldi_ok)
3463 *len = 5;
3464 return (AS2 (ldi,%A0,0x10) CR_TAB
3465 AS2 (muls,%B0,%A0) CR_TAB
3466 AS2 (mov,%A0,r1) CR_TAB
3467 AS2 (sbc,%B0,%B0) CR_TAB
3468 AS1 (clr,__zero_reg__));
3470 if (optimize_size && scratch)
3471 break; /* 5 */
3472 *len = 7;
3473 return (AS2 (mov,%A0,%B0) CR_TAB
3474 AS1 (lsl,%B0) CR_TAB
3475 AS2 (sbc,%B0,%B0) CR_TAB
3476 AS1 (asr,%A0) CR_TAB
3477 AS1 (asr,%A0) CR_TAB
3478 AS1 (asr,%A0) CR_TAB
3479 AS1 (asr,%A0));
3481 case 13:
3482 if (AVR_ENHANCED && ldi_ok)
3484 *len = 5;
3485 return (AS2 (ldi,%A0,0x08) CR_TAB
3486 AS2 (muls,%B0,%A0) CR_TAB
3487 AS2 (mov,%A0,r1) CR_TAB
3488 AS2 (sbc,%B0,%B0) CR_TAB
3489 AS1 (clr,__zero_reg__));
3491 if (optimize_size)
3492 break; /* scratch ? 5 : 7 */
3493 *len = 8;
3494 return (AS2 (mov,%A0,%B0) CR_TAB
3495 AS1 (lsl,%B0) CR_TAB
3496 AS2 (sbc,%B0,%B0) CR_TAB
3497 AS1 (asr,%A0) CR_TAB
3498 AS1 (asr,%A0) CR_TAB
3499 AS1 (asr,%A0) CR_TAB
3500 AS1 (asr,%A0) CR_TAB
3501 AS1 (asr,%A0));
3503 case 14:
3504 *len = 5;
3505 return (AS1 (lsl,%B0) CR_TAB
3506 AS2 (sbc,%A0,%A0) CR_TAB
3507 AS1 (lsl,%B0) CR_TAB
3508 AS2 (mov,%B0,%A0) CR_TAB
3509 AS1 (rol,%A0));
3511 case 15:
3512 return *len = 3, (AS1 (lsl,%B0) CR_TAB
3513 AS2 (sbc,%A0,%A0) CR_TAB
3514 AS2 (mov,%B0,%A0));
3516 len = t;
3518 out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3519 AS1 (ror,%A0)),
3520 insn, operands, len, 2);
3521 return "";
3525 /* 32bit arithmetic shift right ((signed long)x >> i) */
3527 const char *
3528 ashrsi3_out (rtx insn, rtx operands[], int *len)
3530 if (GET_CODE (operands[2]) == CONST_INT)
3532 int k;
3533 int *t = len;
3535 if (!len)
3536 len = &k;
3538 switch (INTVAL (operands[2]))
3540 case 8:
3542 int reg0 = true_regnum (operands[0]);
3543 int reg1 = true_regnum (operands[1]);
3544 *len=6;
3545 if (reg0 <= reg1)
3546 return (AS2 (mov,%A0,%B1) CR_TAB
3547 AS2 (mov,%B0,%C1) CR_TAB
3548 AS2 (mov,%C0,%D1) CR_TAB
3549 AS1 (clr,%D0) CR_TAB
3550 AS2 (sbrc,%C0,7) CR_TAB
3551 AS1 (dec,%D0));
3552 else if (reg0 == reg1 + 1)
3554 *len = 3;
3555 return (AS1 (clr,%D0) CR_TAB
3556 AS2 (sbrc,%C0,7) CR_TAB
3557 AS1 (dec,%D0));
3559 else
3560 return (AS1 (clr,%D0) CR_TAB
3561 AS2 (sbrc,%D1,7) CR_TAB
3562 AS1 (dec,%D0) CR_TAB
3563 AS2 (mov,%C0,%D1) CR_TAB
3564 AS2 (mov,%B0,%C1) CR_TAB
3565 AS2 (mov,%A0,%B1));
3568 case 16:
3570 int reg0 = true_regnum (operands[0]);
3571 int reg1 = true_regnum (operands[1]);
3572 *len=6;
3573 if (AVR_ENHANCED && (reg0 != reg1 + 2))
3575 *len = 5;
3576 return (AS2 (movw,%A0,%C1) CR_TAB
3577 AS1 (clr,%D0) CR_TAB
3578 AS2 (sbrc,%B0,7) CR_TAB
3579 AS1 (com,%D0) CR_TAB
3580 AS2 (mov,%C0,%D0));
3582 if (reg0 <= reg1 + 1)
3583 return (AS2 (mov,%A0,%C1) CR_TAB
3584 AS2 (mov,%B0,%D1) CR_TAB
3585 AS1 (clr,%D0) CR_TAB
3586 AS2 (sbrc,%B0,7) CR_TAB
3587 AS1 (com,%D0) CR_TAB
3588 AS2 (mov,%C0,%D0));
3589 else if (reg0 == reg1 + 2)
3590 return *len = 4, (AS1 (clr,%D0) CR_TAB
3591 AS2 (sbrc,%B0,7) CR_TAB
3592 AS1 (com,%D0) CR_TAB
3593 AS2 (mov,%C0,%D0));
3594 else
3595 return (AS2 (mov,%B0,%D1) CR_TAB
3596 AS2 (mov,%A0,%C1) CR_TAB
3597 AS1 (clr,%D0) CR_TAB
3598 AS2 (sbrc,%B0,7) CR_TAB
3599 AS1 (com,%D0) CR_TAB
3600 AS2 (mov,%C0,%D0));
3603 case 24:
3604 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3605 return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3606 AS1 (clr,%D0) CR_TAB
3607 AS2 (sbrc,%A0,7) CR_TAB
3608 AS1 (com,%D0) CR_TAB
3609 AS2 (mov,%B0,%D0) CR_TAB
3610 AS2 (mov,%C0,%D0));
3611 else
3612 return *len = 5, (AS1 (clr,%D0) CR_TAB
3613 AS2 (sbrc,%A0,7) CR_TAB
3614 AS1 (com,%D0) CR_TAB
3615 AS2 (mov,%B0,%D0) CR_TAB
3616 AS2 (mov,%C0,%D0));
3618 case 31:
3619 if (AVR_ENHANCED)
3620 return *len = 4, (AS1 (lsl,%D0) CR_TAB
3621 AS2 (sbc,%A0,%A0) CR_TAB
3622 AS2 (mov,%B0,%A0) CR_TAB
3623 AS2 (movw,%C0,%A0));
3624 else
3625 return *len = 5, (AS1 (lsl,%D0) CR_TAB
3626 AS2 (sbc,%A0,%A0) CR_TAB
3627 AS2 (mov,%B0,%A0) CR_TAB
3628 AS2 (mov,%C0,%A0) CR_TAB
3629 AS2 (mov,%D0,%A0));
3631 len = t;
3633 out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
3634 AS1 (ror,%C0) CR_TAB
3635 AS1 (ror,%B0) CR_TAB
3636 AS1 (ror,%A0)),
3637 insn, operands, len, 4);
3638 return "";
3641 /* 8bit logic shift right ((unsigned char)x >> i) */
3643 const char *
3644 lshrqi3_out (rtx insn, rtx operands[], int *len)
3646 if (GET_CODE (operands[2]) == CONST_INT)
3648 int k;
3650 if (!len)
3651 len = &k;
3653 switch (INTVAL (operands[2]))
3655 default:
3656 *len = 1;
3657 return AS1 (clr,%0);
3659 case 1:
3660 *len = 1;
3661 return AS1 (lsr,%0);
3663 case 2:
3664 *len = 2;
3665 return (AS1 (lsr,%0) CR_TAB
3666 AS1 (lsr,%0));
3667 case 3:
3668 *len = 3;
3669 return (AS1 (lsr,%0) CR_TAB
3670 AS1 (lsr,%0) CR_TAB
3671 AS1 (lsr,%0));
3673 case 4:
3674 if (test_hard_reg_class (LD_REGS, operands[0]))
3676 *len=2;
3677 return (AS1 (swap,%0) CR_TAB
3678 AS2 (andi,%0,0x0f));
3680 *len = 4;
3681 return (AS1 (lsr,%0) CR_TAB
3682 AS1 (lsr,%0) CR_TAB
3683 AS1 (lsr,%0) CR_TAB
3684 AS1 (lsr,%0));
3686 case 5:
3687 if (test_hard_reg_class (LD_REGS, operands[0]))
3689 *len = 3;
3690 return (AS1 (swap,%0) CR_TAB
3691 AS1 (lsr,%0) CR_TAB
3692 AS2 (andi,%0,0x7));
3694 *len = 5;
3695 return (AS1 (lsr,%0) CR_TAB
3696 AS1 (lsr,%0) CR_TAB
3697 AS1 (lsr,%0) CR_TAB
3698 AS1 (lsr,%0) CR_TAB
3699 AS1 (lsr,%0));
3701 case 6:
3702 if (test_hard_reg_class (LD_REGS, operands[0]))
3704 *len = 4;
3705 return (AS1 (swap,%0) CR_TAB
3706 AS1 (lsr,%0) CR_TAB
3707 AS1 (lsr,%0) CR_TAB
3708 AS2 (andi,%0,0x3));
3710 *len = 6;
3711 return (AS1 (lsr,%0) CR_TAB
3712 AS1 (lsr,%0) CR_TAB
3713 AS1 (lsr,%0) CR_TAB
3714 AS1 (lsr,%0) CR_TAB
3715 AS1 (lsr,%0) CR_TAB
3716 AS1 (lsr,%0));
3718 case 7:
3719 *len = 3;
3720 return (AS1 (rol,%0) CR_TAB
3721 AS1 (clr,%0) CR_TAB
3722 AS1 (rol,%0));
3725 else if (CONSTANT_P (operands[2]))
3726 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3728 out_shift_with_cnt (AS1 (lsr,%0),
3729 insn, operands, len, 1);
3730 return "";
3733 /* 16bit logic shift right ((unsigned short)x >> i) */
3735 const char *
3736 lshrhi3_out (rtx insn, rtx operands[], int *len)
3738 if (GET_CODE (operands[2]) == CONST_INT)
3740 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3741 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3742 int k;
3743 int *t = len;
3745 if (!len)
3746 len = &k;
3748 switch (INTVAL (operands[2]))
3750 case 4:
3751 if (optimize_size && scratch)
3752 break; /* 5 */
3753 if (ldi_ok)
3755 *len = 6;
3756 return (AS1 (swap,%B0) CR_TAB
3757 AS1 (swap,%A0) CR_TAB
3758 AS2 (andi,%A0,0x0f) CR_TAB
3759 AS2 (eor,%A0,%B0) CR_TAB
3760 AS2 (andi,%B0,0x0f) CR_TAB
3761 AS2 (eor,%A0,%B0));
3763 if (scratch)
3765 *len = 7;
3766 return (AS1 (swap,%B0) CR_TAB
3767 AS1 (swap,%A0) CR_TAB
3768 AS2 (ldi,%3,0x0f) CR_TAB
3769 AS2 (and,%A0,%3) CR_TAB
3770 AS2 (eor,%A0,%B0) CR_TAB
3771 AS2 (and,%B0,%3) CR_TAB
3772 AS2 (eor,%A0,%B0));
3774 break; /* optimize_size ? 6 : 8 */
3776 case 5:
3777 if (optimize_size)
3778 break; /* scratch ? 5 : 6 */
3779 if (ldi_ok)
3781 *len = 8;
3782 return (AS1 (lsr,%B0) CR_TAB
3783 AS1 (ror,%A0) CR_TAB
3784 AS1 (swap,%B0) CR_TAB
3785 AS1 (swap,%A0) CR_TAB
3786 AS2 (andi,%A0,0x0f) CR_TAB
3787 AS2 (eor,%A0,%B0) CR_TAB
3788 AS2 (andi,%B0,0x0f) CR_TAB
3789 AS2 (eor,%A0,%B0));
3791 if (scratch)
3793 *len = 9;
3794 return (AS1 (lsr,%B0) CR_TAB
3795 AS1 (ror,%A0) CR_TAB
3796 AS1 (swap,%B0) CR_TAB
3797 AS1 (swap,%A0) CR_TAB
3798 AS2 (ldi,%3,0x0f) CR_TAB
3799 AS2 (and,%A0,%3) CR_TAB
3800 AS2 (eor,%A0,%B0) CR_TAB
3801 AS2 (and,%B0,%3) CR_TAB
3802 AS2 (eor,%A0,%B0));
3804 break; /* 10 */
3806 case 6:
3807 if (optimize_size)
3808 break; /* scratch ? 5 : 6 */
3809 *len = 9;
3810 return (AS1 (clr,__tmp_reg__) CR_TAB
3811 AS1 (lsl,%A0) CR_TAB
3812 AS1 (rol,%B0) CR_TAB
3813 AS1 (rol,__tmp_reg__) CR_TAB
3814 AS1 (lsl,%A0) CR_TAB
3815 AS1 (rol,%B0) CR_TAB
3816 AS1 (rol,__tmp_reg__) CR_TAB
3817 AS2 (mov,%A0,%B0) CR_TAB
3818 AS2 (mov,%B0,__tmp_reg__));
3820 case 7:
3821 *len = 5;
3822 return (AS1 (lsl,%A0) CR_TAB
3823 AS2 (mov,%A0,%B0) CR_TAB
3824 AS1 (rol,%A0) CR_TAB
3825 AS2 (sbc,%B0,%B0) CR_TAB
3826 AS1 (neg,%B0));
3828 case 8:
3829 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
3830 return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
3831 AS1 (clr,%B0));
3832 else
3833 return *len = 1, AS1 (clr,%B0);
3835 case 9:
3836 *len = 3;
3837 return (AS2 (mov,%A0,%B0) CR_TAB
3838 AS1 (clr,%B0) CR_TAB
3839 AS1 (lsr,%A0));
3841 case 10:
3842 *len = 4;
3843 return (AS2 (mov,%A0,%B0) CR_TAB
3844 AS1 (clr,%B0) CR_TAB
3845 AS1 (lsr,%A0) CR_TAB
3846 AS1 (lsr,%A0));
3848 case 11:
3849 *len = 5;
3850 return (AS2 (mov,%A0,%B0) CR_TAB
3851 AS1 (clr,%B0) CR_TAB
3852 AS1 (lsr,%A0) CR_TAB
3853 AS1 (lsr,%A0) CR_TAB
3854 AS1 (lsr,%A0));
3856 case 12:
3857 if (ldi_ok)
3859 *len = 4;
3860 return (AS2 (mov,%A0,%B0) CR_TAB
3861 AS1 (clr,%B0) CR_TAB
3862 AS1 (swap,%A0) CR_TAB
3863 AS2 (andi,%A0,0x0f));
3865 if (scratch)
3867 *len = 5;
3868 return (AS2 (mov,%A0,%B0) CR_TAB
3869 AS1 (clr,%B0) CR_TAB
3870 AS1 (swap,%A0) CR_TAB
3871 AS2 (ldi,%3,0x0f) CR_TAB
3872 AS2 (and,%A0,%3));
3874 *len = 6;
3875 return (AS2 (mov,%A0,%B0) CR_TAB
3876 AS1 (clr,%B0) CR_TAB
3877 AS1 (lsr,%A0) CR_TAB
3878 AS1 (lsr,%A0) CR_TAB
3879 AS1 (lsr,%A0) CR_TAB
3880 AS1 (lsr,%A0));
3882 case 13:
3883 if (ldi_ok)
3885 *len = 5;
3886 return (AS2 (mov,%A0,%B0) CR_TAB
3887 AS1 (clr,%B0) CR_TAB
3888 AS1 (swap,%A0) CR_TAB
3889 AS1 (lsr,%A0) CR_TAB
3890 AS2 (andi,%A0,0x07));
3892 if (AVR_ENHANCED && scratch)
3894 *len = 5;
3895 return (AS2 (ldi,%3,0x08) CR_TAB
3896 AS2 (mul,%B0,%3) CR_TAB
3897 AS2 (mov,%A0,r1) CR_TAB
3898 AS1 (clr,%B0) CR_TAB
3899 AS1 (clr,__zero_reg__));
3901 if (optimize_size && scratch)
3902 break; /* 5 */
3903 if (scratch)
3905 *len = 6;
3906 return (AS2 (mov,%A0,%B0) CR_TAB
3907 AS1 (clr,%B0) CR_TAB
3908 AS1 (swap,%A0) CR_TAB
3909 AS1 (lsr,%A0) CR_TAB
3910 AS2 (ldi,%3,0x07) CR_TAB
3911 AS2 (and,%A0,%3));
3913 if (AVR_ENHANCED)
3915 *len = 6;
3916 return ("set" CR_TAB
3917 AS2 (bld,r1,3) CR_TAB
3918 AS2 (mul,%B0,r1) CR_TAB
3919 AS2 (mov,%A0,r1) CR_TAB
3920 AS1 (clr,%B0) CR_TAB
3921 AS1 (clr,__zero_reg__));
3923 *len = 7;
3924 return (AS2 (mov,%A0,%B0) CR_TAB
3925 AS1 (clr,%B0) CR_TAB
3926 AS1 (lsr,%A0) CR_TAB
3927 AS1 (lsr,%A0) CR_TAB
3928 AS1 (lsr,%A0) CR_TAB
3929 AS1 (lsr,%A0) CR_TAB
3930 AS1 (lsr,%A0));
3932 case 14:
3933 if (AVR_ENHANCED && ldi_ok)
3935 *len = 5;
3936 return (AS2 (ldi,%A0,0x04) CR_TAB
3937 AS2 (mul,%B0,%A0) CR_TAB
3938 AS2 (mov,%A0,r1) CR_TAB
3939 AS1 (clr,%B0) CR_TAB
3940 AS1 (clr,__zero_reg__));
3942 if (AVR_ENHANCED && scratch)
3944 *len = 5;
3945 return (AS2 (ldi,%3,0x04) CR_TAB
3946 AS2 (mul,%B0,%3) CR_TAB
3947 AS2 (mov,%A0,r1) CR_TAB
3948 AS1 (clr,%B0) CR_TAB
3949 AS1 (clr,__zero_reg__));
3951 if (optimize_size && ldi_ok)
3953 *len = 5;
3954 return (AS2 (mov,%A0,%B0) CR_TAB
3955 AS2 (ldi,%B0,6) "\n1:\t"
3956 AS1 (lsr,%A0) CR_TAB
3957 AS1 (dec,%B0) CR_TAB
3958 AS1 (brne,1b));
3960 if (optimize_size && scratch)
3961 break; /* 5 */
3962 *len = 6;
3963 return (AS1 (clr,%A0) CR_TAB
3964 AS1 (lsl,%B0) CR_TAB
3965 AS1 (rol,%A0) CR_TAB
3966 AS1 (lsl,%B0) CR_TAB
3967 AS1 (rol,%A0) CR_TAB
3968 AS1 (clr,%B0));
3970 case 15:
3971 *len = 4;
3972 return (AS1 (clr,%A0) CR_TAB
3973 AS1 (lsl,%B0) CR_TAB
3974 AS1 (rol,%A0) CR_TAB
3975 AS1 (clr,%B0));
3977 len = t;
3979 out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
3980 AS1 (ror,%A0)),
3981 insn, operands, len, 2);
3982 return "";
3985 /* 32bit logic shift right ((unsigned int)x >> i) */
3987 const char *
3988 lshrsi3_out (rtx insn, rtx operands[], int *len)
3990 if (GET_CODE (operands[2]) == CONST_INT)
3992 int k;
3993 int *t = len;
3995 if (!len)
3996 len = &k;
3998 switch (INTVAL (operands[2]))
4000 case 8:
4002 int reg0 = true_regnum (operands[0]);
4003 int reg1 = true_regnum (operands[1]);
4004 *len = 4;
4005 if (reg0 <= reg1)
4006 return (AS2 (mov,%A0,%B1) CR_TAB
4007 AS2 (mov,%B0,%C1) CR_TAB
4008 AS2 (mov,%C0,%D1) CR_TAB
4009 AS1 (clr,%D0));
4010 else if (reg0 == reg1 + 1)
4011 return *len = 1, AS1 (clr,%D0);
4012 else
4013 return (AS1 (clr,%D0) CR_TAB
4014 AS2 (mov,%C0,%D1) CR_TAB
4015 AS2 (mov,%B0,%C1) CR_TAB
4016 AS2 (mov,%A0,%B1));
4019 case 16:
4021 int reg0 = true_regnum (operands[0]);
4022 int reg1 = true_regnum (operands[1]);
4023 *len = 4;
4024 if (AVR_ENHANCED && (reg0 != reg1 + 2))
4026 *len = 3;
4027 return (AS2 (movw,%A0,%C1) CR_TAB
4028 AS1 (clr,%C0) CR_TAB
4029 AS1 (clr,%D0));
4031 if (reg0 <= reg1 + 1)
4032 return (AS2 (mov,%A0,%C1) CR_TAB
4033 AS2 (mov,%B0,%D1) CR_TAB
4034 AS1 (clr,%C0) CR_TAB
4035 AS1 (clr,%D0));
4036 else if (reg0 == reg1 + 2)
4037 return *len = 2, (AS1 (clr,%C0) CR_TAB
4038 AS1 (clr,%D0));
4039 else
4040 return (AS2 (mov,%B0,%D1) CR_TAB
4041 AS2 (mov,%A0,%C1) CR_TAB
4042 AS1 (clr,%C0) CR_TAB
4043 AS1 (clr,%D0));
4046 case 24:
4047 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
4048 return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4049 AS1 (clr,%B0) CR_TAB
4050 AS1 (clr,%C0) CR_TAB
4051 AS1 (clr,%D0));
4052 else
4053 return *len = 3, (AS1 (clr,%B0) CR_TAB
4054 AS1 (clr,%C0) CR_TAB
4055 AS1 (clr,%D0));
4057 case 31:
4058 *len = 6;
4059 return (AS1 (clr,%A0) CR_TAB
4060 AS2 (sbrc,%D0,7) CR_TAB
4061 AS1 (inc,%A0) CR_TAB
4062 AS1 (clr,%B0) CR_TAB
4063 AS1 (clr,%C0) CR_TAB
4064 AS1 (clr,%D0));
4066 len = t;
4068 out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4069 AS1 (ror,%C0) CR_TAB
4070 AS1 (ror,%B0) CR_TAB
4071 AS1 (ror,%A0)),
4072 insn, operands, len, 4);
4073 return "";
4076 /* Modifies the length assigned to instruction INSN
4077 LEN is the initially computed length of the insn. */
4080 adjust_insn_length (rtx insn, int len)
4082 rtx patt = PATTERN (insn);
4083 rtx set;
4085 if (GET_CODE (patt) == SET)
4087 rtx op[10];
4088 op[1] = SET_SRC (patt);
4089 op[0] = SET_DEST (patt);
4090 if (general_operand (op[1], VOIDmode)
4091 && general_operand (op[0], VOIDmode))
4093 switch (GET_MODE (op[0]))
4095 case QImode:
4096 output_movqi (insn, op, &len);
4097 break;
4098 case HImode:
4099 output_movhi (insn, op, &len);
4100 break;
4101 case SImode:
4102 case SFmode:
4103 output_movsisf (insn, op, &len);
4104 break;
4105 default:
4106 break;
4109 else if (op[0] == cc0_rtx && REG_P (op[1]))
4111 switch (GET_MODE (op[1]))
4113 case HImode: out_tsthi (insn,&len); break;
4114 case SImode: out_tstsi (insn,&len); break;
4115 default: break;
4118 else if (GET_CODE (op[1]) == AND)
4120 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4122 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4123 if (GET_MODE (op[1]) == SImode)
4124 len = (((mask & 0xff) != 0xff)
4125 + ((mask & 0xff00) != 0xff00)
4126 + ((mask & 0xff0000L) != 0xff0000L)
4127 + ((mask & 0xff000000L) != 0xff000000L));
4128 else if (GET_MODE (op[1]) == HImode)
4129 len = (((mask & 0xff) != 0xff)
4130 + ((mask & 0xff00) != 0xff00));
4133 else if (GET_CODE (op[1]) == IOR)
4135 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4137 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4138 if (GET_MODE (op[1]) == SImode)
4139 len = (((mask & 0xff) != 0)
4140 + ((mask & 0xff00) != 0)
4141 + ((mask & 0xff0000L) != 0)
4142 + ((mask & 0xff000000L) != 0));
4143 else if (GET_MODE (op[1]) == HImode)
4144 len = (((mask & 0xff) != 0)
4145 + ((mask & 0xff00) != 0));
4149 set = single_set (insn);
4150 if (set)
4152 rtx op[10];
4154 op[1] = SET_SRC (set);
4155 op[0] = SET_DEST (set);
4157 if (GET_CODE (patt) == PARALLEL
4158 && general_operand (op[1], VOIDmode)
4159 && general_operand (op[0], VOIDmode))
4161 if (XVECLEN (patt, 0) == 2)
4162 op[2] = XVECEXP (patt, 0, 1);
4164 switch (GET_MODE (op[0]))
4166 case QImode:
4167 len = 2;
4168 break;
4169 case HImode:
4170 output_reload_inhi (insn, op, &len);
4171 break;
4172 case SImode:
4173 case SFmode:
4174 output_reload_insisf (insn, op, &len);
4175 break;
4176 default:
4177 break;
4180 else if (GET_CODE (op[1]) == ASHIFT
4181 || GET_CODE (op[1]) == ASHIFTRT
4182 || GET_CODE (op[1]) == LSHIFTRT)
4184 rtx ops[10];
4185 ops[0] = op[0];
4186 ops[1] = XEXP (op[1],0);
4187 ops[2] = XEXP (op[1],1);
4188 switch (GET_CODE (op[1]))
4190 case ASHIFT:
4191 switch (GET_MODE (op[0]))
4193 case QImode: ashlqi3_out (insn,ops,&len); break;
4194 case HImode: ashlhi3_out (insn,ops,&len); break;
4195 case SImode: ashlsi3_out (insn,ops,&len); break;
4196 default: break;
4198 break;
4199 case ASHIFTRT:
4200 switch (GET_MODE (op[0]))
4202 case QImode: ashrqi3_out (insn,ops,&len); break;
4203 case HImode: ashrhi3_out (insn,ops,&len); break;
4204 case SImode: ashrsi3_out (insn,ops,&len); break;
4205 default: break;
4207 break;
4208 case LSHIFTRT:
4209 switch (GET_MODE (op[0]))
4211 case QImode: lshrqi3_out (insn,ops,&len); break;
4212 case HImode: lshrhi3_out (insn,ops,&len); break;
4213 case SImode: lshrsi3_out (insn,ops,&len); break;
4214 default: break;
4216 break;
4217 default:
4218 break;
4222 return len;
4225 /* Return nonzero if register REG dead after INSN. */
4228 reg_unused_after (rtx insn, rtx reg)
4230 return (dead_or_set_p (insn, reg)
4231 || (REG_P(reg) && _reg_unused_after (insn, reg)));
4234 /* Return nonzero if REG is not used after INSN.
4235 We assume REG is a reload reg, and therefore does
4236 not live past labels. It may live past calls or jumps though. */
4239 _reg_unused_after (rtx insn, rtx reg)
4241 enum rtx_code code;
4242 rtx set;
4244 /* If the reg is set by this instruction, then it is safe for our
4245 case. Disregard the case where this is a store to memory, since
4246 we are checking a register used in the store address. */
4247 set = single_set (insn);
4248 if (set && GET_CODE (SET_DEST (set)) != MEM
4249 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4250 return 1;
4252 while ((insn = NEXT_INSN (insn)))
4254 rtx set;
4255 code = GET_CODE (insn);
4257 #if 0
4258 /* If this is a label that existed before reload, then the register
4259 if dead here. However, if this is a label added by reorg, then
4260 the register may still be live here. We can't tell the difference,
4261 so we just ignore labels completely. */
4262 if (code == CODE_LABEL)
4263 return 1;
4264 /* else */
4265 #endif
4267 if (!INSN_P (insn))
4268 continue;
4270 if (code == JUMP_INSN)
4271 return 0;
4273 /* If this is a sequence, we must handle them all at once.
4274 We could have for instance a call that sets the target register,
4275 and an insn in a delay slot that uses the register. In this case,
4276 we must return 0. */
4277 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
4279 int i;
4280 int retval = 0;
4282 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
4284 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
4285 rtx set = single_set (this_insn);
4287 if (GET_CODE (this_insn) == CALL_INSN)
4288 code = CALL_INSN;
4289 else if (GET_CODE (this_insn) == JUMP_INSN)
4291 if (INSN_ANNULLED_BRANCH_P (this_insn))
4292 return 0;
4293 code = JUMP_INSN;
4296 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4297 return 0;
4298 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4300 if (GET_CODE (SET_DEST (set)) != MEM)
4301 retval = 1;
4302 else
4303 return 0;
4305 if (set == 0
4306 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
4307 return 0;
4309 if (retval == 1)
4310 return 1;
4311 else if (code == JUMP_INSN)
4312 return 0;
4315 if (code == CALL_INSN)
4317 rtx tem;
4318 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4319 if (GET_CODE (XEXP (tem, 0)) == USE
4320 && REG_P (XEXP (XEXP (tem, 0), 0))
4321 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
4322 return 0;
4323 if (call_used_regs[REGNO (reg)])
4324 return 1;
4327 set = single_set (insn);
4329 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4330 return 0;
4331 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4332 return GET_CODE (SET_DEST (set)) != MEM;
4333 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
4334 return 0;
4336 return 1;
4339 /* Target hook for assembling integer objects. The AVR version needs
4340 special handling for references to certain labels. */
4342 static bool
4343 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
4345 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
4346 && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x))
4347 || GET_CODE (x) == LABEL_REF))
4349 fputs ("\t.word\tpm(", asm_out_file);
4350 output_addr_const (asm_out_file, x);
4351 fputs (")\n", asm_out_file);
4352 return true;
4354 return default_assemble_integer (x, size, aligned_p);
4357 /* Sets section name for declaration DECL. */
4359 static void
4360 avr_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
4362 int len;
4363 const char *name, *prefix;
4364 char *string;
4366 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
4367 name = (* targetm.strip_name_encoding) (name);
4369 if (TREE_CODE (decl) == FUNCTION_DECL)
4371 if (flag_function_sections)
4372 prefix = ".text.";
4373 else
4374 prefix = ".text";
4376 else
4377 abort ();
4379 if (flag_function_sections)
4381 len = strlen (name) + strlen (prefix);
4382 string = alloca (len + 1);
4383 sprintf (string, "%s%s", prefix, name);
4384 DECL_SECTION_NAME (decl) = build_string (len, string);
4389 /* The routine used to output NUL terminated strings. We use a special
4390 version of this for most svr4 targets because doing so makes the
4391 generated assembly code more compact (and thus faster to assemble)
4392 as well as more readable, especially for targets like the i386
4393 (where the only alternative is to output character sequences as
4394 comma separated lists of numbers). */
4396 void
4397 gas_output_limited_string(FILE *file, const char *str)
4399 const unsigned char *_limited_str = (unsigned char *) str;
4400 unsigned ch;
4401 fprintf (file, "%s\"", STRING_ASM_OP);
4402 for (; (ch = *_limited_str); _limited_str++)
4404 int escape;
4405 switch (escape = ESCAPES[ch])
4407 case 0:
4408 putc (ch, file);
4409 break;
4410 case 1:
4411 fprintf (file, "\\%03o", ch);
4412 break;
4413 default:
4414 putc ('\\', file);
4415 putc (escape, file);
4416 break;
4419 fprintf (file, "\"\n");
4422 /* The routine used to output sequences of byte values. We use a special
4423 version of this for most svr4 targets because doing so makes the
4424 generated assembly code more compact (and thus faster to assemble)
4425 as well as more readable. Note that if we find subparts of the
4426 character sequence which end with NUL (and which are shorter than
4427 STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
4429 void
4430 gas_output_ascii(FILE *file, const char *str, size_t length)
4432 const unsigned char *_ascii_bytes = (const unsigned char *) str;
4433 const unsigned char *limit = _ascii_bytes + length;
4434 unsigned bytes_in_chunk = 0;
4435 for (; _ascii_bytes < limit; _ascii_bytes++)
4437 const unsigned char *p;
4438 if (bytes_in_chunk >= 60)
4440 fprintf (file, "\"\n");
4441 bytes_in_chunk = 0;
4443 for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
4444 continue;
4445 if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
4447 if (bytes_in_chunk > 0)
4449 fprintf (file, "\"\n");
4450 bytes_in_chunk = 0;
4452 gas_output_limited_string (file, (char*)_ascii_bytes);
4453 _ascii_bytes = p;
4455 else
4457 int escape;
4458 unsigned ch;
4459 if (bytes_in_chunk == 0)
4460 fprintf (file, "\t.ascii\t\"");
4461 switch (escape = ESCAPES[ch = *_ascii_bytes])
4463 case 0:
4464 putc (ch, file);
4465 bytes_in_chunk++;
4466 break;
4467 case 1:
4468 fprintf (file, "\\%03o", ch);
4469 bytes_in_chunk += 4;
4470 break;
4471 default:
4472 putc ('\\', file);
4473 putc (escape, file);
4474 bytes_in_chunk += 2;
4475 break;
4479 if (bytes_in_chunk > 0)
4480 fprintf (file, "\"\n");
4483 /* Return value is nonzero if pseudos that have been
4484 assigned to registers of class CLASS would likely be spilled
4485 because registers of CLASS are needed for spill registers. */
4487 enum reg_class
4488 class_likely_spilled_p (int c)
4490 return (c != ALL_REGS && c != ADDW_REGS);
4493 /* Valid attributes:
4494 progmem - put data to program memory;
4495 signal - make a function to be hardware interrupt. After function
4496 prologue interrupts are disabled;
4497 interrupt - make a function to be hardware interrupt. After function
4498 prologue interrupts are enabled;
4499 naked - don't generate function prologue/epilogue and `ret' command.
4501 Only `progmem' attribute valid for type. */
4503 const struct attribute_spec avr_attribute_table[] =
4505 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
4506 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute },
4507 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4508 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4509 { "naked", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4510 { NULL, 0, 0, false, false, false, NULL }
4513 /* Handle a "progmem" attribute; arguments as in
4514 struct attribute_spec.handler. */
4515 static tree
4516 avr_handle_progmem_attribute (tree *node, tree name,
4517 tree args ATTRIBUTE_UNUSED,
4518 int flags ATTRIBUTE_UNUSED,
4519 bool *no_add_attrs)
4521 if (DECL_P (*node))
4523 if (TREE_CODE (*node) == TYPE_DECL)
4525 /* This is really a decl attribute, not a type attribute,
4526 but try to handle it for GCC 3.0 backwards compatibility. */
4528 tree type = TREE_TYPE (*node);
4529 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
4530 tree newtype = build_type_attribute_variant (type, attr);
4532 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
4533 TREE_TYPE (*node) = newtype;
4534 *no_add_attrs = true;
4536 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
4538 if (DECL_INITIAL (*node) == NULL_TREE && !DECL_EXTERNAL (*node))
4540 warning ("only initialized variables can be placed into "
4541 "program memory area");
4542 *no_add_attrs = true;
4545 else
4547 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
4548 *no_add_attrs = true;
4552 return NULL_TREE;
4555 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
4556 struct attribute_spec.handler. */
4558 static tree
4559 avr_handle_fndecl_attribute (tree *node, tree name,
4560 tree args ATTRIBUTE_UNUSED,
4561 int flags ATTRIBUTE_UNUSED,
4562 bool *no_add_attrs)
4564 if (TREE_CODE (*node) != FUNCTION_DECL)
4566 warning ("`%s' attribute only applies to functions",
4567 IDENTIFIER_POINTER (name));
4568 *no_add_attrs = true;
4571 return NULL_TREE;
4574 /* Look for attribute `progmem' in DECL
4575 if found return 1, otherwise 0. */
4578 avr_progmem_p (tree decl, tree attributes)
4580 tree a;
4582 if (TREE_CODE (decl) != VAR_DECL)
4583 return 0;
4585 if (NULL_TREE
4586 != lookup_attribute ("progmem", attributes))
4587 return 1;
4589 a=decl;
4591 a = TREE_TYPE(a);
4592 while (TREE_CODE (a) == ARRAY_TYPE);
4594 if (a == error_mark_node)
4595 return 0;
4597 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
4598 return 1;
4600 return 0;
4603 /* Add the section attribute if the variable is in progmem. */
4605 static void
4606 avr_insert_attributes (tree node, tree *attributes)
4608 if (TREE_CODE (node) == VAR_DECL
4609 && (TREE_STATIC (node) || DECL_EXTERNAL (node))
4610 && avr_progmem_p (node, *attributes))
4612 static const char dsec[] = ".progmem.data";
4613 *attributes = tree_cons (get_identifier ("section"),
4614 build_tree_list (NULL, build_string (strlen (dsec), dsec)),
4615 *attributes);
4617 /* ??? This seems sketchy. Why can't the user declare the
4618 thing const in the first place? */
4619 TREE_READONLY (node) = 1;
4623 static unsigned int
4624 avr_section_type_flags (tree decl, const char *name, int reloc)
4626 unsigned int flags = default_section_type_flags (decl, name, reloc);
4628 if (strncmp (name, ".noinit", 7) == 0)
4630 if (decl && TREE_CODE (decl) == VAR_DECL
4631 && DECL_INITIAL (decl) == NULL_TREE)
4632 flags |= SECTION_BSS; /* @nobits */
4633 else
4634 warning ("only uninitialized variables can be placed in the "
4635 ".noinit section");
4638 return flags;
4641 /* Outputs some appropriate text to go at the start of an assembler
4642 file. */
4644 static void
4645 avr_file_start (void)
4647 if (avr_asm_only_p)
4648 error ("MCU `%s' supported for assembler only", avr_mcu_name);
4650 default_file_start ();
4652 fprintf (asm_out_file, "\t.arch %s\n", avr_mcu_name);
4653 fputs ("__SREG__ = 0x3f\n"
4654 "__SP_H__ = 0x3e\n"
4655 "__SP_L__ = 0x3d\n", asm_out_file);
4657 fputs ("__tmp_reg__ = 0\n"
4658 "__zero_reg__ = 1\n", asm_out_file);
4660 /* FIXME: output these only if there is anything in the .data / .bss
4661 sections - some code size could be saved by not linking in the
4662 initialization code from libgcc if one or both sections are empty. */
4663 fputs ("\t.global __do_copy_data\n", asm_out_file);
4664 fputs ("\t.global __do_clear_bss\n", asm_out_file);
4666 commands_in_file = 0;
4667 commands_in_prologues = 0;
4668 commands_in_epilogues = 0;
4671 /* Outputs to the stdio stream FILE some
4672 appropriate text to go at the end of an assembler file. */
4674 static void
4675 avr_file_end (void)
4677 fputs ("/* File ", asm_out_file);
4678 output_quoted_string (asm_out_file, main_input_filename);
4679 fprintf (asm_out_file,
4680 ": code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
4681 commands_in_file,
4682 commands_in_file,
4683 commands_in_file - commands_in_prologues - commands_in_epilogues,
4684 commands_in_prologues, commands_in_epilogues);
4687 /* Choose the order in which to allocate hard registers for
4688 pseudo-registers local to a basic block.
4690 Store the desired register order in the array `reg_alloc_order'.
4691 Element 0 should be the register to allocate first; element 1, the
4692 next register; and so on. */
4694 void
4695 order_regs_for_local_alloc (void)
4697 unsigned int i;
4698 static const int order_0[] = {
4699 24,25,
4700 18,19,
4701 20,21,
4702 22,23,
4703 30,31,
4704 26,27,
4705 28,29,
4706 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4707 0,1,
4708 32,33,34,35
4710 static const int order_1[] = {
4711 18,19,
4712 20,21,
4713 22,23,
4714 24,25,
4715 30,31,
4716 26,27,
4717 28,29,
4718 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4719 0,1,
4720 32,33,34,35
4722 static const int order_2[] = {
4723 25,24,
4724 23,22,
4725 21,20,
4726 19,18,
4727 30,31,
4728 26,27,
4729 28,29,
4730 17,16,
4731 15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4732 1,0,
4733 32,33,34,35
4736 const int *order = (TARGET_ORDER_1 ? order_1 :
4737 TARGET_ORDER_2 ? order_2 :
4738 order_0);
4739 for (i=0; i < ARRAY_SIZE (order_0); ++i)
4740 reg_alloc_order[i] = order[i];
4743 /* Calculate the cost of X code of the expression in which it is contained,
4744 found in OUTER_CODE */
4746 static int
4747 default_rtx_costs (rtx X, enum rtx_code code, enum rtx_code outer_code)
4749 int cost=0;
4750 switch (code)
4752 case SYMBOL_REF:
4753 case LABEL_REF:
4754 cost = 2 * GET_MODE_SIZE (GET_MODE (X));
4755 break;
4756 case MEM:
4757 if (outer_code != SET)
4758 cost = 1;
4759 if (GET_CODE (XEXP (X,0)) == SYMBOL_REF)
4760 cost += 2 * GET_MODE_SIZE (GET_MODE (X));
4761 else
4762 cost += GET_MODE_SIZE (GET_MODE (X));
4763 break;
4764 case CONST_INT:
4765 cost = 0;
4766 break;
4767 case SIGN_EXTEND:
4768 if (outer_code == SET)
4769 cost = GET_MODE_SIZE (GET_MODE (X));
4770 else
4771 cost = -GET_MODE_SIZE (GET_MODE (X));
4772 break;
4773 case ZERO_EXTEND:
4774 if (outer_code == SET)
4775 cost = GET_MODE_SIZE (GET_MODE (X));
4776 else
4777 cost = -1;
4778 break;
4779 case PLUS:
4780 case MINUS:
4781 if (outer_code == SET)
4783 if (X == stack_pointer_rtx)
4784 cost = -10;
4785 else if (GET_CODE (XEXP (X,1)) == CONST_INT)
4786 cost = (INTVAL (XEXP (X,1)) <= 63 ? 1 :
4787 GET_MODE_SIZE (GET_MODE (X)));
4788 else
4789 cost = GET_MODE_SIZE (GET_MODE (X));
4791 break;
4792 case COMPARE:
4793 if (GET_CODE (XEXP (X,1)) == CONST_INT)
4794 cost = GET_MODE_SIZE (GET_MODE (XEXP (X,0)));
4795 break;
4796 default:
4797 break;
4799 return cost;
4802 static bool
4803 avr_rtx_costs (rtx x, int code, int outer_code, int *total)
4805 int cst;
4807 switch (code)
4809 case CONST_INT:
4810 if (outer_code == PLUS
4811 || outer_code == IOR
4812 || outer_code == AND
4813 || outer_code == MINUS
4814 || outer_code == SET
4815 || INTVAL (x) == 0)
4817 *total = 2;
4818 return true;
4820 if (outer_code == COMPARE
4821 && INTVAL (x) >= 0
4822 && INTVAL (x) <= 255)
4824 *total = 2;
4825 return true;
4827 /* FALLTHRU */
4829 case CONST:
4830 case LABEL_REF:
4831 case SYMBOL_REF:
4832 case CONST_DOUBLE:
4833 *total = 4;
4834 return true;
4836 default:
4837 cst = default_rtx_costs (x, code, outer_code);
4838 if (cst > 0)
4840 *total = cst;
4841 return true;
4843 else if (cst < 0)
4844 *total += -cst;
4845 return false;
4849 /* Calculate the cost of a memory address. */
4851 static int
4852 avr_address_cost (rtx x)
4854 if (GET_CODE (x) == PLUS
4855 && GET_CODE (XEXP (x,1)) == CONST_INT
4856 && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
4857 && INTVAL (XEXP (x,1)) >= 61)
4858 return 18;
4859 if (CONSTANT_ADDRESS_P (x))
4861 if (avr_io_address_p (x, 1))
4862 return 2;
4863 return 4;
4865 return 4;
4868 /* EXTRA_CONSTRAINT helper */
4871 extra_constraint (rtx x, int c)
4873 if (c == 'Q'
4874 && GET_CODE (x) == MEM
4875 && GET_CODE (XEXP (x,0)) == PLUS)
4877 if (TARGET_ALL_DEBUG)
4879 fprintf (stderr, ("extra_constraint:\n"
4880 "reload_completed: %d\n"
4881 "reload_in_progress: %d\n"),
4882 reload_completed, reload_in_progress);
4883 debug_rtx (x);
4885 if (GET_CODE (x) == MEM
4886 && GET_CODE (XEXP (x,0)) == PLUS
4887 && REG_P (XEXP (XEXP (x,0), 0))
4888 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
4889 && (INTVAL (XEXP (XEXP (x,0), 1))
4890 <= MAX_LD_OFFSET (GET_MODE (x))))
4892 rtx xx = XEXP (XEXP (x,0), 0);
4893 int regno = REGNO (xx);
4894 if (TARGET_ALL_DEBUG)
4896 fprintf (stderr, ("extra_constraint:\n"
4897 "reload_completed: %d\n"
4898 "reload_in_progress: %d\n"),
4899 reload_completed, reload_in_progress);
4900 debug_rtx (x);
4902 if (regno >= FIRST_PSEUDO_REGISTER)
4903 return 1; /* allocate pseudos */
4904 else if (regno == REG_Z || regno == REG_Y)
4905 return 1; /* strictly check */
4906 else if (xx == frame_pointer_rtx
4907 || xx == arg_pointer_rtx)
4908 return 1; /* XXX frame & arg pointer checks */
4911 return 0;
4914 /* Convert condition code CONDITION to the valid AVR condition code. */
4916 RTX_CODE
4917 avr_normalize_condition (RTX_CODE condition)
4919 switch (condition)
4921 case GT:
4922 return GE;
4923 case GTU:
4924 return GEU;
4925 case LE:
4926 return LT;
4927 case LEU:
4928 return LTU;
4929 default:
4930 abort ();
4934 /* This function optimizes conditional jumps. */
4936 static void
4937 avr_reorg (void)
4939 rtx insn, pattern;
4941 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4943 if (! (GET_CODE (insn) == INSN
4944 || GET_CODE (insn) == CALL_INSN
4945 || GET_CODE (insn) == JUMP_INSN)
4946 || !single_set (insn))
4947 continue;
4949 pattern = PATTERN (insn);
4951 if (GET_CODE (pattern) == PARALLEL)
4952 pattern = XVECEXP (pattern, 0, 0);
4953 if (GET_CODE (pattern) == SET
4954 && SET_DEST (pattern) == cc0_rtx
4955 && compare_diff_p (insn))
4957 if (GET_CODE (SET_SRC (pattern)) == COMPARE)
4959 /* Now we work under compare insn. */
4961 pattern = SET_SRC (pattern);
4962 if (true_regnum (XEXP (pattern,0)) >= 0
4963 && true_regnum (XEXP (pattern,1)) >= 0 )
4965 rtx x = XEXP (pattern,0);
4966 rtx next = next_real_insn (insn);
4967 rtx pat = PATTERN (next);
4968 rtx src = SET_SRC (pat);
4969 rtx t = XEXP (src,0);
4970 PUT_CODE (t, swap_condition (GET_CODE (t)));
4971 XEXP (pattern,0) = XEXP (pattern,1);
4972 XEXP (pattern,1) = x;
4973 INSN_CODE (next) = -1;
4975 else if (true_regnum (XEXP (pattern,0)) >= 0
4976 && GET_CODE (XEXP (pattern,1)) == CONST_INT)
4978 rtx x = XEXP (pattern,1);
4979 rtx next = next_real_insn (insn);
4980 rtx pat = PATTERN (next);
4981 rtx src = SET_SRC (pat);
4982 rtx t = XEXP (src,0);
4983 enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
4985 if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
4987 XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
4988 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
4989 INSN_CODE (next) = -1;
4990 INSN_CODE (insn) = -1;
4994 else if (true_regnum (SET_SRC (pattern)) >= 0)
4996 /* This is a tst insn */
4997 rtx next = next_real_insn (insn);
4998 rtx pat = PATTERN (next);
4999 rtx src = SET_SRC (pat);
5000 rtx t = XEXP (src,0);
5002 PUT_CODE (t, swap_condition (GET_CODE (t)));
5003 SET_SRC (pattern) = gen_rtx_NEG (GET_MODE (SET_SRC (pattern)),
5004 SET_SRC (pattern));
5005 INSN_CODE (next) = -1;
5006 INSN_CODE (insn) = -1;
5012 /* Returns register number for function return value.*/
5015 avr_ret_register (void)
5017 return 24;
5020 /* Ceate an RTX representing the place where a
5021 library function returns a value of mode MODE. */
5024 avr_libcall_value (enum machine_mode mode)
5026 int offs = GET_MODE_SIZE (mode);
5027 if (offs < 2)
5028 offs = 2;
5029 return gen_rtx_REG (mode, RET_REGISTER + 2 - offs);
5032 /* Create an RTX representing the place where a
5033 function returns a value of data type VALTYPE. */
5036 avr_function_value (tree type, tree func ATTRIBUTE_UNUSED)
5038 unsigned int offs;
5040 if (TYPE_MODE (type) != BLKmode)
5041 return avr_libcall_value (TYPE_MODE (type));
5043 offs = int_size_in_bytes (type);
5044 if (offs < 2)
5045 offs = 2;
5046 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
5047 offs = GET_MODE_SIZE (SImode);
5048 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
5049 offs = GET_MODE_SIZE (DImode);
5051 return gen_rtx_REG (BLKmode, RET_REGISTER + 2 - offs);
5054 /* Returns nonzero if the number MASK has only one bit set. */
5057 mask_one_bit_p (HOST_WIDE_INT mask)
5059 int i;
5060 unsigned HOST_WIDE_INT n=mask;
5061 for (i = 0; i < 32; ++i)
5063 if (n & 0x80000000L)
5065 if (n & 0x7fffffffL)
5066 return 0;
5067 else
5068 return 32-i;
5070 n<<=1;
5072 return 0;
5076 /* Places additional restrictions on the register class to
5077 use when it is necessary to copy value X into a register
5078 in class CLASS. */
5080 enum reg_class
5081 preferred_reload_class (rtx x ATTRIBUTE_UNUSED, enum reg_class class)
5083 return class;
5087 test_hard_reg_class (enum reg_class class, rtx x)
5089 int regno = true_regnum (x);
5090 if (regno < 0)
5091 return 0;
5093 if (TEST_HARD_REG_CLASS (class, regno))
5094 return 1;
5096 return 0;
5101 jump_over_one_insn_p (rtx insn, rtx dest)
5103 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
5104 ? XEXP (dest, 0)
5105 : dest);
5106 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
5107 int dest_addr = INSN_ADDRESSES (uid);
5108 return dest_addr - jump_addr == get_attr_length (insn) + 1;
5111 /* Returns 1 if a value of mode MODE can be stored starting with hard
5112 register number REGNO. On the enhanced core, anything larger than
5113 1 byte must start in even numbered register for "movw" to work
5114 (this way we don't have to check for odd registers everywhere). */
5117 avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
5119 /* Bug workaround: recog.c (peep2_find_free_register) and probably
5120 a few other places assume that the frame pointer is a single hard
5121 register, so r29 may be allocated and overwrite the high byte of
5122 the frame pointer. Do not allow any value to start in r29. */
5123 if (regno == REG_Y + 1)
5124 return 0;
5126 if (mode == QImode)
5127 return 1;
5128 /* if (regno < 24 && !AVR_ENHANCED)
5129 return 1;*/
5130 return !(regno & 1);
5133 /* Returns 1 if X is a valid address for an I/O register of size SIZE
5134 (1 or 2). Used for lds/sts -> in/out optimization. Add 0x20 to SIZE
5135 to check for the lower half of I/O space (for cbi/sbi/sbic/sbis). */
5138 avr_io_address_p (rtx x, int size)
5140 return (optimize > 0 && GET_CODE (x) == CONST_INT
5141 && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size);
5144 /* Returns nonzero (bit number + 1) if X, or -X, is a constant power of 2. */
5147 const_int_pow2_p (rtx x)
5149 if (GET_CODE (x) == CONST_INT)
5151 HOST_WIDE_INT d = INTVAL (x);
5152 HOST_WIDE_INT abs_d = (d >= 0) ? d : -d;
5153 return exact_log2 (abs_d) + 1;
5155 return 0;
5158 const char *
5159 output_reload_inhi (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
5161 int tmp;
5162 if (!len)
5163 len = &tmp;
5165 if (GET_CODE (operands[1]) == CONST_INT)
5167 int val = INTVAL (operands[1]);
5168 if ((val & 0xff) == 0)
5170 *len = 3;
5171 return (AS2 (mov,%A0,__zero_reg__) CR_TAB
5172 AS2 (ldi,%2,hi8(%1)) CR_TAB
5173 AS2 (mov,%B0,%2));
5175 else if ((val & 0xff00) == 0)
5177 *len = 3;
5178 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5179 AS2 (mov,%A0,%2) CR_TAB
5180 AS2 (mov,%B0,__zero_reg__));
5182 else if ((val & 0xff) == ((val & 0xff00) >> 8))
5184 *len = 3;
5185 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5186 AS2 (mov,%A0,%2) CR_TAB
5187 AS2 (mov,%B0,%2));
5190 *len = 4;
5191 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5192 AS2 (mov,%A0,%2) CR_TAB
5193 AS2 (ldi,%2,hi8(%1)) CR_TAB
5194 AS2 (mov,%B0,%2));
5198 const char *
5199 output_reload_insisf (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
5201 rtx src = operands[1];
5202 int cnst = (GET_CODE (src) == CONST_INT);
5204 if (len)
5206 if (cnst)
5207 *len = 4 + ((INTVAL (src) & 0xff) != 0)
5208 + ((INTVAL (src) & 0xff00) != 0)
5209 + ((INTVAL (src) & 0xff0000) != 0)
5210 + ((INTVAL (src) & 0xff000000) != 0);
5211 else
5212 *len = 8;
5214 return "";
5217 if (cnst && ((INTVAL (src) & 0xff) == 0))
5218 output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
5219 else
5221 output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
5222 output_asm_insn (AS2 (mov, %A0, %2), operands);
5224 if (cnst && ((INTVAL (src) & 0xff00) == 0))
5225 output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
5226 else
5228 output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
5229 output_asm_insn (AS2 (mov, %B0, %2), operands);
5231 if (cnst && ((INTVAL (src) & 0xff0000) == 0))
5232 output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
5233 else
5235 output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
5236 output_asm_insn (AS2 (mov, %C0, %2), operands);
5238 if (cnst && ((INTVAL (src) & 0xff000000) == 0))
5239 output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
5240 else
5242 output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
5243 output_asm_insn (AS2 (mov, %D0, %2), operands);
5245 return "";
5248 void
5249 avr_output_bld (rtx operands[], int bit_nr)
5251 static char s[] = "bld %A0,0";
5253 s[5] = 'A' + (bit_nr >> 3);
5254 s[8] = '0' + (bit_nr & 7);
5255 output_asm_insn (s, operands);
5258 void
5259 avr_output_addr_vec_elt (FILE *stream, int value)
5261 if (AVR_MEGA)
5262 fprintf (stream, "\t.word pm(.L%d)\n", value);
5263 else
5264 fprintf (stream, "\trjmp .L%d\n", value);
5266 jump_tables_size++;
5269 /* Returns 1 if SCRATCH are safe to be allocated as a scratch
5270 registers (for a define_peephole2) in the current function. */
5273 avr_peep2_scratch_safe (rtx scratch)
5275 if ((interrupt_function_p (current_function_decl)
5276 || signal_function_p (current_function_decl))
5277 && leaf_function_p ())
5279 int first_reg = true_regnum (scratch);
5280 int last_reg = first_reg + GET_MODE_SIZE (GET_MODE (scratch)) - 1;
5281 int reg;
5283 for (reg = first_reg; reg <= last_reg; reg++)
5285 if (!regs_ever_live[reg])
5286 return 0;
5289 return 1;
5292 /* Output a branch that tests a single bit of a register (QI, HI or SImode)
5293 or memory location in the I/O space (QImode only).
5295 Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
5296 Operand 1: register operand to test, or CONST_INT memory address.
5297 Operand 2: bit number (for QImode operand) or mask (HImode, SImode).
5298 Operand 3: label to jump to if the test is true. */
5300 const char *
5301 avr_out_sbxx_branch (rtx insn, rtx operands[])
5303 enum rtx_code comp = GET_CODE (operands[0]);
5304 int long_jump = (get_attr_length (insn) >= 4);
5305 int reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
5307 if (comp == GE)
5308 comp = EQ;
5309 else if (comp == LT)
5310 comp = NE;
5312 if (reverse)
5313 comp = reverse_condition (comp);
5315 if (GET_CODE (operands[1]) == CONST_INT)
5317 if (INTVAL (operands[1]) < 0x40)
5319 if (comp == EQ)
5320 output_asm_insn (AS2 (sbis,%1-0x20,%2), operands);
5321 else
5322 output_asm_insn (AS2 (sbic,%1-0x20,%2), operands);
5324 else
5326 output_asm_insn (AS2 (in,__tmp_reg__,%1-0x20), operands);
5327 if (comp == EQ)
5328 output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands);
5329 else
5330 output_asm_insn (AS2 (sbrc,__tmp_reg__,%2), operands);
5333 else /* GET_CODE (operands[1]) == REG */
5335 if (GET_MODE (operands[1]) == QImode)
5337 if (comp == EQ)
5338 output_asm_insn (AS2 (sbrs,%1,%2), operands);
5339 else
5340 output_asm_insn (AS2 (sbrc,%1,%2), operands);
5342 else /* HImode or SImode */
5344 static char buf[] = "sbrc %A1,0";
5345 int bit_nr = exact_log2 (INTVAL (operands[2])
5346 & GET_MODE_MASK (GET_MODE (operands[1])));
5348 buf[3] = (comp == EQ) ? 's' : 'c';
5349 buf[6] = 'A' + (bit_nr >> 3);
5350 buf[9] = '0' + (bit_nr & 7);
5351 output_asm_insn (buf, operands);
5355 if (long_jump)
5356 return (AS1 (rjmp,.+4) CR_TAB
5357 AS1 (jmp,%3));
5358 if (!reverse)
5359 return AS1 (rjmp,%3);
5360 return "";
5363 /* Worker function for TARGET_ASM_CONSTRUCTOR. */
5365 static void
5366 avr_asm_out_ctor (rtx symbol, int priority)
5368 fputs ("\t.global __do_global_ctors\n", asm_out_file);
5369 default_ctor_section_asm_out_constructor (symbol, priority);
5372 /* Worker function for TARGET_ASM_DESTRUCTOR. */
5374 static void
5375 avr_asm_out_dtor (rtx symbol, int priority)
5377 fputs ("\t.global __do_global_dtors\n", asm_out_file);
5378 default_dtor_section_asm_out_destructor (symbol, priority);
5381 /* Worker function for TARGET_RETURN_IN_MEMORY. */
5383 static bool
5384 avr_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
5386 if (TYPE_MODE (type) == BLKmode)
5388 HOST_WIDE_INT size = int_size_in_bytes (type);
5389 return (size == -1 || size > 8);
5391 else
5392 return false;
5395 #include "gt-avr.h"