Merge from mainline.
[official-gcc.git] / gcc / config / avr / avr.c
blob2f981dd9738cb1bed77db0683b0e45012675bf08
1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006
3 Free Software Foundation, Inc.
4 Contributed by Denis Chertykov (denisc@overta.ru)
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "real.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "insn-attr.h"
34 #include "flags.h"
35 #include "reload.h"
36 #include "tree.h"
37 #include "output.h"
38 #include "expr.h"
39 #include "toplev.h"
40 #include "obstack.h"
41 #include "function.h"
42 #include "recog.h"
43 #include "ggc.h"
44 #include "tm_p.h"
45 #include "target.h"
46 #include "target-def.h"
48 /* Maximal allowed offset for an address in the LD command */
49 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
51 static int avr_naked_function_p (tree);
52 static int interrupt_function_p (tree);
53 static int signal_function_p (tree);
54 static int avr_regs_to_save (HARD_REG_SET *);
55 static int sequent_regs_live (void);
56 static const char *ptrreg_to_str (int);
57 static const char *cond_string (enum rtx_code);
58 static int avr_num_arg_regs (enum machine_mode, tree);
59 static int out_adj_frame_ptr (FILE *, int);
60 static int out_set_stack_ptr (FILE *, int, int);
61 static RTX_CODE compare_condition (rtx insn);
62 static int compare_sign_p (rtx insn);
63 static tree avr_handle_progmem_attribute (tree *, tree, tree, int, bool *);
64 static tree avr_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
65 const struct attribute_spec avr_attribute_table[];
66 static bool avr_assemble_integer (rtx, unsigned int, int);
67 static void avr_file_start (void);
68 static void avr_file_end (void);
69 static void avr_output_function_prologue (FILE *, HOST_WIDE_INT);
70 static void avr_output_function_epilogue (FILE *, HOST_WIDE_INT);
71 static void avr_insert_attributes (tree, tree *);
72 static void avr_asm_init_sections (void);
73 static unsigned int avr_section_type_flags (tree, const char *, int);
75 static void avr_reorg (void);
76 static void avr_asm_out_ctor (rtx, int);
77 static void avr_asm_out_dtor (rtx, int);
78 static int avr_operand_rtx_cost (rtx, enum machine_mode, enum rtx_code);
79 static bool avr_rtx_costs (rtx, int, int, int *);
80 static int avr_address_cost (rtx);
81 static bool avr_return_in_memory (tree, tree);
83 /* Allocate registers from r25 to r8 for parameters for function calls. */
84 #define FIRST_CUM_REG 26
86 /* Temporary register RTX (gen_rtx_REG (QImode, TMP_REGNO)) */
87 static GTY(()) rtx tmp_reg_rtx;
89 /* Zeroed register RTX (gen_rtx_REG (QImode, ZERO_REGNO)) */
90 static GTY(()) rtx zero_reg_rtx;
92 /* AVR register names {"r0", "r1", ..., "r31"} */
93 static const char *const avr_regnames[] = REGISTER_NAMES;
95 /* This holds the last insn address. */
96 static int last_insn_address = 0;
98 /* Commands count in the compiled file */
99 static int commands_in_file;
101 /* Commands in the functions prologues in the compiled file */
102 static int commands_in_prologues;
104 /* Commands in the functions epilogues in the compiled file */
105 static int commands_in_epilogues;
107 /* Prologue/Epilogue size in words */
108 static int prologue_size;
109 static int epilogue_size;
111 /* Size of all jump tables in the current function, in words. */
112 static int jump_tables_size;
114 /* Preprocessor macros to define depending on MCU type. */
115 const char *avr_base_arch_macro;
116 const char *avr_extra_arch_macro;
118 section *progmem_section;
120 /* More than 8K of program memory: use "call" and "jmp". */
121 int avr_mega_p = 0;
123 /* Enhanced core: use "movw", "mul", ... */
124 int avr_enhanced_p = 0;
126 /* Assembler only. */
127 int avr_asm_only_p = 0;
129 struct base_arch_s {
130 int asm_only;
131 int enhanced;
132 int mega;
133 const char *const macro;
136 static const struct base_arch_s avr_arch_types[] = {
137 { 1, 0, 0, NULL }, /* unknown device specified */
138 { 1, 0, 0, "__AVR_ARCH__=1" },
139 { 0, 0, 0, "__AVR_ARCH__=2" },
140 { 0, 0, 1, "__AVR_ARCH__=3" },
141 { 0, 1, 0, "__AVR_ARCH__=4" },
142 { 0, 1, 1, "__AVR_ARCH__=5" }
145 struct mcu_type_s {
146 const char *const name;
147 int arch; /* index in avr_arch_types[] */
148 /* Must lie outside user's namespace. NULL == no macro. */
149 const char *const macro;
152 /* List of all known AVR MCU types - if updated, it has to be kept
153 in sync in several places (FIXME: is there a better way?):
154 - here
155 - avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
156 - t-avr (MULTILIB_MATCHES)
157 - gas/config/tc-avr.c
158 - avr-libc */
160 static const struct mcu_type_s avr_mcu_types[] = {
161 /* Classic, <= 8K. */
162 { "avr2", 2, NULL },
163 { "at90s2313", 2, "__AVR_AT90S2313__" },
164 { "at90s2323", 2, "__AVR_AT90S2323__" },
165 { "at90s2333", 2, "__AVR_AT90S2333__" },
166 { "at90s2343", 2, "__AVR_AT90S2343__" },
167 { "attiny22", 2, "__AVR_ATtiny22__" },
168 { "attiny26", 2, "__AVR_ATtiny26__" },
169 { "at90s4414", 2, "__AVR_AT90S4414__" },
170 { "at90s4433", 2, "__AVR_AT90S4433__" },
171 { "at90s4434", 2, "__AVR_AT90S4434__" },
172 { "at90s8515", 2, "__AVR_AT90S8515__" },
173 { "at90c8534", 2, "__AVR_AT90C8534__" },
174 { "at90s8535", 2, "__AVR_AT90S8535__" },
175 /* Classic + MOVW, <= 8K. */
176 { "attiny13", 2, "__AVR_ATtiny13__" },
177 { "attiny2313", 2, "__AVR_ATtiny2313__" },
178 { "attiny24", 2, "__AVR_ATtiny24__" },
179 { "attiny44", 2, "__AVR_ATtiny44__" },
180 { "attiny84", 2, "__AVR_ATtiny84__" },
181 { "attiny25", 2, "__AVR_ATtiny25__" },
182 { "attiny45", 2, "__AVR_ATtiny45__" },
183 { "attiny85", 2, "__AVR_ATtiny85__" },
184 { "attiny261", 2, "__AVR_ATtiny261__" },
185 { "attiny461", 2, "__AVR_ATtiny461__" },
186 { "attiny861", 2, "__AVR_ATtiny861__" },
187 { "at86rf401", 2, "__AVR_AT86RF401__" },
188 /* Classic, > 8K. */
189 { "avr3", 3, NULL },
190 { "atmega103", 3, "__AVR_ATmega103__" },
191 { "atmega603", 3, "__AVR_ATmega603__" },
192 { "at43usb320", 3, "__AVR_AT43USB320__" },
193 { "at43usb355", 3, "__AVR_AT43USB355__" },
194 { "at76c711", 3, "__AVR_AT76C711__" },
195 /* Enhanced, <= 8K. */
196 { "avr4", 4, NULL },
197 { "atmega8", 4, "__AVR_ATmega8__" },
198 { "atmega48", 4, "__AVR_ATmega48__" },
199 { "atmega88", 4, "__AVR_ATmega88__" },
200 { "atmega8515", 4, "__AVR_ATmega8515__" },
201 { "atmega8535", 4, "__AVR_ATmega8535__" },
202 { "at90pwm2", 4, "__AVR_AT90PWM2__" },
203 { "at90pwm3", 4, "__AVR_AT90PWM3__" },
204 /* Enhanced, > 8K. */
205 { "avr5", 5, NULL },
206 { "atmega16", 5, "__AVR_ATmega16__" },
207 { "atmega161", 5, "__AVR_ATmega161__" },
208 { "atmega162", 5, "__AVR_ATmega162__" },
209 { "atmega163", 5, "__AVR_ATmega163__" },
210 { "atmega164p",5, "__AVR_ATmega164P__" },
211 { "atmega165", 5, "__AVR_ATmega165__" },
212 { "atmega165p",5, "__AVR_ATmega165P__" },
213 { "atmega168", 5, "__AVR_ATmega168__" },
214 { "atmega169", 5, "__AVR_ATmega169__" },
215 { "atmega169p",5, "__AVR_ATmega169P__" },
216 { "atmega32", 5, "__AVR_ATmega32__" },
217 { "atmega323", 5, "__AVR_ATmega323__" },
218 { "atmega324p",5, "__AVR_ATmega324P__" },
219 { "atmega325", 5, "__AVR_ATmega325__" },
220 { "atmega3250", 5, "__AVR_ATmega3250__" },
221 { "atmega329", 5, "__AVR_ATmega329__" },
222 { "atmega3290", 5, "__AVR_ATmega3290__" },
223 { "atmega406", 5, "__AVR_ATmega406__" },
224 { "atmega64", 5, "__AVR_ATmega64__" },
225 { "atmega640", 5, "__AVR_ATmega640__" },
226 { "atmega644", 5, "__AVR_ATmega644__" },
227 { "atmega644p",5, "__AVR_ATmega644P__" },
228 { "atmega645", 5, "__AVR_ATmega645__" },
229 { "atmega6450", 5, "__AVR_ATmega6450__" },
230 { "atmega649", 5, "__AVR_ATmega649__" },
231 { "atmega6490", 5, "__AVR_ATmega6490__" },
232 { "atmega128", 5, "__AVR_ATmega128__" },
233 { "atmega1280",5, "__AVR_ATmega1280__" },
234 { "atmega1281",5, "__AVR_ATmega1281__" },
235 { "at90can32", 5, "__AVR_AT90CAN32__" },
236 { "at90can64", 5, "__AVR_AT90CAN64__" },
237 { "at90can128", 5, "__AVR_AT90CAN128__" },
238 { "at90usb646", 5, "__AVR_AT90USB646__" },
239 { "at90usb647", 5, "__AVR_AT90USB647__" },
240 { "at90usb1286", 5, "__AVR_AT90USB1286__" },
241 { "at90usb1287", 5, "__AVR_AT90USB1287__" },
242 { "at94k", 5, "__AVR_AT94K__" },
243 /* Assembler only. */
244 { "avr1", 1, NULL },
245 { "at90s1200", 1, "__AVR_AT90S1200__" },
246 { "attiny11", 1, "__AVR_ATtiny11__" },
247 { "attiny12", 1, "__AVR_ATtiny12__" },
248 { "attiny15", 1, "__AVR_ATtiny15__" },
249 { "attiny28", 1, "__AVR_ATtiny28__" },
250 { NULL, 0, NULL }
253 int avr_case_values_threshold = 30000;
255 /* Initialize the GCC target structure. */
256 #undef TARGET_ASM_ALIGNED_HI_OP
257 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
258 #undef TARGET_ASM_ALIGNED_SI_OP
259 #define TARGET_ASM_ALIGNED_SI_OP "\t.long\t"
260 #undef TARGET_ASM_UNALIGNED_HI_OP
261 #define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
262 #undef TARGET_ASM_UNALIGNED_SI_OP
263 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
264 #undef TARGET_ASM_INTEGER
265 #define TARGET_ASM_INTEGER avr_assemble_integer
266 #undef TARGET_ASM_FILE_START
267 #define TARGET_ASM_FILE_START avr_file_start
268 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
269 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
270 #undef TARGET_ASM_FILE_END
271 #define TARGET_ASM_FILE_END avr_file_end
273 #undef TARGET_ASM_FUNCTION_PROLOGUE
274 #define TARGET_ASM_FUNCTION_PROLOGUE avr_output_function_prologue
275 #undef TARGET_ASM_FUNCTION_EPILOGUE
276 #define TARGET_ASM_FUNCTION_EPILOGUE avr_output_function_epilogue
277 #undef TARGET_ATTRIBUTE_TABLE
278 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
279 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
280 #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
281 #undef TARGET_INSERT_ATTRIBUTES
282 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
283 #undef TARGET_SECTION_TYPE_FLAGS
284 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
285 #undef TARGET_RTX_COSTS
286 #define TARGET_RTX_COSTS avr_rtx_costs
287 #undef TARGET_ADDRESS_COST
288 #define TARGET_ADDRESS_COST avr_address_cost
289 #undef TARGET_MACHINE_DEPENDENT_REORG
290 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
292 #undef TARGET_RETURN_IN_MEMORY
293 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
295 #undef TARGET_STRICT_ARGUMENT_NAMING
296 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
298 struct gcc_target targetm = TARGET_INITIALIZER;
300 void
301 avr_override_options (void)
303 const struct mcu_type_s *t;
304 const struct base_arch_s *base;
306 for (t = avr_mcu_types; t->name; t++)
307 if (strcmp (t->name, avr_mcu_name) == 0)
308 break;
310 if (!t->name)
312 fprintf (stderr, "unknown MCU '%s' specified\nKnown MCU names:\n",
313 avr_mcu_name);
314 for (t = avr_mcu_types; t->name; t++)
315 fprintf (stderr," %s\n", t->name);
318 base = &avr_arch_types[t->arch];
319 avr_asm_only_p = base->asm_only;
320 avr_enhanced_p = base->enhanced;
321 avr_mega_p = base->mega;
322 avr_base_arch_macro = base->macro;
323 avr_extra_arch_macro = t->macro;
325 if (optimize && !TARGET_NO_TABLEJUMP)
326 avr_case_values_threshold = (!AVR_MEGA || TARGET_CALL_PROLOGUES) ? 8 : 17;
328 tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO);
329 zero_reg_rtx = gen_rtx_REG (QImode, ZERO_REGNO);
332 /* return register class from register number. */
334 static const int reg_class_tab[]={
335 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
336 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
337 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
338 GENERAL_REGS, /* r0 - r15 */
339 LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
340 LD_REGS, /* r16 - 23 */
341 ADDW_REGS,ADDW_REGS, /* r24,r25 */
342 POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
343 POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
344 POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
345 STACK_REG,STACK_REG /* SPL,SPH */
348 /* Return register class for register R. */
350 enum reg_class
351 avr_regno_reg_class (int r)
353 if (r <= 33)
354 return reg_class_tab[r];
355 return ALL_REGS;
358 /* Return nonzero if FUNC is a naked function. */
360 static int
361 avr_naked_function_p (tree func)
363 tree a;
365 gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
367 a = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
368 return a != NULL_TREE;
371 /* Return nonzero if FUNC is an interrupt function as specified
372 by the "interrupt" attribute. */
374 static int
375 interrupt_function_p (tree func)
377 tree a;
379 if (TREE_CODE (func) != FUNCTION_DECL)
380 return 0;
382 a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
383 return a != NULL_TREE;
386 /* Return nonzero if FUNC is a signal function as specified
387 by the "signal" attribute. */
389 static int
390 signal_function_p (tree func)
392 tree a;
394 if (TREE_CODE (func) != FUNCTION_DECL)
395 return 0;
397 a = lookup_attribute ("signal", DECL_ATTRIBUTES (func));
398 return a != NULL_TREE;
401 /* Return the number of hard registers to push/pop in the prologue/epilogue
402 of the current function, and optionally store these registers in SET. */
404 static int
405 avr_regs_to_save (HARD_REG_SET *set)
407 int reg, count;
408 int int_or_sig_p = (interrupt_function_p (current_function_decl)
409 || signal_function_p (current_function_decl));
410 int leaf_func_p = leaf_function_p ();
412 if (set)
413 CLEAR_HARD_REG_SET (*set);
414 count = 0;
416 /* No need to save any registers if the function never returns. */
417 if (TREE_THIS_VOLATILE (current_function_decl))
418 return 0;
420 for (reg = 0; reg < 32; reg++)
422 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
423 any global register variables. */
424 if (fixed_regs[reg])
425 continue;
427 if ((int_or_sig_p && !leaf_func_p && call_used_regs[reg])
428 || (regs_ever_live[reg]
429 && (int_or_sig_p || !call_used_regs[reg])
430 && !(frame_pointer_needed
431 && (reg == REG_Y || reg == (REG_Y+1)))))
433 if (set)
434 SET_HARD_REG_BIT (*set, reg);
435 count++;
438 return count;
441 /* Compute offset between arg_pointer and frame_pointer. */
444 initial_elimination_offset (int from, int to)
446 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
447 return 0;
448 else
450 int offset = frame_pointer_needed ? 2 : 0;
452 offset += avr_regs_to_save (NULL);
453 return get_frame_size () + 2 + 1 + offset;
457 /* Return 1 if the function epilogue is just a single "ret". */
460 avr_simple_epilogue (void)
462 return (! frame_pointer_needed
463 && get_frame_size () == 0
464 && avr_regs_to_save (NULL) == 0
465 && ! interrupt_function_p (current_function_decl)
466 && ! signal_function_p (current_function_decl)
467 && ! avr_naked_function_p (current_function_decl)
468 && ! MAIN_NAME_P (DECL_NAME (current_function_decl))
469 && ! TREE_THIS_VOLATILE (current_function_decl));
472 /* This function checks sequence of live registers. */
474 static int
475 sequent_regs_live (void)
477 int reg;
478 int live_seq=0;
479 int cur_seq=0;
481 for (reg = 0; reg < 18; ++reg)
483 if (!call_used_regs[reg])
485 if (regs_ever_live[reg])
487 ++live_seq;
488 ++cur_seq;
490 else
491 cur_seq = 0;
495 if (!frame_pointer_needed)
497 if (regs_ever_live[REG_Y])
499 ++live_seq;
500 ++cur_seq;
502 else
503 cur_seq = 0;
505 if (regs_ever_live[REG_Y+1])
507 ++live_seq;
508 ++cur_seq;
510 else
511 cur_seq = 0;
513 else
515 cur_seq += 2;
516 live_seq += 2;
518 return (cur_seq == live_seq) ? live_seq : 0;
522 /* Output to FILE the asm instructions to adjust the frame pointer by
523 ADJ (r29:r28 -= ADJ;) which can be positive (prologue) or negative
524 (epilogue). Returns the number of instructions generated. */
526 static int
527 out_adj_frame_ptr (FILE *file, int adj)
529 int size = 0;
531 if (adj)
533 if (TARGET_TINY_STACK)
535 if (adj < -63 || adj > 63)
536 warning (0, "large frame pointer change (%d) with -mtiny-stack", adj);
538 /* The high byte (r29) doesn't change - prefer "subi" (1 cycle)
539 over "sbiw" (2 cycles, same size). */
541 fprintf (file, (AS2 (subi, r28, %d) CR_TAB), adj);
542 size++;
544 else if (adj < -63 || adj > 63)
546 fprintf (file, (AS2 (subi, r28, lo8(%d)) CR_TAB
547 AS2 (sbci, r29, hi8(%d)) CR_TAB),
548 adj, adj);
549 size += 2;
551 else if (adj < 0)
553 fprintf (file, (AS2 (adiw, r28, %d) CR_TAB), -adj);
554 size++;
556 else
558 fprintf (file, (AS2 (sbiw, r28, %d) CR_TAB), adj);
559 size++;
562 return size;
566 /* Output to FILE the asm instructions to copy r29:r28 to SPH:SPL,
567 handling various cases of interrupt enable flag state BEFORE and AFTER
568 (0=disabled, 1=enabled, -1=unknown/unchanged) and target_flags.
569 Returns the number of instructions generated. */
571 static int
572 out_set_stack_ptr (FILE *file, int before, int after)
574 int do_sph, do_cli, do_save, do_sei, lock_sph, size;
576 /* The logic here is so that -mno-interrupts actually means
577 "it is safe to write SPH in one instruction, then SPL in the
578 next instruction, without disabling interrupts first".
579 The after != -1 case (interrupt/signal) is not affected. */
581 do_sph = !TARGET_TINY_STACK;
582 lock_sph = do_sph && !TARGET_NO_INTERRUPTS;
583 do_cli = (before != 0 && (after == 0 || lock_sph));
584 do_save = (do_cli && before == -1 && after == -1);
585 do_sei = ((do_cli || before != 1) && after == 1);
586 size = 1;
588 if (do_save)
590 fprintf (file, AS2 (in, __tmp_reg__, __SREG__) CR_TAB);
591 size++;
594 if (do_cli)
596 fprintf (file, "cli" CR_TAB);
597 size++;
600 /* Do SPH first - maybe this will disable interrupts for one instruction
601 someday (a suggestion has been sent to avr@atmel.com for consideration
602 in future devices - that would make -mno-interrupts always safe). */
603 if (do_sph)
605 fprintf (file, AS2 (out, __SP_H__, r29) CR_TAB);
606 size++;
609 /* Set/restore the I flag now - interrupts will be really enabled only
610 after the next instruction. This is not clearly documented, but
611 believed to be true for all AVR devices. */
612 if (do_save)
614 fprintf (file, AS2 (out, __SREG__, __tmp_reg__) CR_TAB);
615 size++;
617 else if (do_sei)
619 fprintf (file, "sei" CR_TAB);
620 size++;
623 fprintf (file, AS2 (out, __SP_L__, r28) "\n");
625 return size;
629 /* Output function prologue. */
631 static void
632 avr_output_function_prologue (FILE *file, HOST_WIDE_INT size)
634 int reg;
635 int interrupt_func_p;
636 int signal_func_p;
637 int main_p;
638 int live_seq;
639 int minimize;
641 last_insn_address = 0;
642 jump_tables_size = 0;
643 prologue_size = 0;
644 fprintf (file, "/* prologue: frame size=" HOST_WIDE_INT_PRINT_DEC " */\n",
645 size);
647 if (avr_naked_function_p (current_function_decl))
649 fputs ("/* prologue: naked */\n", file);
650 goto out;
653 interrupt_func_p = interrupt_function_p (current_function_decl);
654 signal_func_p = signal_function_p (current_function_decl);
655 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
656 live_seq = sequent_regs_live ();
657 minimize = (TARGET_CALL_PROLOGUES
658 && !interrupt_func_p && !signal_func_p && live_seq);
660 if (interrupt_func_p)
662 fprintf (file,"\tsei\n");
663 ++prologue_size;
665 if (interrupt_func_p || signal_func_p)
667 fprintf (file, "\t"
668 AS1 (push,__zero_reg__) CR_TAB
669 AS1 (push,__tmp_reg__) CR_TAB
670 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
671 AS1 (push,__tmp_reg__) CR_TAB
672 AS1 (clr,__zero_reg__) "\n");
673 prologue_size += 5;
675 if (main_p)
677 fprintf (file, ("\t"
678 AS1 (ldi,r28) ",lo8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
679 AS1 (ldi,r29) ",hi8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
680 AS2 (out,__SP_H__,r29) CR_TAB
681 AS2 (out,__SP_L__,r28) "\n"),
682 avr_init_stack, size, avr_init_stack, size);
684 prologue_size += 4;
686 else if (minimize && (frame_pointer_needed || live_seq > 6))
688 fprintf (file, ("\t"
689 AS1 (ldi, r26) ",lo8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
690 AS1 (ldi, r27) ",hi8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB), size, size);
692 fputs ((AS2 (ldi,r30,pm_lo8(1f)) CR_TAB
693 AS2 (ldi,r31,pm_hi8(1f)) CR_TAB), file);
695 prologue_size += 4;
697 if (AVR_MEGA)
699 fprintf (file, AS1 (jmp,__prologue_saves__+%d) "\n",
700 (18 - live_seq) * 2);
701 prologue_size += 2;
703 else
705 fprintf (file, AS1 (rjmp,__prologue_saves__+%d) "\n",
706 (18 - live_seq) * 2);
707 ++prologue_size;
709 fputs ("1:\n", file);
711 else
713 HARD_REG_SET set;
715 prologue_size += avr_regs_to_save (&set);
716 for (reg = 0; reg < 32; ++reg)
718 if (TEST_HARD_REG_BIT (set, reg))
720 fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
723 if (frame_pointer_needed)
725 fprintf (file, "\t"
726 AS1 (push,r28) CR_TAB
727 AS1 (push,r29) CR_TAB
728 AS2 (in,r28,__SP_L__) CR_TAB
729 AS2 (in,r29,__SP_H__) "\n");
730 prologue_size += 4;
731 if (size)
733 fputs ("\t", file);
734 prologue_size += out_adj_frame_ptr (file, size);
736 if (interrupt_func_p)
738 prologue_size += out_set_stack_ptr (file, 1, 1);
740 else if (signal_func_p)
742 prologue_size += out_set_stack_ptr (file, 0, 0);
744 else
746 prologue_size += out_set_stack_ptr (file, -1, -1);
752 out:
753 fprintf (file, "/* prologue end (size=%d) */\n", prologue_size);
756 /* Output function epilogue. */
758 static void
759 avr_output_function_epilogue (FILE *file, HOST_WIDE_INT size)
761 int reg;
762 int interrupt_func_p;
763 int signal_func_p;
764 int main_p;
765 int function_size;
766 int live_seq;
767 int minimize;
768 rtx last = get_last_nonnote_insn ();
770 function_size = jump_tables_size;
771 if (last)
773 rtx first = get_first_nonnote_insn ();
774 function_size += (INSN_ADDRESSES (INSN_UID (last)) -
775 INSN_ADDRESSES (INSN_UID (first)));
776 function_size += get_attr_length (last);
779 fprintf (file, "/* epilogue: frame size=" HOST_WIDE_INT_PRINT_DEC " */\n", size);
780 epilogue_size = 0;
782 if (avr_naked_function_p (current_function_decl))
784 fputs ("/* epilogue: naked */\n", file);
785 goto out;
788 if (last && GET_CODE (last) == BARRIER)
790 fputs ("/* epilogue: noreturn */\n", file);
791 goto out;
794 interrupt_func_p = interrupt_function_p (current_function_decl);
795 signal_func_p = signal_function_p (current_function_decl);
796 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
797 live_seq = sequent_regs_live ();
798 minimize = (TARGET_CALL_PROLOGUES
799 && !interrupt_func_p && !signal_func_p && live_seq);
801 if (main_p)
803 /* Return value from main() is already in the correct registers
804 (r25:r24) as the exit() argument. */
805 if (AVR_MEGA)
807 fputs ("\t" AS1 (jmp,exit) "\n", file);
808 epilogue_size += 2;
810 else
812 fputs ("\t" AS1 (rjmp,exit) "\n", file);
813 ++epilogue_size;
816 else if (minimize && (frame_pointer_needed || live_seq > 4))
818 fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
819 ++epilogue_size;
820 if (frame_pointer_needed)
822 epilogue_size += out_adj_frame_ptr (file, -size);
824 else
826 fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
827 AS2 (in , r29, __SP_H__) CR_TAB));
828 epilogue_size += 2;
831 if (AVR_MEGA)
833 fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
834 (18 - live_seq) * 2);
835 epilogue_size += 2;
837 else
839 fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
840 (18 - live_seq) * 2);
841 ++epilogue_size;
844 else
846 HARD_REG_SET set;
848 if (frame_pointer_needed)
850 if (size)
852 fputs ("\t", file);
853 epilogue_size += out_adj_frame_ptr (file, -size);
855 if (interrupt_func_p || signal_func_p)
857 epilogue_size += out_set_stack_ptr (file, -1, 0);
859 else
861 epilogue_size += out_set_stack_ptr (file, -1, -1);
864 fprintf (file, "\t"
865 AS1 (pop,r29) CR_TAB
866 AS1 (pop,r28) "\n");
867 epilogue_size += 2;
870 epilogue_size += avr_regs_to_save (&set);
871 for (reg = 31; reg >= 0; --reg)
873 if (TEST_HARD_REG_BIT (set, reg))
875 fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
879 if (interrupt_func_p || signal_func_p)
881 fprintf (file, "\t"
882 AS1 (pop,__tmp_reg__) CR_TAB
883 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
884 AS1 (pop,__tmp_reg__) CR_TAB
885 AS1 (pop,__zero_reg__) "\n");
886 epilogue_size += 4;
887 fprintf (file, "\treti\n");
889 else
890 fprintf (file, "\tret\n");
891 ++epilogue_size;
894 out:
895 fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
896 fprintf (file, "/* function %s size %d (%d) */\n", current_function_name (),
897 prologue_size + function_size + epilogue_size, function_size);
898 commands_in_file += prologue_size + function_size + epilogue_size;
899 commands_in_prologues += prologue_size;
900 commands_in_epilogues += epilogue_size;
904 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
905 machine for a memory operand of mode MODE. */
908 legitimate_address_p (enum machine_mode mode, rtx x, int strict)
910 enum reg_class r = NO_REGS;
912 if (TARGET_ALL_DEBUG)
914 fprintf (stderr, "mode: (%s) %s %s %s %s:",
915 GET_MODE_NAME(mode),
916 strict ? "(strict)": "",
917 reload_completed ? "(reload_completed)": "",
918 reload_in_progress ? "(reload_in_progress)": "",
919 reg_renumber ? "(reg_renumber)" : "");
920 if (GET_CODE (x) == PLUS
921 && REG_P (XEXP (x, 0))
922 && GET_CODE (XEXP (x, 1)) == CONST_INT
923 && INTVAL (XEXP (x, 1)) >= 0
924 && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
925 && reg_renumber
927 fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
928 true_regnum (XEXP (x, 0)));
929 debug_rtx (x);
931 if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
932 : REG_OK_FOR_BASE_NOSTRICT_P (x)))
933 r = POINTER_REGS;
934 else if (CONSTANT_ADDRESS_P (x))
935 r = ALL_REGS;
936 else if (GET_CODE (x) == PLUS
937 && REG_P (XEXP (x, 0))
938 && GET_CODE (XEXP (x, 1)) == CONST_INT
939 && INTVAL (XEXP (x, 1)) >= 0)
941 int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
942 if (fit)
944 if (! strict
945 || REGNO (XEXP (x,0)) == REG_Y
946 || REGNO (XEXP (x,0)) == REG_Z)
947 r = BASE_POINTER_REGS;
948 if (XEXP (x,0) == frame_pointer_rtx
949 || XEXP (x,0) == arg_pointer_rtx)
950 r = BASE_POINTER_REGS;
952 else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
953 r = POINTER_Y_REGS;
955 else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
956 && REG_P (XEXP (x, 0))
957 && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
958 : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
960 r = POINTER_REGS;
962 if (TARGET_ALL_DEBUG)
964 fprintf (stderr, " ret = %c\n", r + '0');
966 return r == NO_REGS ? 0 : (int)r;
969 /* Attempts to replace X with a valid
970 memory address for an operand of mode MODE */
973 legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
975 x = oldx;
976 if (TARGET_ALL_DEBUG)
978 fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
979 debug_rtx (oldx);
982 if (GET_CODE (oldx) == PLUS
983 && REG_P (XEXP (oldx,0)))
985 if (REG_P (XEXP (oldx,1)))
986 x = force_reg (GET_MODE (oldx), oldx);
987 else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
989 int offs = INTVAL (XEXP (oldx,1));
990 if (frame_pointer_rtx != XEXP (oldx,0))
991 if (offs > MAX_LD_OFFSET (mode))
993 if (TARGET_ALL_DEBUG)
994 fprintf (stderr, "force_reg (big offset)\n");
995 x = force_reg (GET_MODE (oldx), oldx);
999 return x;
1003 /* Return a pointer register name as a string. */
1005 static const char *
1006 ptrreg_to_str (int regno)
1008 switch (regno)
1010 case REG_X: return "X";
1011 case REG_Y: return "Y";
1012 case REG_Z: return "Z";
1013 default:
1014 gcc_unreachable ();
1016 return NULL;
1019 /* Return the condition name as a string.
1020 Used in conditional jump constructing */
1022 static const char *
1023 cond_string (enum rtx_code code)
1025 switch (code)
1027 case NE:
1028 return "ne";
1029 case EQ:
1030 return "eq";
1031 case GE:
1032 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1033 return "pl";
1034 else
1035 return "ge";
1036 case LT:
1037 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1038 return "mi";
1039 else
1040 return "lt";
1041 case GEU:
1042 return "sh";
1043 case LTU:
1044 return "lo";
1045 default:
1046 gcc_unreachable ();
1050 /* Output ADDR to FILE as address. */
1052 void
1053 print_operand_address (FILE *file, rtx addr)
1055 switch (GET_CODE (addr))
1057 case REG:
1058 fprintf (file, ptrreg_to_str (REGNO (addr)));
1059 break;
1061 case PRE_DEC:
1062 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1063 break;
1065 case POST_INC:
1066 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1067 break;
1069 default:
1070 if (CONSTANT_ADDRESS_P (addr)
1071 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (addr))
1072 || GET_CODE (addr) == LABEL_REF))
1074 fprintf (file, "pm(");
1075 output_addr_const (file,addr);
1076 fprintf (file ,")");
1078 else
1079 output_addr_const (file, addr);
1084 /* Output X as assembler operand to file FILE. */
1086 void
1087 print_operand (FILE *file, rtx x, int code)
1089 int abcd = 0;
1091 if (code >= 'A' && code <= 'D')
1092 abcd = code - 'A';
1094 if (code == '~')
1096 if (!AVR_MEGA)
1097 fputc ('r', file);
1099 else if (REG_P (x))
1101 if (x == zero_reg_rtx)
1102 fprintf (file, "__zero_reg__");
1103 else
1104 fprintf (file, reg_names[true_regnum (x) + abcd]);
1106 else if (GET_CODE (x) == CONST_INT)
1107 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd);
1108 else if (GET_CODE (x) == MEM)
1110 rtx addr = XEXP (x,0);
1112 if (CONSTANT_P (addr) && abcd)
1114 fputc ('(', file);
1115 output_address (addr);
1116 fprintf (file, ")+%d", abcd);
1118 else if (code == 'o')
1120 if (GET_CODE (addr) != PLUS)
1121 fatal_insn ("bad address, not (reg+disp):", addr);
1123 print_operand (file, XEXP (addr, 1), 0);
1125 else if (code == 'p' || code == 'r')
1127 if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
1128 fatal_insn ("bad address, not post_inc or pre_dec:", addr);
1130 if (code == 'p')
1131 print_operand_address (file, XEXP (addr, 0)); /* X, Y, Z */
1132 else
1133 print_operand (file, XEXP (addr, 0), 0); /* r26, r28, r30 */
1135 else if (GET_CODE (addr) == PLUS)
1137 print_operand_address (file, XEXP (addr,0));
1138 if (REGNO (XEXP (addr, 0)) == REG_X)
1139 fatal_insn ("internal compiler error. Bad address:"
1140 ,addr);
1141 fputc ('+', file);
1142 print_operand (file, XEXP (addr,1), code);
1144 else
1145 print_operand_address (file, addr);
1147 else if (GET_CODE (x) == CONST_DOUBLE)
1149 long val;
1150 REAL_VALUE_TYPE rv;
1151 if (GET_MODE (x) != SFmode)
1152 fatal_insn ("internal compiler error. Unknown mode:", x);
1153 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1154 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1155 fprintf (file, "0x%lx", val);
1157 else if (code == 'j')
1158 fputs (cond_string (GET_CODE (x)), file);
1159 else if (code == 'k')
1160 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
1161 else
1162 print_operand_address (file, x);
1165 /* Recognize operand OP of mode MODE used in call instructions. */
1168 call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1170 if (GET_CODE (op) == MEM)
1172 rtx inside = XEXP (op, 0);
1173 if (register_operand (inside, Pmode))
1174 return 1;
1175 if (CONSTANT_ADDRESS_P (inside))
1176 return 1;
1178 return 0;
1181 /* Update the condition code in the INSN. */
1183 void
1184 notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
1186 rtx set;
1188 switch (get_attr_cc (insn))
1190 case CC_NONE:
1191 /* Insn does not affect CC at all. */
1192 break;
1194 case CC_SET_N:
1195 CC_STATUS_INIT;
1196 break;
1198 case CC_SET_ZN:
1199 set = single_set (insn);
1200 CC_STATUS_INIT;
1201 if (set)
1203 cc_status.flags |= CC_NO_OVERFLOW;
1204 cc_status.value1 = SET_DEST (set);
1206 break;
1208 case CC_SET_CZN:
1209 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1210 The V flag may or may not be known but that's ok because
1211 alter_cond will change tests to use EQ/NE. */
1212 set = single_set (insn);
1213 CC_STATUS_INIT;
1214 if (set)
1216 cc_status.value1 = SET_DEST (set);
1217 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1219 break;
1221 case CC_COMPARE:
1222 set = single_set (insn);
1223 CC_STATUS_INIT;
1224 if (set)
1225 cc_status.value1 = SET_SRC (set);
1226 break;
1228 case CC_CLOBBER:
1229 /* Insn doesn't leave CC in a usable state. */
1230 CC_STATUS_INIT;
1232 /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1233 set = single_set (insn);
1234 if (set)
1236 rtx src = SET_SRC (set);
1238 if (GET_CODE (src) == ASHIFTRT
1239 && GET_MODE (src) == QImode)
1241 rtx x = XEXP (src, 1);
1243 if (GET_CODE (x) == CONST_INT
1244 && INTVAL (x) > 0
1245 && INTVAL (x) != 6)
1247 cc_status.value1 = SET_DEST (set);
1248 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1252 break;
1256 /* Return maximum number of consecutive registers of
1257 class CLASS needed to hold a value of mode MODE. */
1260 class_max_nregs (enum reg_class class ATTRIBUTE_UNUSED,enum machine_mode mode)
1262 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1265 /* Choose mode for jump insn:
1266 1 - relative jump in range -63 <= x <= 62 ;
1267 2 - relative jump in range -2046 <= x <= 2045 ;
1268 3 - absolute jump (only for ATmega[16]03). */
1271 avr_jump_mode (rtx x, rtx insn)
1273 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1274 ? XEXP (x, 0) : x));
1275 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1276 int jump_distance = cur_addr - dest_addr;
1278 if (-63 <= jump_distance && jump_distance <= 62)
1279 return 1;
1280 else if (-2046 <= jump_distance && jump_distance <= 2045)
1281 return 2;
1282 else if (AVR_MEGA)
1283 return 3;
1285 return 2;
1288 /* return an AVR condition jump commands.
1289 X is a comparison RTX.
1290 LEN is a number returned by avr_jump_mode function.
1291 if REVERSE nonzero then condition code in X must be reversed. */
1293 const char *
1294 ret_cond_branch (rtx x, int len, int reverse)
1296 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1298 switch (cond)
1300 case GT:
1301 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1302 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1303 AS1 (brpl,%0)) :
1304 len == 2 ? (AS1 (breq,.+4) CR_TAB
1305 AS1 (brmi,.+2) CR_TAB
1306 AS1 (rjmp,%0)) :
1307 (AS1 (breq,.+6) CR_TAB
1308 AS1 (brmi,.+4) CR_TAB
1309 AS1 (jmp,%0)));
1311 else
1312 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1313 AS1 (brge,%0)) :
1314 len == 2 ? (AS1 (breq,.+4) CR_TAB
1315 AS1 (brlt,.+2) CR_TAB
1316 AS1 (rjmp,%0)) :
1317 (AS1 (breq,.+6) CR_TAB
1318 AS1 (brlt,.+4) CR_TAB
1319 AS1 (jmp,%0)));
1320 case GTU:
1321 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1322 AS1 (brsh,%0)) :
1323 len == 2 ? (AS1 (breq,.+4) CR_TAB
1324 AS1 (brlo,.+2) CR_TAB
1325 AS1 (rjmp,%0)) :
1326 (AS1 (breq,.+6) CR_TAB
1327 AS1 (brlo,.+4) CR_TAB
1328 AS1 (jmp,%0)));
1329 case LE:
1330 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1331 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1332 AS1 (brmi,%0)) :
1333 len == 2 ? (AS1 (breq,.+2) CR_TAB
1334 AS1 (brpl,.+2) CR_TAB
1335 AS1 (rjmp,%0)) :
1336 (AS1 (breq,.+2) CR_TAB
1337 AS1 (brpl,.+4) CR_TAB
1338 AS1 (jmp,%0)));
1339 else
1340 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1341 AS1 (brlt,%0)) :
1342 len == 2 ? (AS1 (breq,.+2) CR_TAB
1343 AS1 (brge,.+2) CR_TAB
1344 AS1 (rjmp,%0)) :
1345 (AS1 (breq,.+2) CR_TAB
1346 AS1 (brge,.+4) CR_TAB
1347 AS1 (jmp,%0)));
1348 case LEU:
1349 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1350 AS1 (brlo,%0)) :
1351 len == 2 ? (AS1 (breq,.+2) CR_TAB
1352 AS1 (brsh,.+2) CR_TAB
1353 AS1 (rjmp,%0)) :
1354 (AS1 (breq,.+2) CR_TAB
1355 AS1 (brsh,.+4) CR_TAB
1356 AS1 (jmp,%0)));
1357 default:
1358 if (reverse)
1360 switch (len)
1362 case 1:
1363 return AS1 (br%k1,%0);
1364 case 2:
1365 return (AS1 (br%j1,.+2) CR_TAB
1366 AS1 (rjmp,%0));
1367 default:
1368 return (AS1 (br%j1,.+4) CR_TAB
1369 AS1 (jmp,%0));
1372 else
1374 switch (len)
1376 case 1:
1377 return AS1 (br%j1,%0);
1378 case 2:
1379 return (AS1 (br%k1,.+2) CR_TAB
1380 AS1 (rjmp,%0));
1381 default:
1382 return (AS1 (br%k1,.+4) CR_TAB
1383 AS1 (jmp,%0));
1387 return "";
1390 /* Predicate function for immediate operand which fits to byte (8bit) */
1393 byte_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1395 return (GET_CODE (op) == CONST_INT
1396 && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1399 /* Output all insn addresses and their sizes into the assembly language
1400 output file. This is helpful for debugging whether the length attributes
1401 in the md file are correct.
1402 Output insn cost for next insn. */
1404 void
1405 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
1406 int num_operands ATTRIBUTE_UNUSED)
1408 int uid = INSN_UID (insn);
1410 if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1412 fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1413 INSN_ADDRESSES (uid),
1414 INSN_ADDRESSES (uid) - last_insn_address,
1415 rtx_cost (PATTERN (insn), INSN));
1417 last_insn_address = INSN_ADDRESSES (uid);
1420 /* Return 0 if undefined, 1 if always true or always false. */
1423 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE operator, rtx x)
1425 unsigned int max = (mode == QImode ? 0xff :
1426 mode == HImode ? 0xffff :
1427 mode == SImode ? 0xffffffff : 0);
1428 if (max && operator && GET_CODE (x) == CONST_INT)
1430 if (unsigned_condition (operator) != operator)
1431 max >>= 1;
1433 if (max != (INTVAL (x) & max)
1434 && INTVAL (x) != 0xff)
1435 return 1;
1437 return 0;
1441 /* Returns nonzero if REGNO is the number of a hard
1442 register in which function arguments are sometimes passed. */
1445 function_arg_regno_p(int r)
1447 return (r >= 8 && r <= 25);
1450 /* Initializing the variable cum for the state at the beginning
1451 of the argument list. */
1453 void
1454 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
1455 tree fndecl ATTRIBUTE_UNUSED)
1457 cum->nregs = 18;
1458 cum->regno = FIRST_CUM_REG;
1459 if (!libname && fntype)
1461 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1462 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1463 != void_type_node));
1464 if (stdarg)
1465 cum->nregs = 0;
1469 /* Returns the number of registers to allocate for a function argument. */
1471 static int
1472 avr_num_arg_regs (enum machine_mode mode, tree type)
1474 int size;
1476 if (mode == BLKmode)
1477 size = int_size_in_bytes (type);
1478 else
1479 size = GET_MODE_SIZE (mode);
1481 /* Align all function arguments to start in even-numbered registers.
1482 Odd-sized arguments leave holes above them. */
1484 return (size + 1) & ~1;
1487 /* Controls whether a function argument is passed
1488 in a register, and which register. */
1491 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1492 int named ATTRIBUTE_UNUSED)
1494 int bytes = avr_num_arg_regs (mode, type);
1496 if (cum->nregs && bytes <= cum->nregs)
1497 return gen_rtx_REG (mode, cum->regno - bytes);
1499 return NULL_RTX;
1502 /* Update the summarizer variable CUM to advance past an argument
1503 in the argument list. */
1505 void
1506 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1507 int named ATTRIBUTE_UNUSED)
1509 int bytes = avr_num_arg_regs (mode, type);
1511 cum->nregs -= bytes;
1512 cum->regno -= bytes;
1514 if (cum->nregs <= 0)
1516 cum->nregs = 0;
1517 cum->regno = FIRST_CUM_REG;
1521 /***********************************************************************
1522 Functions for outputting various mov's for a various modes
1523 ************************************************************************/
1524 const char *
1525 output_movqi (rtx insn, rtx operands[], int *l)
1527 int dummy;
1528 rtx dest = operands[0];
1529 rtx src = operands[1];
1530 int *real_l = l;
1532 if (!l)
1533 l = &dummy;
1535 *l = 1;
1537 if (register_operand (dest, QImode))
1539 if (register_operand (src, QImode)) /* mov r,r */
1541 if (test_hard_reg_class (STACK_REG, dest))
1542 return AS2 (out,%0,%1);
1543 else if (test_hard_reg_class (STACK_REG, src))
1544 return AS2 (in,%0,%1);
1546 return AS2 (mov,%0,%1);
1548 else if (CONSTANT_P (src))
1550 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1551 return AS2 (ldi,%0,lo8(%1));
1553 if (GET_CODE (src) == CONST_INT)
1555 if (src == const0_rtx) /* mov r,L */
1556 return AS1 (clr,%0);
1557 else if (src == const1_rtx)
1559 *l = 2;
1560 return (AS1 (clr,%0) CR_TAB
1561 AS1 (inc,%0));
1563 else if (src == constm1_rtx)
1565 /* Immediate constants -1 to any register */
1566 *l = 2;
1567 return (AS1 (clr,%0) CR_TAB
1568 AS1 (dec,%0));
1570 else
1572 int bit_nr = exact_log2 (INTVAL (src));
1574 if (bit_nr >= 0)
1576 *l = 3;
1577 if (!real_l)
1578 output_asm_insn ((AS1 (clr,%0) CR_TAB
1579 "set"), operands);
1580 if (!real_l)
1581 avr_output_bld (operands, bit_nr);
1583 return "";
1588 /* Last resort, larger than loading from memory. */
1589 *l = 4;
1590 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1591 AS2 (ldi,r31,lo8(%1)) CR_TAB
1592 AS2 (mov,%0,r31) CR_TAB
1593 AS2 (mov,r31,__tmp_reg__));
1595 else if (GET_CODE (src) == MEM)
1596 return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1598 else if (GET_CODE (dest) == MEM)
1600 const char *template;
1602 if (src == const0_rtx)
1603 operands[1] = zero_reg_rtx;
1605 template = out_movqi_mr_r (insn, operands, real_l);
1607 if (!real_l)
1608 output_asm_insn (template, operands);
1610 operands[1] = src;
1612 return "";
1616 const char *
1617 output_movhi (rtx insn, rtx operands[], int *l)
1619 int dummy;
1620 rtx dest = operands[0];
1621 rtx src = operands[1];
1622 int *real_l = l;
1624 if (!l)
1625 l = &dummy;
1627 if (register_operand (dest, HImode))
1629 if (register_operand (src, HImode)) /* mov r,r */
1631 if (test_hard_reg_class (STACK_REG, dest))
1633 if (TARGET_TINY_STACK)
1635 *l = 1;
1636 return AS2 (out,__SP_L__,%A1);
1638 else if (TARGET_NO_INTERRUPTS)
1640 *l = 2;
1641 return (AS2 (out,__SP_H__,%B1) CR_TAB
1642 AS2 (out,__SP_L__,%A1));
1645 *l = 5;
1646 return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB
1647 "cli" CR_TAB
1648 AS2 (out,__SP_H__,%B1) CR_TAB
1649 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1650 AS2 (out,__SP_L__,%A1));
1652 else if (test_hard_reg_class (STACK_REG, src))
1654 *l = 2;
1655 return (AS2 (in,%A0,__SP_L__) CR_TAB
1656 AS2 (in,%B0,__SP_H__));
1659 if (AVR_ENHANCED)
1661 *l = 1;
1662 return (AS2 (movw,%0,%1));
1665 if (true_regnum (dest) > true_regnum (src))
1667 *l = 2;
1668 return (AS2 (mov,%B0,%B1) CR_TAB
1669 AS2 (mov,%A0,%A1));
1671 else
1673 *l = 2;
1674 return (AS2 (mov,%A0,%A1) CR_TAB
1675 AS2 (mov,%B0,%B1));
1678 else if (CONSTANT_P (src))
1680 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1682 *l = 2;
1683 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1684 AS2 (ldi,%B0,hi8(%1)));
1687 if (GET_CODE (src) == CONST_INT)
1689 if (src == const0_rtx) /* mov r,L */
1691 *l = 2;
1692 return (AS1 (clr,%A0) CR_TAB
1693 AS1 (clr,%B0));
1695 else if (src == const1_rtx)
1697 *l = 3;
1698 return (AS1 (clr,%A0) CR_TAB
1699 AS1 (clr,%B0) CR_TAB
1700 AS1 (inc,%A0));
1702 else if (src == constm1_rtx)
1704 /* Immediate constants -1 to any register */
1705 *l = 3;
1706 return (AS1 (clr,%0) CR_TAB
1707 AS1 (dec,%A0) CR_TAB
1708 AS2 (mov,%B0,%A0));
1710 else
1712 int bit_nr = exact_log2 (INTVAL (src));
1714 if (bit_nr >= 0)
1716 *l = 4;
1717 if (!real_l)
1718 output_asm_insn ((AS1 (clr,%A0) CR_TAB
1719 AS1 (clr,%B0) CR_TAB
1720 "set"), operands);
1721 if (!real_l)
1722 avr_output_bld (operands, bit_nr);
1724 return "";
1728 if ((INTVAL (src) & 0xff) == 0)
1730 *l = 5;
1731 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1732 AS1 (clr,%A0) CR_TAB
1733 AS2 (ldi,r31,hi8(%1)) CR_TAB
1734 AS2 (mov,%B0,r31) CR_TAB
1735 AS2 (mov,r31,__tmp_reg__));
1737 else if ((INTVAL (src) & 0xff00) == 0)
1739 *l = 5;
1740 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1741 AS2 (ldi,r31,lo8(%1)) CR_TAB
1742 AS2 (mov,%A0,r31) CR_TAB
1743 AS1 (clr,%B0) CR_TAB
1744 AS2 (mov,r31,__tmp_reg__));
1748 /* Last resort, equal to loading from memory. */
1749 *l = 6;
1750 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1751 AS2 (ldi,r31,lo8(%1)) CR_TAB
1752 AS2 (mov,%A0,r31) CR_TAB
1753 AS2 (ldi,r31,hi8(%1)) CR_TAB
1754 AS2 (mov,%B0,r31) CR_TAB
1755 AS2 (mov,r31,__tmp_reg__));
1757 else if (GET_CODE (src) == MEM)
1758 return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1760 else if (GET_CODE (dest) == MEM)
1762 const char *template;
1764 if (src == const0_rtx)
1765 operands[1] = zero_reg_rtx;
1767 template = out_movhi_mr_r (insn, operands, real_l);
1769 if (!real_l)
1770 output_asm_insn (template, operands);
1772 operands[1] = src;
1773 return "";
1775 fatal_insn ("invalid insn:", insn);
1776 return "";
1779 const char *
1780 out_movqi_r_mr (rtx insn, rtx op[], int *l)
1782 rtx dest = op[0];
1783 rtx src = op[1];
1784 rtx x = XEXP (src, 0);
1785 int dummy;
1787 if (!l)
1788 l = &dummy;
1790 if (CONSTANT_ADDRESS_P (x))
1792 if (avr_io_address_p (x, 1))
1794 *l = 1;
1795 return AS2 (in,%0,%1-0x20);
1797 *l = 2;
1798 return AS2 (lds,%0,%1);
1800 /* memory access by reg+disp */
1801 else if (GET_CODE (x) == PLUS
1802 && REG_P (XEXP (x,0))
1803 && GET_CODE (XEXP (x,1)) == CONST_INT)
1805 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1807 int disp = INTVAL (XEXP (x,1));
1808 if (REGNO (XEXP (x,0)) != REG_Y)
1809 fatal_insn ("incorrect insn:",insn);
1811 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1812 return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
1813 AS2 (ldd,%0,Y+63) CR_TAB
1814 AS2 (sbiw,r28,%o1-63));
1816 return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1817 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1818 AS2 (ld,%0,Y) CR_TAB
1819 AS2 (subi,r28,lo8(%o1)) CR_TAB
1820 AS2 (sbci,r29,hi8(%o1)));
1822 else if (REGNO (XEXP (x,0)) == REG_X)
1824 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1825 it but I have this situation with extremal optimizing options. */
1826 if (reg_overlap_mentioned_p (dest, XEXP (x,0))
1827 || reg_unused_after (insn, XEXP (x,0)))
1828 return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
1829 AS2 (ld,%0,X));
1831 return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
1832 AS2 (ld,%0,X) CR_TAB
1833 AS2 (sbiw,r26,%o1));
1835 *l = 1;
1836 return AS2 (ldd,%0,%1);
1838 *l = 1;
1839 return AS2 (ld,%0,%1);
1842 const char *
1843 out_movhi_r_mr (rtx insn, rtx op[], int *l)
1845 rtx dest = op[0];
1846 rtx src = op[1];
1847 rtx base = XEXP (src, 0);
1848 int reg_dest = true_regnum (dest);
1849 int reg_base = true_regnum (base);
1850 /* "volatile" forces reading low byte first, even if less efficient,
1851 for correct operation with 16-bit I/O registers. */
1852 int mem_volatile_p = MEM_VOLATILE_P (src);
1853 int tmp;
1855 if (!l)
1856 l = &tmp;
1858 if (reg_base > 0)
1860 if (reg_dest == reg_base) /* R = (R) */
1862 *l = 3;
1863 return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1864 AS2 (ld,%B0,%1) CR_TAB
1865 AS2 (mov,%A0,__tmp_reg__));
1867 else if (reg_base == REG_X) /* (R26) */
1869 if (reg_unused_after (insn, base))
1871 *l = 2;
1872 return (AS2 (ld,%A0,X+) CR_TAB
1873 AS2 (ld,%B0,X));
1875 *l = 3;
1876 return (AS2 (ld,%A0,X+) CR_TAB
1877 AS2 (ld,%B0,X) CR_TAB
1878 AS2 (sbiw,r26,1));
1880 else /* (R) */
1882 *l = 2;
1883 return (AS2 (ld,%A0,%1) CR_TAB
1884 AS2 (ldd,%B0,%1+1));
1887 else if (GET_CODE (base) == PLUS) /* (R + i) */
1889 int disp = INTVAL (XEXP (base, 1));
1890 int reg_base = true_regnum (XEXP (base, 0));
1892 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
1894 if (REGNO (XEXP (base, 0)) != REG_Y)
1895 fatal_insn ("incorrect insn:",insn);
1897 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1898 return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
1899 AS2 (ldd,%A0,Y+62) CR_TAB
1900 AS2 (ldd,%B0,Y+63) CR_TAB
1901 AS2 (sbiw,r28,%o1-62));
1903 return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1904 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1905 AS2 (ld,%A0,Y) CR_TAB
1906 AS2 (ldd,%B0,Y+1) CR_TAB
1907 AS2 (subi,r28,lo8(%o1)) CR_TAB
1908 AS2 (sbci,r29,hi8(%o1)));
1910 if (reg_base == REG_X)
1912 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1913 it but I have this situation with extremal
1914 optimization options. */
1916 *l = 4;
1917 if (reg_base == reg_dest)
1918 return (AS2 (adiw,r26,%o1) CR_TAB
1919 AS2 (ld,__tmp_reg__,X+) CR_TAB
1920 AS2 (ld,%B0,X) CR_TAB
1921 AS2 (mov,%A0,__tmp_reg__));
1923 return (AS2 (adiw,r26,%o1) CR_TAB
1924 AS2 (ld,%A0,X+) CR_TAB
1925 AS2 (ld,%B0,X) CR_TAB
1926 AS2 (sbiw,r26,%o1+1));
1929 if (reg_base == reg_dest)
1931 *l = 3;
1932 return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
1933 AS2 (ldd,%B0,%B1) CR_TAB
1934 AS2 (mov,%A0,__tmp_reg__));
1937 *l = 2;
1938 return (AS2 (ldd,%A0,%A1) CR_TAB
1939 AS2 (ldd,%B0,%B1));
1941 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
1943 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1944 fatal_insn ("incorrect insn:", insn);
1946 if (mem_volatile_p)
1948 if (REGNO (XEXP (base, 0)) == REG_X)
1950 *l = 4;
1951 return (AS2 (sbiw,r26,2) CR_TAB
1952 AS2 (ld,%A0,X+) CR_TAB
1953 AS2 (ld,%B0,X) CR_TAB
1954 AS2 (sbiw,r26,1));
1956 else
1958 *l = 3;
1959 return (AS2 (sbiw,%r1,2) CR_TAB
1960 AS2 (ld,%A0,%p1) CR_TAB
1961 AS2 (ldd,%B0,%p1+1));
1965 *l = 2;
1966 return (AS2 (ld,%B0,%1) CR_TAB
1967 AS2 (ld,%A0,%1));
1969 else if (GET_CODE (base) == POST_INC) /* (R++) */
1971 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1972 fatal_insn ("incorrect insn:", insn);
1974 *l = 2;
1975 return (AS2 (ld,%A0,%1) CR_TAB
1976 AS2 (ld,%B0,%1));
1978 else if (CONSTANT_ADDRESS_P (base))
1980 if (avr_io_address_p (base, 2))
1982 *l = 2;
1983 return (AS2 (in,%A0,%A1-0x20) CR_TAB
1984 AS2 (in,%B0,%B1-0x20));
1986 *l = 4;
1987 return (AS2 (lds,%A0,%A1) CR_TAB
1988 AS2 (lds,%B0,%B1));
1991 fatal_insn ("unknown move insn:",insn);
1992 return "";
1995 const char *
1996 out_movsi_r_mr (rtx insn, rtx op[], int *l)
1998 rtx dest = op[0];
1999 rtx src = op[1];
2000 rtx base = XEXP (src, 0);
2001 int reg_dest = true_regnum (dest);
2002 int reg_base = true_regnum (base);
2003 int tmp;
2005 if (!l)
2006 l = &tmp;
2008 if (reg_base > 0)
2010 if (reg_base == REG_X) /* (R26) */
2012 if (reg_dest == REG_X)
2013 /* "ld r26,-X" is undefined */
2014 return *l=7, (AS2 (adiw,r26,3) CR_TAB
2015 AS2 (ld,r29,X) CR_TAB
2016 AS2 (ld,r28,-X) CR_TAB
2017 AS2 (ld,__tmp_reg__,-X) CR_TAB
2018 AS2 (sbiw,r26,1) CR_TAB
2019 AS2 (ld,r26,X) CR_TAB
2020 AS2 (mov,r27,__tmp_reg__));
2021 else if (reg_dest == REG_X - 2)
2022 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2023 AS2 (ld,%B0,X+) CR_TAB
2024 AS2 (ld,__tmp_reg__,X+) CR_TAB
2025 AS2 (ld,%D0,X) CR_TAB
2026 AS2 (mov,%C0,__tmp_reg__));
2027 else if (reg_unused_after (insn, base))
2028 return *l=4, (AS2 (ld,%A0,X+) CR_TAB
2029 AS2 (ld,%B0,X+) CR_TAB
2030 AS2 (ld,%C0,X+) CR_TAB
2031 AS2 (ld,%D0,X));
2032 else
2033 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2034 AS2 (ld,%B0,X+) CR_TAB
2035 AS2 (ld,%C0,X+) CR_TAB
2036 AS2 (ld,%D0,X) CR_TAB
2037 AS2 (sbiw,r26,3));
2039 else
2041 if (reg_dest == reg_base)
2042 return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
2043 AS2 (ldd,%C0,%1+2) CR_TAB
2044 AS2 (ldd,__tmp_reg__,%1+1) CR_TAB
2045 AS2 (ld,%A0,%1) CR_TAB
2046 AS2 (mov,%B0,__tmp_reg__));
2047 else if (reg_base == reg_dest + 2)
2048 return *l=5, (AS2 (ld ,%A0,%1) CR_TAB
2049 AS2 (ldd,%B0,%1+1) CR_TAB
2050 AS2 (ldd,__tmp_reg__,%1+2) CR_TAB
2051 AS2 (ldd,%D0,%1+3) CR_TAB
2052 AS2 (mov,%C0,__tmp_reg__));
2053 else
2054 return *l=4, (AS2 (ld ,%A0,%1) CR_TAB
2055 AS2 (ldd,%B0,%1+1) CR_TAB
2056 AS2 (ldd,%C0,%1+2) CR_TAB
2057 AS2 (ldd,%D0,%1+3));
2060 else if (GET_CODE (base) == PLUS) /* (R + i) */
2062 int disp = INTVAL (XEXP (base, 1));
2064 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2066 if (REGNO (XEXP (base, 0)) != REG_Y)
2067 fatal_insn ("incorrect insn:",insn);
2069 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2070 return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2071 AS2 (ldd,%A0,Y+60) CR_TAB
2072 AS2 (ldd,%B0,Y+61) CR_TAB
2073 AS2 (ldd,%C0,Y+62) CR_TAB
2074 AS2 (ldd,%D0,Y+63) CR_TAB
2075 AS2 (sbiw,r28,%o1-60));
2077 return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2078 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2079 AS2 (ld,%A0,Y) CR_TAB
2080 AS2 (ldd,%B0,Y+1) CR_TAB
2081 AS2 (ldd,%C0,Y+2) CR_TAB
2082 AS2 (ldd,%D0,Y+3) CR_TAB
2083 AS2 (subi,r28,lo8(%o1)) CR_TAB
2084 AS2 (sbci,r29,hi8(%o1)));
2087 reg_base = true_regnum (XEXP (base, 0));
2088 if (reg_base == REG_X)
2090 /* R = (X + d) */
2091 if (reg_dest == REG_X)
2093 *l = 7;
2094 /* "ld r26,-X" is undefined */
2095 return (AS2 (adiw,r26,%o1+3) CR_TAB
2096 AS2 (ld,r29,X) CR_TAB
2097 AS2 (ld,r28,-X) CR_TAB
2098 AS2 (ld,__tmp_reg__,-X) CR_TAB
2099 AS2 (sbiw,r26,1) CR_TAB
2100 AS2 (ld,r26,X) CR_TAB
2101 AS2 (mov,r27,__tmp_reg__));
2103 *l = 6;
2104 if (reg_dest == REG_X - 2)
2105 return (AS2 (adiw,r26,%o1) CR_TAB
2106 AS2 (ld,r24,X+) CR_TAB
2107 AS2 (ld,r25,X+) CR_TAB
2108 AS2 (ld,__tmp_reg__,X+) CR_TAB
2109 AS2 (ld,r27,X) CR_TAB
2110 AS2 (mov,r26,__tmp_reg__));
2112 return (AS2 (adiw,r26,%o1) CR_TAB
2113 AS2 (ld,%A0,X+) CR_TAB
2114 AS2 (ld,%B0,X+) CR_TAB
2115 AS2 (ld,%C0,X+) CR_TAB
2116 AS2 (ld,%D0,X) CR_TAB
2117 AS2 (sbiw,r26,%o1+3));
2119 if (reg_dest == reg_base)
2120 return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2121 AS2 (ldd,%C0,%C1) CR_TAB
2122 AS2 (ldd,__tmp_reg__,%B1) CR_TAB
2123 AS2 (ldd,%A0,%A1) CR_TAB
2124 AS2 (mov,%B0,__tmp_reg__));
2125 else if (reg_dest == reg_base - 2)
2126 return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2127 AS2 (ldd,%B0,%B1) CR_TAB
2128 AS2 (ldd,__tmp_reg__,%C1) CR_TAB
2129 AS2 (ldd,%D0,%D1) CR_TAB
2130 AS2 (mov,%C0,__tmp_reg__));
2131 return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2132 AS2 (ldd,%B0,%B1) CR_TAB
2133 AS2 (ldd,%C0,%C1) CR_TAB
2134 AS2 (ldd,%D0,%D1));
2136 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2137 return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2138 AS2 (ld,%C0,%1) CR_TAB
2139 AS2 (ld,%B0,%1) CR_TAB
2140 AS2 (ld,%A0,%1));
2141 else if (GET_CODE (base) == POST_INC) /* (R++) */
2142 return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2143 AS2 (ld,%B0,%1) CR_TAB
2144 AS2 (ld,%C0,%1) CR_TAB
2145 AS2 (ld,%D0,%1));
2146 else if (CONSTANT_ADDRESS_P (base))
2147 return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2148 AS2 (lds,%B0,%B1) CR_TAB
2149 AS2 (lds,%C0,%C1) CR_TAB
2150 AS2 (lds,%D0,%D1));
2152 fatal_insn ("unknown move insn:",insn);
2153 return "";
2156 const char *
2157 out_movsi_mr_r (rtx insn, rtx op[], int *l)
2159 rtx dest = op[0];
2160 rtx src = op[1];
2161 rtx base = XEXP (dest, 0);
2162 int reg_base = true_regnum (base);
2163 int reg_src = true_regnum (src);
2164 int tmp;
2166 if (!l)
2167 l = &tmp;
2169 if (CONSTANT_ADDRESS_P (base))
2170 return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2171 AS2 (sts,%B0,%B1) CR_TAB
2172 AS2 (sts,%C0,%C1) CR_TAB
2173 AS2 (sts,%D0,%D1));
2174 if (reg_base > 0) /* (r) */
2176 if (reg_base == REG_X) /* (R26) */
2178 if (reg_src == REG_X)
2180 /* "st X+,r26" is undefined */
2181 if (reg_unused_after (insn, base))
2182 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2183 AS2 (st,X,r26) CR_TAB
2184 AS2 (adiw,r26,1) CR_TAB
2185 AS2 (st,X+,__tmp_reg__) CR_TAB
2186 AS2 (st,X+,r28) CR_TAB
2187 AS2 (st,X,r29));
2188 else
2189 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2190 AS2 (st,X,r26) CR_TAB
2191 AS2 (adiw,r26,1) CR_TAB
2192 AS2 (st,X+,__tmp_reg__) CR_TAB
2193 AS2 (st,X+,r28) CR_TAB
2194 AS2 (st,X,r29) CR_TAB
2195 AS2 (sbiw,r26,3));
2197 else if (reg_base == reg_src + 2)
2199 if (reg_unused_after (insn, base))
2200 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2201 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2202 AS2 (st,%0+,%A1) CR_TAB
2203 AS2 (st,%0+,%B1) CR_TAB
2204 AS2 (st,%0+,__zero_reg__) CR_TAB
2205 AS2 (st,%0,__tmp_reg__) CR_TAB
2206 AS1 (clr,__zero_reg__));
2207 else
2208 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2209 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2210 AS2 (st,%0+,%A1) CR_TAB
2211 AS2 (st,%0+,%B1) CR_TAB
2212 AS2 (st,%0+,__zero_reg__) CR_TAB
2213 AS2 (st,%0,__tmp_reg__) CR_TAB
2214 AS1 (clr,__zero_reg__) CR_TAB
2215 AS2 (sbiw,r26,3));
2217 return *l=5, (AS2 (st,%0+,%A1) CR_TAB
2218 AS2 (st,%0+,%B1) CR_TAB
2219 AS2 (st,%0+,%C1) CR_TAB
2220 AS2 (st,%0,%D1) CR_TAB
2221 AS2 (sbiw,r26,3));
2223 else
2224 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2225 AS2 (std,%0+1,%B1) CR_TAB
2226 AS2 (std,%0+2,%C1) CR_TAB
2227 AS2 (std,%0+3,%D1));
2229 else if (GET_CODE (base) == PLUS) /* (R + i) */
2231 int disp = INTVAL (XEXP (base, 1));
2232 reg_base = REGNO (XEXP (base, 0));
2233 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2235 if (reg_base != REG_Y)
2236 fatal_insn ("incorrect insn:",insn);
2238 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2239 return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2240 AS2 (std,Y+60,%A1) CR_TAB
2241 AS2 (std,Y+61,%B1) CR_TAB
2242 AS2 (std,Y+62,%C1) CR_TAB
2243 AS2 (std,Y+63,%D1) CR_TAB
2244 AS2 (sbiw,r28,%o0-60));
2246 return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2247 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2248 AS2 (st,Y,%A1) CR_TAB
2249 AS2 (std,Y+1,%B1) CR_TAB
2250 AS2 (std,Y+2,%C1) CR_TAB
2251 AS2 (std,Y+3,%D1) CR_TAB
2252 AS2 (subi,r28,lo8(%o0)) CR_TAB
2253 AS2 (sbci,r29,hi8(%o0)));
2255 if (reg_base == REG_X)
2257 /* (X + d) = R */
2258 if (reg_src == REG_X)
2260 *l = 9;
2261 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2262 AS2 (mov,__zero_reg__,r27) CR_TAB
2263 AS2 (adiw,r26,%o0) CR_TAB
2264 AS2 (st,X+,__tmp_reg__) CR_TAB
2265 AS2 (st,X+,__zero_reg__) CR_TAB
2266 AS2 (st,X+,r28) CR_TAB
2267 AS2 (st,X,r29) CR_TAB
2268 AS1 (clr,__zero_reg__) CR_TAB
2269 AS2 (sbiw,r26,%o0+3));
2271 else if (reg_src == REG_X - 2)
2273 *l = 9;
2274 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2275 AS2 (mov,__zero_reg__,r27) CR_TAB
2276 AS2 (adiw,r26,%o0) CR_TAB
2277 AS2 (st,X+,r24) CR_TAB
2278 AS2 (st,X+,r25) CR_TAB
2279 AS2 (st,X+,__tmp_reg__) CR_TAB
2280 AS2 (st,X,__zero_reg__) CR_TAB
2281 AS1 (clr,__zero_reg__) CR_TAB
2282 AS2 (sbiw,r26,%o0+3));
2284 *l = 6;
2285 return (AS2 (adiw,r26,%o0) CR_TAB
2286 AS2 (st,X+,%A1) CR_TAB
2287 AS2 (st,X+,%B1) CR_TAB
2288 AS2 (st,X+,%C1) CR_TAB
2289 AS2 (st,X,%D1) CR_TAB
2290 AS2 (sbiw,r26,%o0+3));
2292 return *l=4, (AS2 (std,%A0,%A1) CR_TAB
2293 AS2 (std,%B0,%B1) CR_TAB
2294 AS2 (std,%C0,%C1) CR_TAB
2295 AS2 (std,%D0,%D1));
2297 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2298 return *l=4, (AS2 (st,%0,%D1) CR_TAB
2299 AS2 (st,%0,%C1) CR_TAB
2300 AS2 (st,%0,%B1) CR_TAB
2301 AS2 (st,%0,%A1));
2302 else if (GET_CODE (base) == POST_INC) /* (R++) */
2303 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2304 AS2 (st,%0,%B1) CR_TAB
2305 AS2 (st,%0,%C1) CR_TAB
2306 AS2 (st,%0,%D1));
2307 fatal_insn ("unknown move insn:",insn);
2308 return "";
2311 const char *
2312 output_movsisf(rtx insn, rtx operands[], int *l)
2314 int dummy;
2315 rtx dest = operands[0];
2316 rtx src = operands[1];
2317 int *real_l = l;
2319 if (!l)
2320 l = &dummy;
2322 if (register_operand (dest, VOIDmode))
2324 if (register_operand (src, VOIDmode)) /* mov r,r */
2326 if (true_regnum (dest) > true_regnum (src))
2328 if (AVR_ENHANCED)
2330 *l = 2;
2331 return (AS2 (movw,%C0,%C1) CR_TAB
2332 AS2 (movw,%A0,%A1));
2334 *l = 4;
2335 return (AS2 (mov,%D0,%D1) CR_TAB
2336 AS2 (mov,%C0,%C1) CR_TAB
2337 AS2 (mov,%B0,%B1) CR_TAB
2338 AS2 (mov,%A0,%A1));
2340 else
2342 if (AVR_ENHANCED)
2344 *l = 2;
2345 return (AS2 (movw,%A0,%A1) CR_TAB
2346 AS2 (movw,%C0,%C1));
2348 *l = 4;
2349 return (AS2 (mov,%A0,%A1) CR_TAB
2350 AS2 (mov,%B0,%B1) CR_TAB
2351 AS2 (mov,%C0,%C1) CR_TAB
2352 AS2 (mov,%D0,%D1));
2355 else if (CONSTANT_P (src))
2357 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2359 *l = 4;
2360 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
2361 AS2 (ldi,%B0,hi8(%1)) CR_TAB
2362 AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2363 AS2 (ldi,%D0,hhi8(%1)));
2366 if (GET_CODE (src) == CONST_INT)
2368 const char *const clr_op0 =
2369 AVR_ENHANCED ? (AS1 (clr,%A0) CR_TAB
2370 AS1 (clr,%B0) CR_TAB
2371 AS2 (movw,%C0,%A0))
2372 : (AS1 (clr,%A0) CR_TAB
2373 AS1 (clr,%B0) CR_TAB
2374 AS1 (clr,%C0) CR_TAB
2375 AS1 (clr,%D0));
2377 if (src == const0_rtx) /* mov r,L */
2379 *l = AVR_ENHANCED ? 3 : 4;
2380 return clr_op0;
2382 else if (src == const1_rtx)
2384 if (!real_l)
2385 output_asm_insn (clr_op0, operands);
2386 *l = AVR_ENHANCED ? 4 : 5;
2387 return AS1 (inc,%A0);
2389 else if (src == constm1_rtx)
2391 /* Immediate constants -1 to any register */
2392 if (AVR_ENHANCED)
2394 *l = 4;
2395 return (AS1 (clr,%A0) CR_TAB
2396 AS1 (dec,%A0) CR_TAB
2397 AS2 (mov,%B0,%A0) CR_TAB
2398 AS2 (movw,%C0,%A0));
2400 *l = 5;
2401 return (AS1 (clr,%A0) CR_TAB
2402 AS1 (dec,%A0) CR_TAB
2403 AS2 (mov,%B0,%A0) CR_TAB
2404 AS2 (mov,%C0,%A0) CR_TAB
2405 AS2 (mov,%D0,%A0));
2407 else
2409 int bit_nr = exact_log2 (INTVAL (src));
2411 if (bit_nr >= 0)
2413 *l = AVR_ENHANCED ? 5 : 6;
2414 if (!real_l)
2416 output_asm_insn (clr_op0, operands);
2417 output_asm_insn ("set", operands);
2419 if (!real_l)
2420 avr_output_bld (operands, bit_nr);
2422 return "";
2427 /* Last resort, better than loading from memory. */
2428 *l = 10;
2429 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2430 AS2 (ldi,r31,lo8(%1)) CR_TAB
2431 AS2 (mov,%A0,r31) CR_TAB
2432 AS2 (ldi,r31,hi8(%1)) CR_TAB
2433 AS2 (mov,%B0,r31) CR_TAB
2434 AS2 (ldi,r31,hlo8(%1)) CR_TAB
2435 AS2 (mov,%C0,r31) CR_TAB
2436 AS2 (ldi,r31,hhi8(%1)) CR_TAB
2437 AS2 (mov,%D0,r31) CR_TAB
2438 AS2 (mov,r31,__tmp_reg__));
2440 else if (GET_CODE (src) == MEM)
2441 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2443 else if (GET_CODE (dest) == MEM)
2445 const char *template;
2447 if (src == const0_rtx)
2448 operands[1] = zero_reg_rtx;
2450 template = out_movsi_mr_r (insn, operands, real_l);
2452 if (!real_l)
2453 output_asm_insn (template, operands);
2455 operands[1] = src;
2456 return "";
2458 fatal_insn ("invalid insn:", insn);
2459 return "";
2462 const char *
2463 out_movqi_mr_r (rtx insn, rtx op[], int *l)
2465 rtx dest = op[0];
2466 rtx src = op[1];
2467 rtx x = XEXP (dest, 0);
2468 int dummy;
2470 if (!l)
2471 l = &dummy;
2473 if (CONSTANT_ADDRESS_P (x))
2475 if (avr_io_address_p (x, 1))
2477 *l = 1;
2478 return AS2 (out,%0-0x20,%1);
2480 *l = 2;
2481 return AS2 (sts,%0,%1);
2483 /* memory access by reg+disp */
2484 else if (GET_CODE (x) == PLUS
2485 && REG_P (XEXP (x,0))
2486 && GET_CODE (XEXP (x,1)) == CONST_INT)
2488 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2490 int disp = INTVAL (XEXP (x,1));
2491 if (REGNO (XEXP (x,0)) != REG_Y)
2492 fatal_insn ("incorrect insn:",insn);
2494 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2495 return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2496 AS2 (std,Y+63,%1) CR_TAB
2497 AS2 (sbiw,r28,%o0-63));
2499 return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2500 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2501 AS2 (st,Y,%1) CR_TAB
2502 AS2 (subi,r28,lo8(%o0)) CR_TAB
2503 AS2 (sbci,r29,hi8(%o0)));
2505 else if (REGNO (XEXP (x,0)) == REG_X)
2507 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2509 if (reg_unused_after (insn, XEXP (x,0)))
2510 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2511 AS2 (adiw,r26,%o0) CR_TAB
2512 AS2 (st,X,__tmp_reg__));
2514 return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2515 AS2 (adiw,r26,%o0) CR_TAB
2516 AS2 (st,X,__tmp_reg__) CR_TAB
2517 AS2 (sbiw,r26,%o0));
2519 else
2521 if (reg_unused_after (insn, XEXP (x,0)))
2522 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2523 AS2 (st,X,%1));
2525 return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2526 AS2 (st,X,%1) CR_TAB
2527 AS2 (sbiw,r26,%o0));
2530 *l = 1;
2531 return AS2 (std,%0,%1);
2533 *l = 1;
2534 return AS2 (st,%0,%1);
2537 const char *
2538 out_movhi_mr_r (rtx insn, rtx op[], int *l)
2540 rtx dest = op[0];
2541 rtx src = op[1];
2542 rtx base = XEXP (dest, 0);
2543 int reg_base = true_regnum (base);
2544 int reg_src = true_regnum (src);
2545 /* "volatile" forces writing high byte first, even if less efficient,
2546 for correct operation with 16-bit I/O registers. */
2547 int mem_volatile_p = MEM_VOLATILE_P (dest);
2548 int tmp;
2550 if (!l)
2551 l = &tmp;
2552 if (CONSTANT_ADDRESS_P (base))
2554 if (avr_io_address_p (base, 2))
2556 *l = 2;
2557 return (AS2 (out,%B0-0x20,%B1) CR_TAB
2558 AS2 (out,%A0-0x20,%A1));
2560 return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2561 AS2 (sts,%A0,%A1));
2563 if (reg_base > 0)
2565 if (reg_base == REG_X)
2567 if (reg_src == REG_X)
2569 /* "st X+,r26" and "st -X,r26" are undefined. */
2570 if (!mem_volatile_p && reg_unused_after (insn, src))
2571 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2572 AS2 (st,X,r26) CR_TAB
2573 AS2 (adiw,r26,1) CR_TAB
2574 AS2 (st,X,__tmp_reg__));
2575 else
2576 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2577 AS2 (adiw,r26,1) CR_TAB
2578 AS2 (st,X,__tmp_reg__) CR_TAB
2579 AS2 (sbiw,r26,1) CR_TAB
2580 AS2 (st,X,r26));
2582 else
2584 if (!mem_volatile_p && reg_unused_after (insn, base))
2585 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2586 AS2 (st,X,%B1));
2587 else
2588 return *l=3, (AS2 (adiw,r26,1) CR_TAB
2589 AS2 (st,X,%B1) CR_TAB
2590 AS2 (st,-X,%A1));
2593 else
2594 return *l=2, (AS2 (std,%0+1,%B1) CR_TAB
2595 AS2 (st,%0,%A1));
2597 else if (GET_CODE (base) == PLUS)
2599 int disp = INTVAL (XEXP (base, 1));
2600 reg_base = REGNO (XEXP (base, 0));
2601 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2603 if (reg_base != REG_Y)
2604 fatal_insn ("incorrect insn:",insn);
2606 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2607 return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2608 AS2 (std,Y+63,%B1) CR_TAB
2609 AS2 (std,Y+62,%A1) CR_TAB
2610 AS2 (sbiw,r28,%o0-62));
2612 return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2613 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2614 AS2 (std,Y+1,%B1) CR_TAB
2615 AS2 (st,Y,%A1) CR_TAB
2616 AS2 (subi,r28,lo8(%o0)) CR_TAB
2617 AS2 (sbci,r29,hi8(%o0)));
2619 if (reg_base == REG_X)
2621 /* (X + d) = R */
2622 if (reg_src == REG_X)
2624 *l = 7;
2625 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2626 AS2 (mov,__zero_reg__,r27) CR_TAB
2627 AS2 (adiw,r26,%o0+1) CR_TAB
2628 AS2 (st,X,__zero_reg__) CR_TAB
2629 AS2 (st,-X,__tmp_reg__) CR_TAB
2630 AS1 (clr,__zero_reg__) CR_TAB
2631 AS2 (sbiw,r26,%o0));
2633 *l = 4;
2634 return (AS2 (adiw,r26,%o0+1) CR_TAB
2635 AS2 (st,X,%B1) CR_TAB
2636 AS2 (st,-X,%A1) CR_TAB
2637 AS2 (sbiw,r26,%o0));
2639 return *l=2, (AS2 (std,%B0,%B1) CR_TAB
2640 AS2 (std,%A0,%A1));
2642 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2643 return *l=2, (AS2 (st,%0,%B1) CR_TAB
2644 AS2 (st,%0,%A1));
2645 else if (GET_CODE (base) == POST_INC) /* (R++) */
2647 if (mem_volatile_p)
2649 if (REGNO (XEXP (base, 0)) == REG_X)
2651 *l = 4;
2652 return (AS2 (adiw,r26,1) CR_TAB
2653 AS2 (st,X,%B1) CR_TAB
2654 AS2 (st,-X,%A1) CR_TAB
2655 AS2 (adiw,r26,2));
2657 else
2659 *l = 3;
2660 return (AS2 (std,%p0+1,%B1) CR_TAB
2661 AS2 (st,%p0,%A1) CR_TAB
2662 AS2 (adiw,%r0,2));
2666 *l = 2;
2667 return (AS2 (st,%0,%A1) CR_TAB
2668 AS2 (st,%0,%B1));
2670 fatal_insn ("unknown move insn:",insn);
2671 return "";
2674 /* Return 1 if frame pointer for current function required. */
2677 frame_pointer_required_p (void)
2679 return (current_function_calls_alloca
2680 || current_function_args_info.nregs == 0
2681 || get_frame_size () > 0);
2684 /* Returns the condition of compare insn INSN, or UNKNOWN. */
2686 static RTX_CODE
2687 compare_condition (rtx insn)
2689 rtx next = next_real_insn (insn);
2690 RTX_CODE cond = UNKNOWN;
2691 if (next && GET_CODE (next) == JUMP_INSN)
2693 rtx pat = PATTERN (next);
2694 rtx src = SET_SRC (pat);
2695 rtx t = XEXP (src, 0);
2696 cond = GET_CODE (t);
2698 return cond;
2701 /* Returns nonzero if INSN is a tst insn that only tests the sign. */
2703 static int
2704 compare_sign_p (rtx insn)
2706 RTX_CODE cond = compare_condition (insn);
2707 return (cond == GE || cond == LT);
2710 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
2711 that needs to be swapped (GT, GTU, LE, LEU). */
2714 compare_diff_p (rtx insn)
2716 RTX_CODE cond = compare_condition (insn);
2717 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2720 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition. */
2723 compare_eq_p (rtx insn)
2725 RTX_CODE cond = compare_condition (insn);
2726 return (cond == EQ || cond == NE);
2730 /* Output test instruction for HImode. */
2732 const char *
2733 out_tsthi (rtx insn, int *l)
2735 if (compare_sign_p (insn))
2737 if (l) *l = 1;
2738 return AS1 (tst,%B0);
2740 if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
2741 && compare_eq_p (insn))
2743 /* Faster than sbiw if we can clobber the operand. */
2744 if (l) *l = 1;
2745 return AS2 (or,%A0,%B0);
2747 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2749 if (l) *l = 1;
2750 return AS2 (sbiw,%0,0);
2752 if (l) *l = 2;
2753 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2754 AS2 (cpc,%B0,__zero_reg__));
2758 /* Output test instruction for SImode. */
2760 const char *
2761 out_tstsi (rtx insn, int *l)
2763 if (compare_sign_p (insn))
2765 if (l) *l = 1;
2766 return AS1 (tst,%D0);
2768 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2770 if (l) *l = 3;
2771 return (AS2 (sbiw,%A0,0) CR_TAB
2772 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2773 AS2 (cpc,%D0,__zero_reg__));
2775 if (l) *l = 4;
2776 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2777 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2778 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2779 AS2 (cpc,%D0,__zero_reg__));
2783 /* Generate asm equivalent for various shifts.
2784 Shift count is a CONST_INT, MEM or REG.
2785 This only handles cases that are not already
2786 carefully hand-optimized in ?sh??i3_out. */
2788 void
2789 out_shift_with_cnt (const char *template, rtx insn, rtx operands[],
2790 int *len, int t_len)
2792 rtx op[10];
2793 char str[500];
2794 int second_label = 1;
2795 int saved_in_tmp = 0;
2796 int use_zero_reg = 0;
2798 op[0] = operands[0];
2799 op[1] = operands[1];
2800 op[2] = operands[2];
2801 op[3] = operands[3];
2802 str[0] = 0;
2804 if (len)
2805 *len = 1;
2807 if (GET_CODE (operands[2]) == CONST_INT)
2809 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2810 int count = INTVAL (operands[2]);
2811 int max_len = 10; /* If larger than this, always use a loop. */
2813 if (count <= 0)
2815 if (len)
2816 *len = 0;
2817 return;
2820 if (count < 8 && !scratch)
2821 use_zero_reg = 1;
2823 if (optimize_size)
2824 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
2826 if (t_len * count <= max_len)
2828 /* Output shifts inline with no loop - faster. */
2829 if (len)
2830 *len = t_len * count;
2831 else
2833 while (count-- > 0)
2834 output_asm_insn (template, op);
2837 return;
2840 if (scratch)
2842 if (!len)
2843 strcat (str, AS2 (ldi,%3,%2));
2845 else if (use_zero_reg)
2847 /* Hack to save one word: use __zero_reg__ as loop counter.
2848 Set one bit, then shift in a loop until it is 0 again. */
2850 op[3] = zero_reg_rtx;
2851 if (len)
2852 *len = 2;
2853 else
2854 strcat (str, ("set" CR_TAB
2855 AS2 (bld,%3,%2-1)));
2857 else
2859 /* No scratch register available, use one from LD_REGS (saved in
2860 __tmp_reg__) that doesn't overlap with registers to shift. */
2862 op[3] = gen_rtx_REG (QImode,
2863 ((true_regnum (operands[0]) - 1) & 15) + 16);
2864 op[4] = tmp_reg_rtx;
2865 saved_in_tmp = 1;
2867 if (len)
2868 *len = 3; /* Includes "mov %3,%4" after the loop. */
2869 else
2870 strcat (str, (AS2 (mov,%4,%3) CR_TAB
2871 AS2 (ldi,%3,%2)));
2874 second_label = 0;
2876 else if (GET_CODE (operands[2]) == MEM)
2878 rtx op_mov[10];
2880 op[3] = op_mov[0] = tmp_reg_rtx;
2881 op_mov[1] = op[2];
2883 if (len)
2884 out_movqi_r_mr (insn, op_mov, len);
2885 else
2886 output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2888 else if (register_operand (operands[2], QImode))
2890 if (reg_unused_after (insn, operands[2]))
2891 op[3] = op[2];
2892 else
2894 op[3] = tmp_reg_rtx;
2895 if (!len)
2896 strcat (str, (AS2 (mov,%3,%2) CR_TAB));
2899 else
2900 fatal_insn ("bad shift insn:", insn);
2902 if (second_label)
2904 if (len)
2905 ++*len;
2906 else
2907 strcat (str, AS1 (rjmp,2f));
2910 if (len)
2911 *len += t_len + 2; /* template + dec + brXX */
2912 else
2914 strcat (str, "\n1:\t");
2915 strcat (str, template);
2916 strcat (str, second_label ? "\n2:\t" : "\n\t");
2917 strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
2918 strcat (str, CR_TAB);
2919 strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
2920 if (saved_in_tmp)
2921 strcat (str, (CR_TAB AS2 (mov,%3,%4)));
2922 output_asm_insn (str, op);
2927 /* 8bit shift left ((char)x << i) */
2929 const char *
2930 ashlqi3_out (rtx insn, rtx operands[], int *len)
2932 if (GET_CODE (operands[2]) == CONST_INT)
2934 int k;
2936 if (!len)
2937 len = &k;
2939 switch (INTVAL (operands[2]))
2941 default:
2942 if (INTVAL (operands[2]) < 8)
2943 break;
2945 *len = 1;
2946 return AS1 (clr,%0);
2948 case 1:
2949 *len = 1;
2950 return AS1 (lsl,%0);
2952 case 2:
2953 *len = 2;
2954 return (AS1 (lsl,%0) CR_TAB
2955 AS1 (lsl,%0));
2957 case 3:
2958 *len = 3;
2959 return (AS1 (lsl,%0) CR_TAB
2960 AS1 (lsl,%0) CR_TAB
2961 AS1 (lsl,%0));
2963 case 4:
2964 if (test_hard_reg_class (LD_REGS, operands[0]))
2966 *len = 2;
2967 return (AS1 (swap,%0) CR_TAB
2968 AS2 (andi,%0,0xf0));
2970 *len = 4;
2971 return (AS1 (lsl,%0) CR_TAB
2972 AS1 (lsl,%0) CR_TAB
2973 AS1 (lsl,%0) CR_TAB
2974 AS1 (lsl,%0));
2976 case 5:
2977 if (test_hard_reg_class (LD_REGS, operands[0]))
2979 *len = 3;
2980 return (AS1 (swap,%0) CR_TAB
2981 AS1 (lsl,%0) CR_TAB
2982 AS2 (andi,%0,0xe0));
2984 *len = 5;
2985 return (AS1 (lsl,%0) CR_TAB
2986 AS1 (lsl,%0) CR_TAB
2987 AS1 (lsl,%0) CR_TAB
2988 AS1 (lsl,%0) CR_TAB
2989 AS1 (lsl,%0));
2991 case 6:
2992 if (test_hard_reg_class (LD_REGS, operands[0]))
2994 *len = 4;
2995 return (AS1 (swap,%0) CR_TAB
2996 AS1 (lsl,%0) CR_TAB
2997 AS1 (lsl,%0) CR_TAB
2998 AS2 (andi,%0,0xc0));
3000 *len = 6;
3001 return (AS1 (lsl,%0) CR_TAB
3002 AS1 (lsl,%0) CR_TAB
3003 AS1 (lsl,%0) CR_TAB
3004 AS1 (lsl,%0) CR_TAB
3005 AS1 (lsl,%0) CR_TAB
3006 AS1 (lsl,%0));
3008 case 7:
3009 *len = 3;
3010 return (AS1 (ror,%0) CR_TAB
3011 AS1 (clr,%0) CR_TAB
3012 AS1 (ror,%0));
3015 else if (CONSTANT_P (operands[2]))
3016 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3018 out_shift_with_cnt (AS1 (lsl,%0),
3019 insn, operands, len, 1);
3020 return "";
3024 /* 16bit shift left ((short)x << i) */
3026 const char *
3027 ashlhi3_out (rtx insn, rtx operands[], int *len)
3029 if (GET_CODE (operands[2]) == CONST_INT)
3031 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3032 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3033 int k;
3034 int *t = len;
3036 if (!len)
3037 len = &k;
3039 switch (INTVAL (operands[2]))
3041 default:
3042 if (INTVAL (operands[2]) < 16)
3043 break;
3045 *len = 2;
3046 return (AS1 (clr,%B0) CR_TAB
3047 AS1 (clr,%A0));
3049 case 4:
3050 if (optimize_size && scratch)
3051 break; /* 5 */
3052 if (ldi_ok)
3054 *len = 6;
3055 return (AS1 (swap,%A0) CR_TAB
3056 AS1 (swap,%B0) CR_TAB
3057 AS2 (andi,%B0,0xf0) CR_TAB
3058 AS2 (eor,%B0,%A0) CR_TAB
3059 AS2 (andi,%A0,0xf0) CR_TAB
3060 AS2 (eor,%B0,%A0));
3062 if (scratch)
3064 *len = 7;
3065 return (AS1 (swap,%A0) CR_TAB
3066 AS1 (swap,%B0) CR_TAB
3067 AS2 (ldi,%3,0xf0) CR_TAB
3068 AS2 (and,%B0,%3) CR_TAB
3069 AS2 (eor,%B0,%A0) CR_TAB
3070 AS2 (and,%A0,%3) CR_TAB
3071 AS2 (eor,%B0,%A0));
3073 break; /* optimize_size ? 6 : 8 */
3075 case 5:
3076 if (optimize_size)
3077 break; /* scratch ? 5 : 6 */
3078 if (ldi_ok)
3080 *len = 8;
3081 return (AS1 (lsl,%A0) CR_TAB
3082 AS1 (rol,%B0) CR_TAB
3083 AS1 (swap,%A0) CR_TAB
3084 AS1 (swap,%B0) CR_TAB
3085 AS2 (andi,%B0,0xf0) CR_TAB
3086 AS2 (eor,%B0,%A0) CR_TAB
3087 AS2 (andi,%A0,0xf0) CR_TAB
3088 AS2 (eor,%B0,%A0));
3090 if (scratch)
3092 *len = 9;
3093 return (AS1 (lsl,%A0) CR_TAB
3094 AS1 (rol,%B0) CR_TAB
3095 AS1 (swap,%A0) CR_TAB
3096 AS1 (swap,%B0) CR_TAB
3097 AS2 (ldi,%3,0xf0) CR_TAB
3098 AS2 (and,%B0,%3) CR_TAB
3099 AS2 (eor,%B0,%A0) CR_TAB
3100 AS2 (and,%A0,%3) CR_TAB
3101 AS2 (eor,%B0,%A0));
3103 break; /* 10 */
3105 case 6:
3106 if (optimize_size)
3107 break; /* scratch ? 5 : 6 */
3108 *len = 9;
3109 return (AS1 (clr,__tmp_reg__) CR_TAB
3110 AS1 (lsr,%B0) CR_TAB
3111 AS1 (ror,%A0) CR_TAB
3112 AS1 (ror,__tmp_reg__) CR_TAB
3113 AS1 (lsr,%B0) CR_TAB
3114 AS1 (ror,%A0) CR_TAB
3115 AS1 (ror,__tmp_reg__) CR_TAB
3116 AS2 (mov,%B0,%A0) CR_TAB
3117 AS2 (mov,%A0,__tmp_reg__));
3119 case 7:
3120 *len = 5;
3121 return (AS1 (lsr,%B0) CR_TAB
3122 AS2 (mov,%B0,%A0) CR_TAB
3123 AS1 (clr,%A0) CR_TAB
3124 AS1 (ror,%B0) CR_TAB
3125 AS1 (ror,%A0));
3127 case 8:
3128 if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
3129 return *len = 1, AS1 (clr,%A0);
3130 else
3131 return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3132 AS1 (clr,%A0));
3134 case 9:
3135 *len = 3;
3136 return (AS2 (mov,%B0,%A0) CR_TAB
3137 AS1 (clr,%A0) CR_TAB
3138 AS1 (lsl,%B0));
3140 case 10:
3141 *len = 4;
3142 return (AS2 (mov,%B0,%A0) CR_TAB
3143 AS1 (clr,%A0) CR_TAB
3144 AS1 (lsl,%B0) CR_TAB
3145 AS1 (lsl,%B0));
3147 case 11:
3148 *len = 5;
3149 return (AS2 (mov,%B0,%A0) CR_TAB
3150 AS1 (clr,%A0) CR_TAB
3151 AS1 (lsl,%B0) CR_TAB
3152 AS1 (lsl,%B0) CR_TAB
3153 AS1 (lsl,%B0));
3155 case 12:
3156 if (ldi_ok)
3158 *len = 4;
3159 return (AS2 (mov,%B0,%A0) CR_TAB
3160 AS1 (clr,%A0) CR_TAB
3161 AS1 (swap,%B0) CR_TAB
3162 AS2 (andi,%B0,0xf0));
3164 if (scratch)
3166 *len = 5;
3167 return (AS2 (mov,%B0,%A0) CR_TAB
3168 AS1 (clr,%A0) CR_TAB
3169 AS1 (swap,%B0) CR_TAB
3170 AS2 (ldi,%3,0xf0) CR_TAB
3171 AS2 (and,%B0,%3));
3173 *len = 6;
3174 return (AS2 (mov,%B0,%A0) CR_TAB
3175 AS1 (clr,%A0) CR_TAB
3176 AS1 (lsl,%B0) CR_TAB
3177 AS1 (lsl,%B0) CR_TAB
3178 AS1 (lsl,%B0) CR_TAB
3179 AS1 (lsl,%B0));
3181 case 13:
3182 if (ldi_ok)
3184 *len = 5;
3185 return (AS2 (mov,%B0,%A0) CR_TAB
3186 AS1 (clr,%A0) CR_TAB
3187 AS1 (swap,%B0) CR_TAB
3188 AS1 (lsl,%B0) CR_TAB
3189 AS2 (andi,%B0,0xe0));
3191 if (AVR_ENHANCED && scratch)
3193 *len = 5;
3194 return (AS2 (ldi,%3,0x20) CR_TAB
3195 AS2 (mul,%A0,%3) CR_TAB
3196 AS2 (mov,%B0,r0) CR_TAB
3197 AS1 (clr,%A0) CR_TAB
3198 AS1 (clr,__zero_reg__));
3200 if (optimize_size && scratch)
3201 break; /* 5 */
3202 if (scratch)
3204 *len = 6;
3205 return (AS2 (mov,%B0,%A0) CR_TAB
3206 AS1 (clr,%A0) CR_TAB
3207 AS1 (swap,%B0) CR_TAB
3208 AS1 (lsl,%B0) CR_TAB
3209 AS2 (ldi,%3,0xe0) CR_TAB
3210 AS2 (and,%B0,%3));
3212 if (AVR_ENHANCED)
3214 *len = 6;
3215 return ("set" CR_TAB
3216 AS2 (bld,r1,5) CR_TAB
3217 AS2 (mul,%A0,r1) CR_TAB
3218 AS2 (mov,%B0,r0) CR_TAB
3219 AS1 (clr,%A0) CR_TAB
3220 AS1 (clr,__zero_reg__));
3222 *len = 7;
3223 return (AS2 (mov,%B0,%A0) CR_TAB
3224 AS1 (clr,%A0) CR_TAB
3225 AS1 (lsl,%B0) CR_TAB
3226 AS1 (lsl,%B0) CR_TAB
3227 AS1 (lsl,%B0) CR_TAB
3228 AS1 (lsl,%B0) CR_TAB
3229 AS1 (lsl,%B0));
3231 case 14:
3232 if (AVR_ENHANCED && ldi_ok)
3234 *len = 5;
3235 return (AS2 (ldi,%B0,0x40) CR_TAB
3236 AS2 (mul,%A0,%B0) CR_TAB
3237 AS2 (mov,%B0,r0) CR_TAB
3238 AS1 (clr,%A0) CR_TAB
3239 AS1 (clr,__zero_reg__));
3241 if (AVR_ENHANCED && scratch)
3243 *len = 5;
3244 return (AS2 (ldi,%3,0x40) CR_TAB
3245 AS2 (mul,%A0,%3) CR_TAB
3246 AS2 (mov,%B0,r0) CR_TAB
3247 AS1 (clr,%A0) CR_TAB
3248 AS1 (clr,__zero_reg__));
3250 if (optimize_size && ldi_ok)
3252 *len = 5;
3253 return (AS2 (mov,%B0,%A0) CR_TAB
3254 AS2 (ldi,%A0,6) "\n1:\t"
3255 AS1 (lsl,%B0) CR_TAB
3256 AS1 (dec,%A0) CR_TAB
3257 AS1 (brne,1b));
3259 if (optimize_size && scratch)
3260 break; /* 5 */
3261 *len = 6;
3262 return (AS1 (clr,%B0) CR_TAB
3263 AS1 (lsr,%A0) CR_TAB
3264 AS1 (ror,%B0) CR_TAB
3265 AS1 (lsr,%A0) CR_TAB
3266 AS1 (ror,%B0) CR_TAB
3267 AS1 (clr,%A0));
3269 case 15:
3270 *len = 4;
3271 return (AS1 (clr,%B0) CR_TAB
3272 AS1 (lsr,%A0) CR_TAB
3273 AS1 (ror,%B0) CR_TAB
3274 AS1 (clr,%A0));
3276 len = t;
3278 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3279 AS1 (rol,%B0)),
3280 insn, operands, len, 2);
3281 return "";
3285 /* 32bit shift left ((long)x << i) */
3287 const char *
3288 ashlsi3_out (rtx insn, rtx operands[], int *len)
3290 if (GET_CODE (operands[2]) == CONST_INT)
3292 int k;
3293 int *t = len;
3295 if (!len)
3296 len = &k;
3298 switch (INTVAL (operands[2]))
3300 default:
3301 if (INTVAL (operands[2]) < 32)
3302 break;
3304 if (AVR_ENHANCED)
3305 return *len = 3, (AS1 (clr,%D0) CR_TAB
3306 AS1 (clr,%C0) CR_TAB
3307 AS2 (movw,%A0,%C0));
3308 *len = 4;
3309 return (AS1 (clr,%D0) CR_TAB
3310 AS1 (clr,%C0) CR_TAB
3311 AS1 (clr,%B0) CR_TAB
3312 AS1 (clr,%A0));
3314 case 8:
3316 int reg0 = true_regnum (operands[0]);
3317 int reg1 = true_regnum (operands[1]);
3318 *len = 4;
3319 if (reg0 >= reg1)
3320 return (AS2 (mov,%D0,%C1) CR_TAB
3321 AS2 (mov,%C0,%B1) CR_TAB
3322 AS2 (mov,%B0,%A1) CR_TAB
3323 AS1 (clr,%A0));
3324 else if (reg0 + 1 == reg1)
3326 *len = 1;
3327 return AS1 (clr,%A0);
3329 else
3330 return (AS1 (clr,%A0) CR_TAB
3331 AS2 (mov,%B0,%A1) CR_TAB
3332 AS2 (mov,%C0,%B1) CR_TAB
3333 AS2 (mov,%D0,%C1));
3336 case 16:
3338 int reg0 = true_regnum (operands[0]);
3339 int reg1 = true_regnum (operands[1]);
3340 *len = 4;
3341 if (AVR_ENHANCED && (reg0 + 2 != reg1))
3343 *len = 3;
3344 return (AS2 (movw,%C0,%A1) CR_TAB
3345 AS1 (clr,%B0) CR_TAB
3346 AS1 (clr,%A0));
3348 if (reg0 + 1 >= reg1)
3349 return (AS2 (mov,%D0,%B1) CR_TAB
3350 AS2 (mov,%C0,%A1) CR_TAB
3351 AS1 (clr,%B0) CR_TAB
3352 AS1 (clr,%A0));
3353 if (reg0 + 2 == reg1)
3355 *len = 2;
3356 return (AS1 (clr,%B0) CR_TAB
3357 AS1 (clr,%A0));
3359 else
3360 return (AS2 (mov,%C0,%A1) CR_TAB
3361 AS2 (mov,%D0,%B1) CR_TAB
3362 AS1 (clr,%B0) CR_TAB
3363 AS1 (clr,%A0));
3366 case 24:
3367 *len = 4;
3368 if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
3369 return (AS2 (mov,%D0,%A1) CR_TAB
3370 AS1 (clr,%C0) CR_TAB
3371 AS1 (clr,%B0) CR_TAB
3372 AS1 (clr,%A0));
3373 else
3375 *len = 3;
3376 return (AS1 (clr,%C0) CR_TAB
3377 AS1 (clr,%B0) CR_TAB
3378 AS1 (clr,%A0));
3381 case 31:
3382 *len = 6;
3383 return (AS1 (clr,%D0) CR_TAB
3384 AS1 (lsr,%A0) CR_TAB
3385 AS1 (ror,%D0) CR_TAB
3386 AS1 (clr,%C0) CR_TAB
3387 AS1 (clr,%B0) CR_TAB
3388 AS1 (clr,%A0));
3390 len = t;
3392 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3393 AS1 (rol,%B0) CR_TAB
3394 AS1 (rol,%C0) CR_TAB
3395 AS1 (rol,%D0)),
3396 insn, operands, len, 4);
3397 return "";
3400 /* 8bit arithmetic shift right ((signed char)x >> i) */
3402 const char *
3403 ashrqi3_out (rtx insn, rtx operands[], int *len)
3405 if (GET_CODE (operands[2]) == CONST_INT)
3407 int k;
3409 if (!len)
3410 len = &k;
3412 switch (INTVAL (operands[2]))
3414 case 1:
3415 *len = 1;
3416 return AS1 (asr,%0);
3418 case 2:
3419 *len = 2;
3420 return (AS1 (asr,%0) CR_TAB
3421 AS1 (asr,%0));
3423 case 3:
3424 *len = 3;
3425 return (AS1 (asr,%0) CR_TAB
3426 AS1 (asr,%0) CR_TAB
3427 AS1 (asr,%0));
3429 case 4:
3430 *len = 4;
3431 return (AS1 (asr,%0) CR_TAB
3432 AS1 (asr,%0) CR_TAB
3433 AS1 (asr,%0) CR_TAB
3434 AS1 (asr,%0));
3436 case 5:
3437 *len = 5;
3438 return (AS1 (asr,%0) CR_TAB
3439 AS1 (asr,%0) CR_TAB
3440 AS1 (asr,%0) CR_TAB
3441 AS1 (asr,%0) CR_TAB
3442 AS1 (asr,%0));
3444 case 6:
3445 *len = 4;
3446 return (AS2 (bst,%0,6) CR_TAB
3447 AS1 (lsl,%0) CR_TAB
3448 AS2 (sbc,%0,%0) CR_TAB
3449 AS2 (bld,%0,0));
3451 default:
3452 if (INTVAL (operands[2]) < 8)
3453 break;
3455 /* fall through */
3457 case 7:
3458 *len = 2;
3459 return (AS1 (lsl,%0) CR_TAB
3460 AS2 (sbc,%0,%0));
3463 else if (CONSTANT_P (operands[2]))
3464 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3466 out_shift_with_cnt (AS1 (asr,%0),
3467 insn, operands, len, 1);
3468 return "";
3472 /* 16bit arithmetic shift right ((signed short)x >> i) */
3474 const char *
3475 ashrhi3_out (rtx insn, rtx operands[], int *len)
3477 if (GET_CODE (operands[2]) == CONST_INT)
3479 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3480 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3481 int k;
3482 int *t = len;
3484 if (!len)
3485 len = &k;
3487 switch (INTVAL (operands[2]))
3489 case 4:
3490 case 5:
3491 /* XXX try to optimize this too? */
3492 break;
3494 case 6:
3495 if (optimize_size)
3496 break; /* scratch ? 5 : 6 */
3497 *len = 8;
3498 return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3499 AS2 (mov,%A0,%B0) CR_TAB
3500 AS1 (lsl,__tmp_reg__) CR_TAB
3501 AS1 (rol,%A0) CR_TAB
3502 AS2 (sbc,%B0,%B0) CR_TAB
3503 AS1 (lsl,__tmp_reg__) CR_TAB
3504 AS1 (rol,%A0) CR_TAB
3505 AS1 (rol,%B0));
3507 case 7:
3508 *len = 4;
3509 return (AS1 (lsl,%A0) CR_TAB
3510 AS2 (mov,%A0,%B0) CR_TAB
3511 AS1 (rol,%A0) CR_TAB
3512 AS2 (sbc,%B0,%B0));
3514 case 8:
3516 int reg0 = true_regnum (operands[0]);
3517 int reg1 = true_regnum (operands[1]);
3519 if (reg0 == reg1)
3520 return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3521 AS1 (lsl,%B0) CR_TAB
3522 AS2 (sbc,%B0,%B0));
3523 else if (reg0 == reg1 + 1)
3524 return *len = 3, (AS1 (clr,%B0) CR_TAB
3525 AS2 (sbrc,%A0,7) CR_TAB
3526 AS1 (dec,%B0));
3528 return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3529 AS1 (clr,%B0) CR_TAB
3530 AS2 (sbrc,%A0,7) CR_TAB
3531 AS1 (dec,%B0));
3534 case 9:
3535 *len = 4;
3536 return (AS2 (mov,%A0,%B0) CR_TAB
3537 AS1 (lsl,%B0) CR_TAB
3538 AS2 (sbc,%B0,%B0) CR_TAB
3539 AS1 (asr,%A0));
3541 case 10:
3542 *len = 5;
3543 return (AS2 (mov,%A0,%B0) CR_TAB
3544 AS1 (lsl,%B0) CR_TAB
3545 AS2 (sbc,%B0,%B0) CR_TAB
3546 AS1 (asr,%A0) CR_TAB
3547 AS1 (asr,%A0));
3549 case 11:
3550 if (AVR_ENHANCED && ldi_ok)
3552 *len = 5;
3553 return (AS2 (ldi,%A0,0x20) CR_TAB
3554 AS2 (muls,%B0,%A0) CR_TAB
3555 AS2 (mov,%A0,r1) CR_TAB
3556 AS2 (sbc,%B0,%B0) CR_TAB
3557 AS1 (clr,__zero_reg__));
3559 if (optimize_size && scratch)
3560 break; /* 5 */
3561 *len = 6;
3562 return (AS2 (mov,%A0,%B0) CR_TAB
3563 AS1 (lsl,%B0) CR_TAB
3564 AS2 (sbc,%B0,%B0) CR_TAB
3565 AS1 (asr,%A0) CR_TAB
3566 AS1 (asr,%A0) CR_TAB
3567 AS1 (asr,%A0));
3569 case 12:
3570 if (AVR_ENHANCED && ldi_ok)
3572 *len = 5;
3573 return (AS2 (ldi,%A0,0x10) CR_TAB
3574 AS2 (muls,%B0,%A0) CR_TAB
3575 AS2 (mov,%A0,r1) CR_TAB
3576 AS2 (sbc,%B0,%B0) CR_TAB
3577 AS1 (clr,__zero_reg__));
3579 if (optimize_size && scratch)
3580 break; /* 5 */
3581 *len = 7;
3582 return (AS2 (mov,%A0,%B0) CR_TAB
3583 AS1 (lsl,%B0) CR_TAB
3584 AS2 (sbc,%B0,%B0) CR_TAB
3585 AS1 (asr,%A0) CR_TAB
3586 AS1 (asr,%A0) CR_TAB
3587 AS1 (asr,%A0) CR_TAB
3588 AS1 (asr,%A0));
3590 case 13:
3591 if (AVR_ENHANCED && ldi_ok)
3593 *len = 5;
3594 return (AS2 (ldi,%A0,0x08) CR_TAB
3595 AS2 (muls,%B0,%A0) CR_TAB
3596 AS2 (mov,%A0,r1) CR_TAB
3597 AS2 (sbc,%B0,%B0) CR_TAB
3598 AS1 (clr,__zero_reg__));
3600 if (optimize_size)
3601 break; /* scratch ? 5 : 7 */
3602 *len = 8;
3603 return (AS2 (mov,%A0,%B0) CR_TAB
3604 AS1 (lsl,%B0) CR_TAB
3605 AS2 (sbc,%B0,%B0) CR_TAB
3606 AS1 (asr,%A0) CR_TAB
3607 AS1 (asr,%A0) CR_TAB
3608 AS1 (asr,%A0) CR_TAB
3609 AS1 (asr,%A0) CR_TAB
3610 AS1 (asr,%A0));
3612 case 14:
3613 *len = 5;
3614 return (AS1 (lsl,%B0) CR_TAB
3615 AS2 (sbc,%A0,%A0) CR_TAB
3616 AS1 (lsl,%B0) CR_TAB
3617 AS2 (mov,%B0,%A0) CR_TAB
3618 AS1 (rol,%A0));
3620 default:
3621 if (INTVAL (operands[2]) < 16)
3622 break;
3624 /* fall through */
3626 case 15:
3627 return *len = 3, (AS1 (lsl,%B0) CR_TAB
3628 AS2 (sbc,%A0,%A0) CR_TAB
3629 AS2 (mov,%B0,%A0));
3631 len = t;
3633 out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3634 AS1 (ror,%A0)),
3635 insn, operands, len, 2);
3636 return "";
3640 /* 32bit arithmetic shift right ((signed long)x >> i) */
3642 const char *
3643 ashrsi3_out (rtx insn, rtx operands[], int *len)
3645 if (GET_CODE (operands[2]) == CONST_INT)
3647 int k;
3648 int *t = len;
3650 if (!len)
3651 len = &k;
3653 switch (INTVAL (operands[2]))
3655 case 8:
3657 int reg0 = true_regnum (operands[0]);
3658 int reg1 = true_regnum (operands[1]);
3659 *len=6;
3660 if (reg0 <= reg1)
3661 return (AS2 (mov,%A0,%B1) CR_TAB
3662 AS2 (mov,%B0,%C1) CR_TAB
3663 AS2 (mov,%C0,%D1) CR_TAB
3664 AS1 (clr,%D0) CR_TAB
3665 AS2 (sbrc,%C0,7) CR_TAB
3666 AS1 (dec,%D0));
3667 else if (reg0 == reg1 + 1)
3669 *len = 3;
3670 return (AS1 (clr,%D0) CR_TAB
3671 AS2 (sbrc,%C0,7) CR_TAB
3672 AS1 (dec,%D0));
3674 else
3675 return (AS1 (clr,%D0) CR_TAB
3676 AS2 (sbrc,%D1,7) CR_TAB
3677 AS1 (dec,%D0) CR_TAB
3678 AS2 (mov,%C0,%D1) CR_TAB
3679 AS2 (mov,%B0,%C1) CR_TAB
3680 AS2 (mov,%A0,%B1));
3683 case 16:
3685 int reg0 = true_regnum (operands[0]);
3686 int reg1 = true_regnum (operands[1]);
3687 *len=6;
3688 if (AVR_ENHANCED && (reg0 != reg1 + 2))
3690 *len = 5;
3691 return (AS2 (movw,%A0,%C1) CR_TAB
3692 AS1 (clr,%D0) CR_TAB
3693 AS2 (sbrc,%B0,7) CR_TAB
3694 AS1 (com,%D0) CR_TAB
3695 AS2 (mov,%C0,%D0));
3697 if (reg0 <= reg1 + 1)
3698 return (AS2 (mov,%A0,%C1) CR_TAB
3699 AS2 (mov,%B0,%D1) CR_TAB
3700 AS1 (clr,%D0) CR_TAB
3701 AS2 (sbrc,%B0,7) CR_TAB
3702 AS1 (com,%D0) CR_TAB
3703 AS2 (mov,%C0,%D0));
3704 else if (reg0 == reg1 + 2)
3705 return *len = 4, (AS1 (clr,%D0) CR_TAB
3706 AS2 (sbrc,%B0,7) CR_TAB
3707 AS1 (com,%D0) CR_TAB
3708 AS2 (mov,%C0,%D0));
3709 else
3710 return (AS2 (mov,%B0,%D1) CR_TAB
3711 AS2 (mov,%A0,%C1) CR_TAB
3712 AS1 (clr,%D0) CR_TAB
3713 AS2 (sbrc,%B0,7) CR_TAB
3714 AS1 (com,%D0) CR_TAB
3715 AS2 (mov,%C0,%D0));
3718 case 24:
3719 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3720 return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3721 AS1 (clr,%D0) CR_TAB
3722 AS2 (sbrc,%A0,7) CR_TAB
3723 AS1 (com,%D0) CR_TAB
3724 AS2 (mov,%B0,%D0) CR_TAB
3725 AS2 (mov,%C0,%D0));
3726 else
3727 return *len = 5, (AS1 (clr,%D0) CR_TAB
3728 AS2 (sbrc,%A0,7) CR_TAB
3729 AS1 (com,%D0) CR_TAB
3730 AS2 (mov,%B0,%D0) CR_TAB
3731 AS2 (mov,%C0,%D0));
3733 default:
3734 if (INTVAL (operands[2]) < 32)
3735 break;
3737 /* fall through */
3739 case 31:
3740 if (AVR_ENHANCED)
3741 return *len = 4, (AS1 (lsl,%D0) CR_TAB
3742 AS2 (sbc,%A0,%A0) CR_TAB
3743 AS2 (mov,%B0,%A0) CR_TAB
3744 AS2 (movw,%C0,%A0));
3745 else
3746 return *len = 5, (AS1 (lsl,%D0) CR_TAB
3747 AS2 (sbc,%A0,%A0) CR_TAB
3748 AS2 (mov,%B0,%A0) CR_TAB
3749 AS2 (mov,%C0,%A0) CR_TAB
3750 AS2 (mov,%D0,%A0));
3752 len = t;
3754 out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
3755 AS1 (ror,%C0) CR_TAB
3756 AS1 (ror,%B0) CR_TAB
3757 AS1 (ror,%A0)),
3758 insn, operands, len, 4);
3759 return "";
3762 /* 8bit logic shift right ((unsigned char)x >> i) */
3764 const char *
3765 lshrqi3_out (rtx insn, rtx operands[], int *len)
3767 if (GET_CODE (operands[2]) == CONST_INT)
3769 int k;
3771 if (!len)
3772 len = &k;
3774 switch (INTVAL (operands[2]))
3776 default:
3777 if (INTVAL (operands[2]) < 8)
3778 break;
3780 *len = 1;
3781 return AS1 (clr,%0);
3783 case 1:
3784 *len = 1;
3785 return AS1 (lsr,%0);
3787 case 2:
3788 *len = 2;
3789 return (AS1 (lsr,%0) CR_TAB
3790 AS1 (lsr,%0));
3791 case 3:
3792 *len = 3;
3793 return (AS1 (lsr,%0) CR_TAB
3794 AS1 (lsr,%0) CR_TAB
3795 AS1 (lsr,%0));
3797 case 4:
3798 if (test_hard_reg_class (LD_REGS, operands[0]))
3800 *len=2;
3801 return (AS1 (swap,%0) CR_TAB
3802 AS2 (andi,%0,0x0f));
3804 *len = 4;
3805 return (AS1 (lsr,%0) CR_TAB
3806 AS1 (lsr,%0) CR_TAB
3807 AS1 (lsr,%0) CR_TAB
3808 AS1 (lsr,%0));
3810 case 5:
3811 if (test_hard_reg_class (LD_REGS, operands[0]))
3813 *len = 3;
3814 return (AS1 (swap,%0) CR_TAB
3815 AS1 (lsr,%0) CR_TAB
3816 AS2 (andi,%0,0x7));
3818 *len = 5;
3819 return (AS1 (lsr,%0) CR_TAB
3820 AS1 (lsr,%0) CR_TAB
3821 AS1 (lsr,%0) CR_TAB
3822 AS1 (lsr,%0) CR_TAB
3823 AS1 (lsr,%0));
3825 case 6:
3826 if (test_hard_reg_class (LD_REGS, operands[0]))
3828 *len = 4;
3829 return (AS1 (swap,%0) CR_TAB
3830 AS1 (lsr,%0) CR_TAB
3831 AS1 (lsr,%0) CR_TAB
3832 AS2 (andi,%0,0x3));
3834 *len = 6;
3835 return (AS1 (lsr,%0) CR_TAB
3836 AS1 (lsr,%0) CR_TAB
3837 AS1 (lsr,%0) CR_TAB
3838 AS1 (lsr,%0) CR_TAB
3839 AS1 (lsr,%0) CR_TAB
3840 AS1 (lsr,%0));
3842 case 7:
3843 *len = 3;
3844 return (AS1 (rol,%0) CR_TAB
3845 AS1 (clr,%0) CR_TAB
3846 AS1 (rol,%0));
3849 else if (CONSTANT_P (operands[2]))
3850 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3852 out_shift_with_cnt (AS1 (lsr,%0),
3853 insn, operands, len, 1);
3854 return "";
3857 /* 16bit logic shift right ((unsigned short)x >> i) */
3859 const char *
3860 lshrhi3_out (rtx insn, rtx operands[], int *len)
3862 if (GET_CODE (operands[2]) == CONST_INT)
3864 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3865 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3866 int k;
3867 int *t = len;
3869 if (!len)
3870 len = &k;
3872 switch (INTVAL (operands[2]))
3874 default:
3875 if (INTVAL (operands[2]) < 16)
3876 break;
3878 *len = 2;
3879 return (AS1 (clr,%B0) CR_TAB
3880 AS1 (clr,%A0));
3882 case 4:
3883 if (optimize_size && scratch)
3884 break; /* 5 */
3885 if (ldi_ok)
3887 *len = 6;
3888 return (AS1 (swap,%B0) CR_TAB
3889 AS1 (swap,%A0) CR_TAB
3890 AS2 (andi,%A0,0x0f) CR_TAB
3891 AS2 (eor,%A0,%B0) CR_TAB
3892 AS2 (andi,%B0,0x0f) CR_TAB
3893 AS2 (eor,%A0,%B0));
3895 if (scratch)
3897 *len = 7;
3898 return (AS1 (swap,%B0) CR_TAB
3899 AS1 (swap,%A0) CR_TAB
3900 AS2 (ldi,%3,0x0f) CR_TAB
3901 AS2 (and,%A0,%3) CR_TAB
3902 AS2 (eor,%A0,%B0) CR_TAB
3903 AS2 (and,%B0,%3) CR_TAB
3904 AS2 (eor,%A0,%B0));
3906 break; /* optimize_size ? 6 : 8 */
3908 case 5:
3909 if (optimize_size)
3910 break; /* scratch ? 5 : 6 */
3911 if (ldi_ok)
3913 *len = 8;
3914 return (AS1 (lsr,%B0) CR_TAB
3915 AS1 (ror,%A0) CR_TAB
3916 AS1 (swap,%B0) CR_TAB
3917 AS1 (swap,%A0) CR_TAB
3918 AS2 (andi,%A0,0x0f) CR_TAB
3919 AS2 (eor,%A0,%B0) CR_TAB
3920 AS2 (andi,%B0,0x0f) CR_TAB
3921 AS2 (eor,%A0,%B0));
3923 if (scratch)
3925 *len = 9;
3926 return (AS1 (lsr,%B0) CR_TAB
3927 AS1 (ror,%A0) CR_TAB
3928 AS1 (swap,%B0) CR_TAB
3929 AS1 (swap,%A0) CR_TAB
3930 AS2 (ldi,%3,0x0f) CR_TAB
3931 AS2 (and,%A0,%3) CR_TAB
3932 AS2 (eor,%A0,%B0) CR_TAB
3933 AS2 (and,%B0,%3) CR_TAB
3934 AS2 (eor,%A0,%B0));
3936 break; /* 10 */
3938 case 6:
3939 if (optimize_size)
3940 break; /* scratch ? 5 : 6 */
3941 *len = 9;
3942 return (AS1 (clr,__tmp_reg__) CR_TAB
3943 AS1 (lsl,%A0) CR_TAB
3944 AS1 (rol,%B0) CR_TAB
3945 AS1 (rol,__tmp_reg__) CR_TAB
3946 AS1 (lsl,%A0) CR_TAB
3947 AS1 (rol,%B0) CR_TAB
3948 AS1 (rol,__tmp_reg__) CR_TAB
3949 AS2 (mov,%A0,%B0) CR_TAB
3950 AS2 (mov,%B0,__tmp_reg__));
3952 case 7:
3953 *len = 5;
3954 return (AS1 (lsl,%A0) CR_TAB
3955 AS2 (mov,%A0,%B0) CR_TAB
3956 AS1 (rol,%A0) CR_TAB
3957 AS2 (sbc,%B0,%B0) CR_TAB
3958 AS1 (neg,%B0));
3960 case 8:
3961 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
3962 return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
3963 AS1 (clr,%B0));
3964 else
3965 return *len = 1, AS1 (clr,%B0);
3967 case 9:
3968 *len = 3;
3969 return (AS2 (mov,%A0,%B0) CR_TAB
3970 AS1 (clr,%B0) CR_TAB
3971 AS1 (lsr,%A0));
3973 case 10:
3974 *len = 4;
3975 return (AS2 (mov,%A0,%B0) CR_TAB
3976 AS1 (clr,%B0) CR_TAB
3977 AS1 (lsr,%A0) CR_TAB
3978 AS1 (lsr,%A0));
3980 case 11:
3981 *len = 5;
3982 return (AS2 (mov,%A0,%B0) CR_TAB
3983 AS1 (clr,%B0) CR_TAB
3984 AS1 (lsr,%A0) CR_TAB
3985 AS1 (lsr,%A0) CR_TAB
3986 AS1 (lsr,%A0));
3988 case 12:
3989 if (ldi_ok)
3991 *len = 4;
3992 return (AS2 (mov,%A0,%B0) CR_TAB
3993 AS1 (clr,%B0) CR_TAB
3994 AS1 (swap,%A0) CR_TAB
3995 AS2 (andi,%A0,0x0f));
3997 if (scratch)
3999 *len = 5;
4000 return (AS2 (mov,%A0,%B0) CR_TAB
4001 AS1 (clr,%B0) CR_TAB
4002 AS1 (swap,%A0) CR_TAB
4003 AS2 (ldi,%3,0x0f) CR_TAB
4004 AS2 (and,%A0,%3));
4006 *len = 6;
4007 return (AS2 (mov,%A0,%B0) CR_TAB
4008 AS1 (clr,%B0) CR_TAB
4009 AS1 (lsr,%A0) CR_TAB
4010 AS1 (lsr,%A0) CR_TAB
4011 AS1 (lsr,%A0) CR_TAB
4012 AS1 (lsr,%A0));
4014 case 13:
4015 if (ldi_ok)
4017 *len = 5;
4018 return (AS2 (mov,%A0,%B0) CR_TAB
4019 AS1 (clr,%B0) CR_TAB
4020 AS1 (swap,%A0) CR_TAB
4021 AS1 (lsr,%A0) CR_TAB
4022 AS2 (andi,%A0,0x07));
4024 if (AVR_ENHANCED && scratch)
4026 *len = 5;
4027 return (AS2 (ldi,%3,0x08) CR_TAB
4028 AS2 (mul,%B0,%3) CR_TAB
4029 AS2 (mov,%A0,r1) CR_TAB
4030 AS1 (clr,%B0) CR_TAB
4031 AS1 (clr,__zero_reg__));
4033 if (optimize_size && scratch)
4034 break; /* 5 */
4035 if (scratch)
4037 *len = 6;
4038 return (AS2 (mov,%A0,%B0) CR_TAB
4039 AS1 (clr,%B0) CR_TAB
4040 AS1 (swap,%A0) CR_TAB
4041 AS1 (lsr,%A0) CR_TAB
4042 AS2 (ldi,%3,0x07) CR_TAB
4043 AS2 (and,%A0,%3));
4045 if (AVR_ENHANCED)
4047 *len = 6;
4048 return ("set" CR_TAB
4049 AS2 (bld,r1,3) CR_TAB
4050 AS2 (mul,%B0,r1) CR_TAB
4051 AS2 (mov,%A0,r1) CR_TAB
4052 AS1 (clr,%B0) CR_TAB
4053 AS1 (clr,__zero_reg__));
4055 *len = 7;
4056 return (AS2 (mov,%A0,%B0) CR_TAB
4057 AS1 (clr,%B0) CR_TAB
4058 AS1 (lsr,%A0) CR_TAB
4059 AS1 (lsr,%A0) CR_TAB
4060 AS1 (lsr,%A0) CR_TAB
4061 AS1 (lsr,%A0) CR_TAB
4062 AS1 (lsr,%A0));
4064 case 14:
4065 if (AVR_ENHANCED && ldi_ok)
4067 *len = 5;
4068 return (AS2 (ldi,%A0,0x04) CR_TAB
4069 AS2 (mul,%B0,%A0) CR_TAB
4070 AS2 (mov,%A0,r1) CR_TAB
4071 AS1 (clr,%B0) CR_TAB
4072 AS1 (clr,__zero_reg__));
4074 if (AVR_ENHANCED && scratch)
4076 *len = 5;
4077 return (AS2 (ldi,%3,0x04) CR_TAB
4078 AS2 (mul,%B0,%3) CR_TAB
4079 AS2 (mov,%A0,r1) CR_TAB
4080 AS1 (clr,%B0) CR_TAB
4081 AS1 (clr,__zero_reg__));
4083 if (optimize_size && ldi_ok)
4085 *len = 5;
4086 return (AS2 (mov,%A0,%B0) CR_TAB
4087 AS2 (ldi,%B0,6) "\n1:\t"
4088 AS1 (lsr,%A0) CR_TAB
4089 AS1 (dec,%B0) CR_TAB
4090 AS1 (brne,1b));
4092 if (optimize_size && scratch)
4093 break; /* 5 */
4094 *len = 6;
4095 return (AS1 (clr,%A0) CR_TAB
4096 AS1 (lsl,%B0) CR_TAB
4097 AS1 (rol,%A0) CR_TAB
4098 AS1 (lsl,%B0) CR_TAB
4099 AS1 (rol,%A0) CR_TAB
4100 AS1 (clr,%B0));
4102 case 15:
4103 *len = 4;
4104 return (AS1 (clr,%A0) CR_TAB
4105 AS1 (lsl,%B0) CR_TAB
4106 AS1 (rol,%A0) CR_TAB
4107 AS1 (clr,%B0));
4109 len = t;
4111 out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
4112 AS1 (ror,%A0)),
4113 insn, operands, len, 2);
4114 return "";
4117 /* 32bit logic shift right ((unsigned int)x >> i) */
4119 const char *
4120 lshrsi3_out (rtx insn, rtx operands[], int *len)
4122 if (GET_CODE (operands[2]) == CONST_INT)
4124 int k;
4125 int *t = len;
4127 if (!len)
4128 len = &k;
4130 switch (INTVAL (operands[2]))
4132 default:
4133 if (INTVAL (operands[2]) < 32)
4134 break;
4136 if (AVR_ENHANCED)
4137 return *len = 3, (AS1 (clr,%D0) CR_TAB
4138 AS1 (clr,%C0) CR_TAB
4139 AS2 (movw,%A0,%C0));
4140 *len = 4;
4141 return (AS1 (clr,%D0) CR_TAB
4142 AS1 (clr,%C0) CR_TAB
4143 AS1 (clr,%B0) CR_TAB
4144 AS1 (clr,%A0));
4146 case 8:
4148 int reg0 = true_regnum (operands[0]);
4149 int reg1 = true_regnum (operands[1]);
4150 *len = 4;
4151 if (reg0 <= reg1)
4152 return (AS2 (mov,%A0,%B1) CR_TAB
4153 AS2 (mov,%B0,%C1) CR_TAB
4154 AS2 (mov,%C0,%D1) CR_TAB
4155 AS1 (clr,%D0));
4156 else if (reg0 == reg1 + 1)
4157 return *len = 1, AS1 (clr,%D0);
4158 else
4159 return (AS1 (clr,%D0) CR_TAB
4160 AS2 (mov,%C0,%D1) CR_TAB
4161 AS2 (mov,%B0,%C1) CR_TAB
4162 AS2 (mov,%A0,%B1));
4165 case 16:
4167 int reg0 = true_regnum (operands[0]);
4168 int reg1 = true_regnum (operands[1]);
4169 *len = 4;
4170 if (AVR_ENHANCED && (reg0 != reg1 + 2))
4172 *len = 3;
4173 return (AS2 (movw,%A0,%C1) CR_TAB
4174 AS1 (clr,%C0) CR_TAB
4175 AS1 (clr,%D0));
4177 if (reg0 <= reg1 + 1)
4178 return (AS2 (mov,%A0,%C1) CR_TAB
4179 AS2 (mov,%B0,%D1) CR_TAB
4180 AS1 (clr,%C0) CR_TAB
4181 AS1 (clr,%D0));
4182 else if (reg0 == reg1 + 2)
4183 return *len = 2, (AS1 (clr,%C0) CR_TAB
4184 AS1 (clr,%D0));
4185 else
4186 return (AS2 (mov,%B0,%D1) CR_TAB
4187 AS2 (mov,%A0,%C1) CR_TAB
4188 AS1 (clr,%C0) CR_TAB
4189 AS1 (clr,%D0));
4192 case 24:
4193 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
4194 return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4195 AS1 (clr,%B0) CR_TAB
4196 AS1 (clr,%C0) CR_TAB
4197 AS1 (clr,%D0));
4198 else
4199 return *len = 3, (AS1 (clr,%B0) CR_TAB
4200 AS1 (clr,%C0) CR_TAB
4201 AS1 (clr,%D0));
4203 case 31:
4204 *len = 6;
4205 return (AS1 (clr,%A0) CR_TAB
4206 AS2 (sbrc,%D0,7) CR_TAB
4207 AS1 (inc,%A0) CR_TAB
4208 AS1 (clr,%B0) CR_TAB
4209 AS1 (clr,%C0) CR_TAB
4210 AS1 (clr,%D0));
4212 len = t;
4214 out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4215 AS1 (ror,%C0) CR_TAB
4216 AS1 (ror,%B0) CR_TAB
4217 AS1 (ror,%A0)),
4218 insn, operands, len, 4);
4219 return "";
4222 /* Modifies the length assigned to instruction INSN
4223 LEN is the initially computed length of the insn. */
4226 adjust_insn_length (rtx insn, int len)
4228 rtx patt = PATTERN (insn);
4229 rtx set;
4231 if (GET_CODE (patt) == SET)
4233 rtx op[10];
4234 op[1] = SET_SRC (patt);
4235 op[0] = SET_DEST (patt);
4236 if (general_operand (op[1], VOIDmode)
4237 && general_operand (op[0], VOIDmode))
4239 switch (GET_MODE (op[0]))
4241 case QImode:
4242 output_movqi (insn, op, &len);
4243 break;
4244 case HImode:
4245 output_movhi (insn, op, &len);
4246 break;
4247 case SImode:
4248 case SFmode:
4249 output_movsisf (insn, op, &len);
4250 break;
4251 default:
4252 break;
4255 else if (op[0] == cc0_rtx && REG_P (op[1]))
4257 switch (GET_MODE (op[1]))
4259 case HImode: out_tsthi (insn,&len); break;
4260 case SImode: out_tstsi (insn,&len); break;
4261 default: break;
4264 else if (GET_CODE (op[1]) == AND)
4266 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4268 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4269 if (GET_MODE (op[1]) == SImode)
4270 len = (((mask & 0xff) != 0xff)
4271 + ((mask & 0xff00) != 0xff00)
4272 + ((mask & 0xff0000L) != 0xff0000L)
4273 + ((mask & 0xff000000L) != 0xff000000L));
4274 else if (GET_MODE (op[1]) == HImode)
4275 len = (((mask & 0xff) != 0xff)
4276 + ((mask & 0xff00) != 0xff00));
4279 else if (GET_CODE (op[1]) == IOR)
4281 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4283 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4284 if (GET_MODE (op[1]) == SImode)
4285 len = (((mask & 0xff) != 0)
4286 + ((mask & 0xff00) != 0)
4287 + ((mask & 0xff0000L) != 0)
4288 + ((mask & 0xff000000L) != 0));
4289 else if (GET_MODE (op[1]) == HImode)
4290 len = (((mask & 0xff) != 0)
4291 + ((mask & 0xff00) != 0));
4295 set = single_set (insn);
4296 if (set)
4298 rtx op[10];
4300 op[1] = SET_SRC (set);
4301 op[0] = SET_DEST (set);
4303 if (GET_CODE (patt) == PARALLEL
4304 && general_operand (op[1], VOIDmode)
4305 && general_operand (op[0], VOIDmode))
4307 if (XVECLEN (patt, 0) == 2)
4308 op[2] = XVECEXP (patt, 0, 1);
4310 switch (GET_MODE (op[0]))
4312 case QImode:
4313 len = 2;
4314 break;
4315 case HImode:
4316 output_reload_inhi (insn, op, &len);
4317 break;
4318 case SImode:
4319 case SFmode:
4320 output_reload_insisf (insn, op, &len);
4321 break;
4322 default:
4323 break;
4326 else if (GET_CODE (op[1]) == ASHIFT
4327 || GET_CODE (op[1]) == ASHIFTRT
4328 || GET_CODE (op[1]) == LSHIFTRT)
4330 rtx ops[10];
4331 ops[0] = op[0];
4332 ops[1] = XEXP (op[1],0);
4333 ops[2] = XEXP (op[1],1);
4334 switch (GET_CODE (op[1]))
4336 case ASHIFT:
4337 switch (GET_MODE (op[0]))
4339 case QImode: ashlqi3_out (insn,ops,&len); break;
4340 case HImode: ashlhi3_out (insn,ops,&len); break;
4341 case SImode: ashlsi3_out (insn,ops,&len); break;
4342 default: break;
4344 break;
4345 case ASHIFTRT:
4346 switch (GET_MODE (op[0]))
4348 case QImode: ashrqi3_out (insn,ops,&len); break;
4349 case HImode: ashrhi3_out (insn,ops,&len); break;
4350 case SImode: ashrsi3_out (insn,ops,&len); break;
4351 default: break;
4353 break;
4354 case LSHIFTRT:
4355 switch (GET_MODE (op[0]))
4357 case QImode: lshrqi3_out (insn,ops,&len); break;
4358 case HImode: lshrhi3_out (insn,ops,&len); break;
4359 case SImode: lshrsi3_out (insn,ops,&len); break;
4360 default: break;
4362 break;
4363 default:
4364 break;
4368 return len;
4371 /* Return nonzero if register REG dead after INSN. */
4374 reg_unused_after (rtx insn, rtx reg)
4376 return (dead_or_set_p (insn, reg)
4377 || (REG_P(reg) && _reg_unused_after (insn, reg)));
4380 /* Return nonzero if REG is not used after INSN.
4381 We assume REG is a reload reg, and therefore does
4382 not live past labels. It may live past calls or jumps though. */
4385 _reg_unused_after (rtx insn, rtx reg)
4387 enum rtx_code code;
4388 rtx set;
4390 /* If the reg is set by this instruction, then it is safe for our
4391 case. Disregard the case where this is a store to memory, since
4392 we are checking a register used in the store address. */
4393 set = single_set (insn);
4394 if (set && GET_CODE (SET_DEST (set)) != MEM
4395 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4396 return 1;
4398 while ((insn = NEXT_INSN (insn)))
4400 rtx set;
4401 code = GET_CODE (insn);
4403 #if 0
4404 /* If this is a label that existed before reload, then the register
4405 if dead here. However, if this is a label added by reorg, then
4406 the register may still be live here. We can't tell the difference,
4407 so we just ignore labels completely. */
4408 if (code == CODE_LABEL)
4409 return 1;
4410 /* else */
4411 #endif
4413 if (!INSN_P (insn))
4414 continue;
4416 if (code == JUMP_INSN)
4417 return 0;
4419 /* If this is a sequence, we must handle them all at once.
4420 We could have for instance a call that sets the target register,
4421 and an insn in a delay slot that uses the register. In this case,
4422 we must return 0. */
4423 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
4425 int i;
4426 int retval = 0;
4428 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
4430 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
4431 rtx set = single_set (this_insn);
4433 if (GET_CODE (this_insn) == CALL_INSN)
4434 code = CALL_INSN;
4435 else if (GET_CODE (this_insn) == JUMP_INSN)
4437 if (INSN_ANNULLED_BRANCH_P (this_insn))
4438 return 0;
4439 code = JUMP_INSN;
4442 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4443 return 0;
4444 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4446 if (GET_CODE (SET_DEST (set)) != MEM)
4447 retval = 1;
4448 else
4449 return 0;
4451 if (set == 0
4452 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
4453 return 0;
4455 if (retval == 1)
4456 return 1;
4457 else if (code == JUMP_INSN)
4458 return 0;
4461 if (code == CALL_INSN)
4463 rtx tem;
4464 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4465 if (GET_CODE (XEXP (tem, 0)) == USE
4466 && REG_P (XEXP (XEXP (tem, 0), 0))
4467 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
4468 return 0;
4469 if (call_used_regs[REGNO (reg)])
4470 return 1;
4473 set = single_set (insn);
4475 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4476 return 0;
4477 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4478 return GET_CODE (SET_DEST (set)) != MEM;
4479 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
4480 return 0;
4482 return 1;
4485 /* Target hook for assembling integer objects. The AVR version needs
4486 special handling for references to certain labels. */
4488 static bool
4489 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
4491 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
4492 && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x))
4493 || GET_CODE (x) == LABEL_REF))
4495 fputs ("\t.word\tpm(", asm_out_file);
4496 output_addr_const (asm_out_file, x);
4497 fputs (")\n", asm_out_file);
4498 return true;
4500 return default_assemble_integer (x, size, aligned_p);
4503 /* The routine used to output NUL terminated strings. We use a special
4504 version of this for most svr4 targets because doing so makes the
4505 generated assembly code more compact (and thus faster to assemble)
4506 as well as more readable, especially for targets like the i386
4507 (where the only alternative is to output character sequences as
4508 comma separated lists of numbers). */
4510 void
4511 gas_output_limited_string(FILE *file, const char *str)
4513 const unsigned char *_limited_str = (unsigned char *) str;
4514 unsigned ch;
4515 fprintf (file, "%s\"", STRING_ASM_OP);
4516 for (; (ch = *_limited_str); _limited_str++)
4518 int escape;
4519 switch (escape = ESCAPES[ch])
4521 case 0:
4522 putc (ch, file);
4523 break;
4524 case 1:
4525 fprintf (file, "\\%03o", ch);
4526 break;
4527 default:
4528 putc ('\\', file);
4529 putc (escape, file);
4530 break;
4533 fprintf (file, "\"\n");
4536 /* The routine used to output sequences of byte values. We use a special
4537 version of this for most svr4 targets because doing so makes the
4538 generated assembly code more compact (and thus faster to assemble)
4539 as well as more readable. Note that if we find subparts of the
4540 character sequence which end with NUL (and which are shorter than
4541 STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
4543 void
4544 gas_output_ascii(FILE *file, const char *str, size_t length)
4546 const unsigned char *_ascii_bytes = (const unsigned char *) str;
4547 const unsigned char *limit = _ascii_bytes + length;
4548 unsigned bytes_in_chunk = 0;
4549 for (; _ascii_bytes < limit; _ascii_bytes++)
4551 const unsigned char *p;
4552 if (bytes_in_chunk >= 60)
4554 fprintf (file, "\"\n");
4555 bytes_in_chunk = 0;
4557 for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
4558 continue;
4559 if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
4561 if (bytes_in_chunk > 0)
4563 fprintf (file, "\"\n");
4564 bytes_in_chunk = 0;
4566 gas_output_limited_string (file, (char*)_ascii_bytes);
4567 _ascii_bytes = p;
4569 else
4571 int escape;
4572 unsigned ch;
4573 if (bytes_in_chunk == 0)
4574 fprintf (file, "\t.ascii\t\"");
4575 switch (escape = ESCAPES[ch = *_ascii_bytes])
4577 case 0:
4578 putc (ch, file);
4579 bytes_in_chunk++;
4580 break;
4581 case 1:
4582 fprintf (file, "\\%03o", ch);
4583 bytes_in_chunk += 4;
4584 break;
4585 default:
4586 putc ('\\', file);
4587 putc (escape, file);
4588 bytes_in_chunk += 2;
4589 break;
4593 if (bytes_in_chunk > 0)
4594 fprintf (file, "\"\n");
4597 /* Return value is nonzero if pseudos that have been
4598 assigned to registers of class CLASS would likely be spilled
4599 because registers of CLASS are needed for spill registers. */
4601 enum reg_class
4602 class_likely_spilled_p (int c)
4604 return (c != ALL_REGS && c != ADDW_REGS);
4607 /* Valid attributes:
4608 progmem - put data to program memory;
4609 signal - make a function to be hardware interrupt. After function
4610 prologue interrupts are disabled;
4611 interrupt - make a function to be hardware interrupt. After function
4612 prologue interrupts are enabled;
4613 naked - don't generate function prologue/epilogue and `ret' command.
4615 Only `progmem' attribute valid for type. */
4617 const struct attribute_spec avr_attribute_table[] =
4619 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
4620 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute },
4621 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4622 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4623 { "naked", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4624 { NULL, 0, 0, false, false, false, NULL }
4627 /* Handle a "progmem" attribute; arguments as in
4628 struct attribute_spec.handler. */
4629 static tree
4630 avr_handle_progmem_attribute (tree *node, tree name,
4631 tree args ATTRIBUTE_UNUSED,
4632 int flags ATTRIBUTE_UNUSED,
4633 bool *no_add_attrs)
4635 if (DECL_P (*node))
4637 if (TREE_CODE (*node) == TYPE_DECL)
4639 /* This is really a decl attribute, not a type attribute,
4640 but try to handle it for GCC 3.0 backwards compatibility. */
4642 tree type = TREE_TYPE (*node);
4643 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
4644 tree newtype = build_type_attribute_variant (type, attr);
4646 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
4647 TREE_TYPE (*node) = newtype;
4648 *no_add_attrs = true;
4650 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
4652 if (DECL_INITIAL (*node) == NULL_TREE && !DECL_EXTERNAL (*node))
4654 warning (0, "only initialized variables can be placed into "
4655 "program memory area");
4656 *no_add_attrs = true;
4659 else
4661 warning (OPT_Wattributes, "%qs attribute ignored",
4662 IDENTIFIER_POINTER (name));
4663 *no_add_attrs = true;
4667 return NULL_TREE;
4670 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
4671 struct attribute_spec.handler. */
4673 static tree
4674 avr_handle_fndecl_attribute (tree *node, tree name,
4675 tree args ATTRIBUTE_UNUSED,
4676 int flags ATTRIBUTE_UNUSED,
4677 bool *no_add_attrs)
4679 if (TREE_CODE (*node) != FUNCTION_DECL)
4681 warning (OPT_Wattributes, "%qs attribute only applies to functions",
4682 IDENTIFIER_POINTER (name));
4683 *no_add_attrs = true;
4685 else
4687 const char *func_name = IDENTIFIER_POINTER (DECL_NAME (*node));
4688 const char *attr = IDENTIFIER_POINTER (name);
4690 /* If the function has the 'signal' or 'interrupt' attribute, test to
4691 make sure that the name of the function is "__vector_NN" so as to
4692 catch when the user misspells the interrupt vector name. */
4694 if (strncmp (attr, "interrupt", strlen ("interrupt")) == 0)
4696 if (strncmp (func_name, "__vector", strlen ("__vector")) != 0)
4698 warning (0, "%qs appears to be a misspelled interrupt handler",
4699 func_name);
4702 else if (strncmp (attr, "signal", strlen ("signal")) == 0)
4704 if (strncmp (func_name, "__vector", strlen ("__vector")) != 0)
4706 warning (0, "%qs appears to be a misspelled signal handler",
4707 func_name);
4712 return NULL_TREE;
4715 /* Look for attribute `progmem' in DECL
4716 if found return 1, otherwise 0. */
4719 avr_progmem_p (tree decl, tree attributes)
4721 tree a;
4723 if (TREE_CODE (decl) != VAR_DECL)
4724 return 0;
4726 if (NULL_TREE
4727 != lookup_attribute ("progmem", attributes))
4728 return 1;
4730 a=decl;
4732 a = TREE_TYPE(a);
4733 while (TREE_CODE (a) == ARRAY_TYPE);
4735 if (a == error_mark_node)
4736 return 0;
4738 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
4739 return 1;
4741 return 0;
4744 /* Add the section attribute if the variable is in progmem. */
4746 static void
4747 avr_insert_attributes (tree node, tree *attributes)
4749 if (TREE_CODE (node) == VAR_DECL
4750 && (TREE_STATIC (node) || DECL_EXTERNAL (node))
4751 && avr_progmem_p (node, *attributes))
4753 static const char dsec[] = ".progmem.data";
4754 *attributes = tree_cons (get_identifier ("section"),
4755 build_tree_list (NULL, build_string (strlen (dsec), dsec)),
4756 *attributes);
4758 /* ??? This seems sketchy. Why can't the user declare the
4759 thing const in the first place? */
4760 TREE_READONLY (node) = 1;
4764 /* A get_unnamed_section callback for switching to progmem_section. */
4766 static void
4767 avr_output_progmem_section_asm_op (const void *arg ATTRIBUTE_UNUSED)
4769 fprintf (asm_out_file,
4770 "\t.section .progmem.gcc_sw_table, \"%s\", @progbits\n",
4771 AVR_MEGA ? "a" : "ax");
4772 /* Should already be aligned, this is just to be safe if it isn't. */
4773 fprintf (asm_out_file, "\t.p2align 1\n");
4776 /* Implement TARGET_ASM_INIT_SECTIONS. */
4778 static void
4779 avr_asm_init_sections (void)
4781 progmem_section = get_unnamed_section (AVR_MEGA ? 0 : SECTION_CODE,
4782 avr_output_progmem_section_asm_op,
4783 NULL);
4784 readonly_data_section = data_section;
4787 static unsigned int
4788 avr_section_type_flags (tree decl, const char *name, int reloc)
4790 unsigned int flags = default_section_type_flags (decl, name, reloc);
4792 if (strncmp (name, ".noinit", 7) == 0)
4794 if (decl && TREE_CODE (decl) == VAR_DECL
4795 && DECL_INITIAL (decl) == NULL_TREE)
4796 flags |= SECTION_BSS; /* @nobits */
4797 else
4798 warning (0, "only uninitialized variables can be placed in the "
4799 ".noinit section");
4802 return flags;
4805 /* Outputs some appropriate text to go at the start of an assembler
4806 file. */
4808 static void
4809 avr_file_start (void)
4811 if (avr_asm_only_p)
4812 error ("MCU %qs supported for assembler only", avr_mcu_name);
4814 default_file_start ();
4816 fprintf (asm_out_file, "\t.arch %s\n", avr_mcu_name);
4817 fputs ("__SREG__ = 0x3f\n"
4818 "__SP_H__ = 0x3e\n"
4819 "__SP_L__ = 0x3d\n", asm_out_file);
4821 fputs ("__tmp_reg__ = 0\n"
4822 "__zero_reg__ = 1\n", asm_out_file);
4824 /* FIXME: output these only if there is anything in the .data / .bss
4825 sections - some code size could be saved by not linking in the
4826 initialization code from libgcc if one or both sections are empty. */
4827 fputs ("\t.global __do_copy_data\n", asm_out_file);
4828 fputs ("\t.global __do_clear_bss\n", asm_out_file);
4830 commands_in_file = 0;
4831 commands_in_prologues = 0;
4832 commands_in_epilogues = 0;
4835 /* Outputs to the stdio stream FILE some
4836 appropriate text to go at the end of an assembler file. */
4838 static void
4839 avr_file_end (void)
4841 fputs ("/* File ", asm_out_file);
4842 output_quoted_string (asm_out_file, main_input_filename);
4843 fprintf (asm_out_file,
4844 ": code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
4845 commands_in_file,
4846 commands_in_file,
4847 commands_in_file - commands_in_prologues - commands_in_epilogues,
4848 commands_in_prologues, commands_in_epilogues);
4851 /* Choose the order in which to allocate hard registers for
4852 pseudo-registers local to a basic block.
4854 Store the desired register order in the array `reg_alloc_order'.
4855 Element 0 should be the register to allocate first; element 1, the
4856 next register; and so on. */
4858 void
4859 order_regs_for_local_alloc (void)
4861 unsigned int i;
4862 static const int order_0[] = {
4863 24,25,
4864 18,19,
4865 20,21,
4866 22,23,
4867 30,31,
4868 26,27,
4869 28,29,
4870 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4871 0,1,
4872 32,33,34,35
4874 static const int order_1[] = {
4875 18,19,
4876 20,21,
4877 22,23,
4878 24,25,
4879 30,31,
4880 26,27,
4881 28,29,
4882 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4883 0,1,
4884 32,33,34,35
4886 static const int order_2[] = {
4887 25,24,
4888 23,22,
4889 21,20,
4890 19,18,
4891 30,31,
4892 26,27,
4893 28,29,
4894 17,16,
4895 15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4896 1,0,
4897 32,33,34,35
4900 const int *order = (TARGET_ORDER_1 ? order_1 :
4901 TARGET_ORDER_2 ? order_2 :
4902 order_0);
4903 for (i=0; i < ARRAY_SIZE (order_0); ++i)
4904 reg_alloc_order[i] = order[i];
4908 /* Mutually recursive subroutine of avr_rtx_cost for calculating the
4909 cost of an RTX operand given its context. X is the rtx of the
4910 operand, MODE is its mode, and OUTER is the rtx_code of this
4911 operand's parent operator. */
4913 static int
4914 avr_operand_rtx_cost (rtx x, enum machine_mode mode, enum rtx_code outer)
4916 enum rtx_code code = GET_CODE (x);
4917 int total;
4919 switch (code)
4921 case REG:
4922 case SUBREG:
4923 return 0;
4925 case CONST_INT:
4926 case CONST_DOUBLE:
4927 return COSTS_N_INSNS (GET_MODE_SIZE (mode));
4929 default:
4930 break;
4933 total = 0;
4934 avr_rtx_costs (x, code, outer, &total);
4935 return total;
4938 /* The AVR backend's rtx_cost function. X is rtx expression whose cost
4939 is to be calculated. Return true if the complete cost has been
4940 computed, and false if subexpressions should be scanned. In either
4941 case, *TOTAL contains the cost result. */
4943 static bool
4944 avr_rtx_costs (rtx x, int code, int outer_code, int *total)
4946 enum machine_mode mode = GET_MODE (x);
4947 HOST_WIDE_INT val;
4949 switch (code)
4951 case CONST_INT:
4952 case CONST_DOUBLE:
4953 /* Immediate constants are as cheap as registers. */
4954 *total = 0;
4955 return true;
4957 case MEM:
4958 case CONST:
4959 case LABEL_REF:
4960 case SYMBOL_REF:
4961 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
4962 return true;
4964 case NEG:
4965 switch (mode)
4967 case QImode:
4968 case SFmode:
4969 *total = COSTS_N_INSNS (1);
4970 break;
4972 case HImode:
4973 *total = COSTS_N_INSNS (3);
4974 break;
4976 case SImode:
4977 *total = COSTS_N_INSNS (7);
4978 break;
4980 default:
4981 return false;
4983 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
4984 return true;
4986 case ABS:
4987 switch (mode)
4989 case QImode:
4990 case SFmode:
4991 *total = COSTS_N_INSNS (1);
4992 break;
4994 default:
4995 return false;
4997 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
4998 return true;
5000 case NOT:
5001 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5002 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5003 return true;
5005 case ZERO_EXTEND:
5006 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
5007 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
5008 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5009 return true;
5011 case SIGN_EXTEND:
5012 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
5013 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
5014 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5015 return true;
5017 case PLUS:
5018 switch (mode)
5020 case QImode:
5021 *total = COSTS_N_INSNS (1);
5022 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5023 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5024 break;
5026 case HImode:
5027 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5029 *total = COSTS_N_INSNS (2);
5030 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5032 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
5033 *total = COSTS_N_INSNS (1);
5034 else
5035 *total = COSTS_N_INSNS (2);
5036 break;
5038 case SImode:
5039 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5041 *total = COSTS_N_INSNS (4);
5042 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5044 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
5045 *total = COSTS_N_INSNS (1);
5046 else
5047 *total = COSTS_N_INSNS (4);
5048 break;
5050 default:
5051 return false;
5053 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5054 return true;
5056 case MINUS:
5057 case AND:
5058 case IOR:
5059 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5060 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5061 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5062 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5063 return true;
5065 case XOR:
5066 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5067 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5068 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5069 return true;
5071 case MULT:
5072 switch (mode)
5074 case QImode:
5075 if (AVR_ENHANCED)
5076 *total = COSTS_N_INSNS (optimize_size ? 3 : 4);
5077 else if (optimize_size)
5078 *total = COSTS_N_INSNS (AVR_MEGA ? 2 : 1);
5079 else
5080 return false;
5082 case HImode:
5083 if (AVR_ENHANCED)
5084 *total = COSTS_N_INSNS (optimize_size ? 7 : 10);
5085 else if (optimize_size)
5086 *total = COSTS_N_INSNS (AVR_MEGA ? 2 : 1);
5087 else
5088 return false;
5090 default:
5091 return false;
5093 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5094 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5095 return true;
5097 case DIV:
5098 case MOD:
5099 case UDIV:
5100 case UMOD:
5101 if (optimize_size)
5102 *total = COSTS_N_INSNS (AVR_MEGA ? 2 : 1);
5103 else
5104 return false;
5105 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5106 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5107 return true;
5109 case ASHIFT:
5110 switch (mode)
5112 case QImode:
5113 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5115 *total = COSTS_N_INSNS (optimize_size ? 4 : 17);
5116 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5118 else
5120 val = INTVAL (XEXP (x, 1));
5121 if (val == 7)
5122 *total = COSTS_N_INSNS (3);
5123 else if (val >= 0 && val <= 7)
5124 *total = COSTS_N_INSNS (val);
5125 else
5126 *total = COSTS_N_INSNS (1);
5128 break;
5130 case HImode:
5131 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5133 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5134 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5136 else
5137 switch (INTVAL (XEXP (x, 1)))
5139 case 0:
5140 *total = 0;
5141 break;
5142 case 1:
5143 case 8:
5144 *total = COSTS_N_INSNS (2);
5145 break;
5146 case 9:
5147 *total = COSTS_N_INSNS (3);
5148 break;
5149 case 2:
5150 case 3:
5151 case 10:
5152 case 15:
5153 *total = COSTS_N_INSNS (4);
5154 break;
5155 case 7:
5156 case 11:
5157 case 12:
5158 *total = COSTS_N_INSNS (5);
5159 break;
5160 case 4:
5161 *total = COSTS_N_INSNS (optimize_size ? 5 : 8);
5162 break;
5163 case 6:
5164 *total = COSTS_N_INSNS (optimize_size ? 5 : 9);
5165 break;
5166 case 5:
5167 *total = COSTS_N_INSNS (optimize_size ? 5 : 10);
5168 break;
5169 default:
5170 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5171 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5173 break;
5175 case SImode:
5176 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5178 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5179 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5181 else
5182 switch (INTVAL (XEXP (x, 1)))
5184 case 0:
5185 *total = 0;
5186 break;
5187 case 24:
5188 *total = COSTS_N_INSNS (3);
5189 break;
5190 case 1:
5191 case 8:
5192 case 16:
5193 *total = COSTS_N_INSNS (4);
5194 break;
5195 case 31:
5196 *total = COSTS_N_INSNS (6);
5197 break;
5198 case 2:
5199 *total = COSTS_N_INSNS (optimize_size ? 7 : 8);
5200 break;
5201 default:
5202 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5203 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5205 break;
5207 default:
5208 return false;
5210 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5211 return true;
5213 case ASHIFTRT:
5214 switch (mode)
5216 case QImode:
5217 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5219 *total = COSTS_N_INSNS (optimize_size ? 4 : 17);
5220 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5222 else
5224 val = INTVAL (XEXP (x, 1));
5225 if (val == 6)
5226 *total = COSTS_N_INSNS (4);
5227 else if (val == 7)
5228 *total = COSTS_N_INSNS (2);
5229 else if (val >= 0 && val <= 7)
5230 *total = COSTS_N_INSNS (val);
5231 else
5232 *total = COSTS_N_INSNS (1);
5234 break;
5236 case HImode:
5237 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5239 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5240 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5242 else
5243 switch (INTVAL (XEXP (x, 1)))
5245 case 0:
5246 *total = 0;
5247 break;
5248 case 1:
5249 *total = COSTS_N_INSNS (2);
5250 break;
5251 case 15:
5252 *total = COSTS_N_INSNS (3);
5253 break;
5254 case 2:
5255 case 7:
5256 case 8:
5257 case 9:
5258 *total = COSTS_N_INSNS (4);
5259 break;
5260 case 10:
5261 case 14:
5262 *total = COSTS_N_INSNS (5);
5263 break;
5264 case 11:
5265 *total = COSTS_N_INSNS (optimize_size ? 5 : 6);
5266 break;
5267 case 12:
5268 *total = COSTS_N_INSNS (optimize_size ? 5 : 7);
5269 break;
5270 case 6:
5271 case 13:
5272 *total = COSTS_N_INSNS (optimize_size ? 5 : 8);
5273 break;
5274 default:
5275 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5276 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5278 break;
5280 case SImode:
5281 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5283 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5284 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5286 else
5287 switch (INTVAL (XEXP (x, 1)))
5289 case 0:
5290 *total = 0;
5291 break;
5292 case 1:
5293 *total = COSTS_N_INSNS (4);
5294 break;
5295 case 8:
5296 case 16:
5297 case 24:
5298 *total = COSTS_N_INSNS (6);
5299 break;
5300 case 2:
5301 *total = COSTS_N_INSNS (optimize_size ? 7 : 8);
5302 break;
5303 case 31:
5304 *total = COSTS_N_INSNS (AVR_ENHANCED ? 4 : 5);
5305 break;
5306 default:
5307 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5308 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5310 break;
5312 default:
5313 return false;
5315 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5316 return true;
5318 case LSHIFTRT:
5319 switch (mode)
5321 case QImode:
5322 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5324 *total = COSTS_N_INSNS (optimize_size ? 4 : 17);
5325 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5327 else
5329 val = INTVAL (XEXP (x, 1));
5330 if (val == 7)
5331 *total = COSTS_N_INSNS (3);
5332 else if (val >= 0 && val <= 7)
5333 *total = COSTS_N_INSNS (val);
5334 else
5335 *total = COSTS_N_INSNS (1);
5337 break;
5339 case HImode:
5340 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5342 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5343 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5345 else
5346 switch (INTVAL (XEXP (x, 1)))
5348 case 0:
5349 *total = 0;
5350 break;
5351 case 1:
5352 case 8:
5353 *total = COSTS_N_INSNS (2);
5354 break;
5355 case 9:
5356 *total = COSTS_N_INSNS (3);
5357 break;
5358 case 2:
5359 case 10:
5360 case 15:
5361 *total = COSTS_N_INSNS (4);
5362 break;
5363 case 7:
5364 case 11:
5365 *total = COSTS_N_INSNS (5);
5366 break;
5367 case 3:
5368 case 12:
5369 case 13:
5370 case 14:
5371 *total = COSTS_N_INSNS (optimize_size ? 5 : 6);
5372 break;
5373 case 4:
5374 *total = COSTS_N_INSNS (optimize_size ? 5 : 7);
5375 break;
5376 case 5:
5377 case 6:
5378 *total = COSTS_N_INSNS (optimize_size ? 5 : 9);
5379 break;
5380 default:
5381 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5382 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5384 break;
5386 case SImode:
5387 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5389 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5390 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5392 else
5393 switch (INTVAL (XEXP (x, 1)))
5395 case 0:
5396 *total = 0;
5397 break;
5398 case 1:
5399 *total = COSTS_N_INSNS (4);
5400 break;
5401 case 2:
5402 *total = COSTS_N_INSNS (optimize_size ? 7 : 8);
5403 break;
5404 case 8:
5405 case 16:
5406 case 24:
5407 *total = COSTS_N_INSNS (4);
5408 break;
5409 case 31:
5410 *total = COSTS_N_INSNS (6);
5411 break;
5412 default:
5413 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5414 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5416 break;
5418 default:
5419 return false;
5421 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5422 return true;
5424 case COMPARE:
5425 switch (GET_MODE (XEXP (x, 0)))
5427 case QImode:
5428 *total = COSTS_N_INSNS (1);
5429 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5430 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5431 break;
5433 case HImode:
5434 *total = COSTS_N_INSNS (2);
5435 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5436 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5437 else if (INTVAL (XEXP (x, 1)) != 0)
5438 *total += COSTS_N_INSNS (1);
5439 break;
5441 case SImode:
5442 *total = COSTS_N_INSNS (4);
5443 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5444 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5445 else if (INTVAL (XEXP (x, 1)) != 0)
5446 *total += COSTS_N_INSNS (3);
5447 break;
5449 default:
5450 return false;
5452 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5453 return true;
5455 default:
5456 break;
5458 return false;
5461 /* Calculate the cost of a memory address. */
5463 static int
5464 avr_address_cost (rtx x)
5466 if (GET_CODE (x) == PLUS
5467 && GET_CODE (XEXP (x,1)) == CONST_INT
5468 && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
5469 && INTVAL (XEXP (x,1)) >= 61)
5470 return 18;
5471 if (CONSTANT_ADDRESS_P (x))
5473 if (avr_io_address_p (x, 1))
5474 return 2;
5475 return 4;
5477 return 4;
5480 /* Test for extra memory constraint 'Q'.
5481 It's a memory address based on Y or Z pointer with valid displacement. */
5484 extra_constraint_Q (rtx x)
5486 if (GET_CODE (XEXP (x,0)) == PLUS
5487 && REG_P (XEXP (XEXP (x,0), 0))
5488 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
5489 && (INTVAL (XEXP (XEXP (x,0), 1))
5490 <= MAX_LD_OFFSET (GET_MODE (x))))
5492 rtx xx = XEXP (XEXP (x,0), 0);
5493 int regno = REGNO (xx);
5494 if (TARGET_ALL_DEBUG)
5496 fprintf (stderr, ("extra_constraint:\n"
5497 "reload_completed: %d\n"
5498 "reload_in_progress: %d\n"),
5499 reload_completed, reload_in_progress);
5500 debug_rtx (x);
5502 if (regno >= FIRST_PSEUDO_REGISTER)
5503 return 1; /* allocate pseudos */
5504 else if (regno == REG_Z || regno == REG_Y)
5505 return 1; /* strictly check */
5506 else if (xx == frame_pointer_rtx
5507 || xx == arg_pointer_rtx)
5508 return 1; /* XXX frame & arg pointer checks */
5510 return 0;
5513 /* Convert condition code CONDITION to the valid AVR condition code. */
5515 RTX_CODE
5516 avr_normalize_condition (RTX_CODE condition)
5518 switch (condition)
5520 case GT:
5521 return GE;
5522 case GTU:
5523 return GEU;
5524 case LE:
5525 return LT;
5526 case LEU:
5527 return LTU;
5528 default:
5529 gcc_unreachable ();
5533 /* This function optimizes conditional jumps. */
5535 static void
5536 avr_reorg (void)
5538 rtx insn, pattern;
5540 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5542 if (! (GET_CODE (insn) == INSN
5543 || GET_CODE (insn) == CALL_INSN
5544 || GET_CODE (insn) == JUMP_INSN)
5545 || !single_set (insn))
5546 continue;
5548 pattern = PATTERN (insn);
5550 if (GET_CODE (pattern) == PARALLEL)
5551 pattern = XVECEXP (pattern, 0, 0);
5552 if (GET_CODE (pattern) == SET
5553 && SET_DEST (pattern) == cc0_rtx
5554 && compare_diff_p (insn))
5556 if (GET_CODE (SET_SRC (pattern)) == COMPARE)
5558 /* Now we work under compare insn. */
5560 pattern = SET_SRC (pattern);
5561 if (true_regnum (XEXP (pattern,0)) >= 0
5562 && true_regnum (XEXP (pattern,1)) >= 0 )
5564 rtx x = XEXP (pattern,0);
5565 rtx next = next_real_insn (insn);
5566 rtx pat = PATTERN (next);
5567 rtx src = SET_SRC (pat);
5568 rtx t = XEXP (src,0);
5569 PUT_CODE (t, swap_condition (GET_CODE (t)));
5570 XEXP (pattern,0) = XEXP (pattern,1);
5571 XEXP (pattern,1) = x;
5572 INSN_CODE (next) = -1;
5574 else if (true_regnum (XEXP (pattern,0)) >= 0
5575 && GET_CODE (XEXP (pattern,1)) == CONST_INT)
5577 rtx x = XEXP (pattern,1);
5578 rtx next = next_real_insn (insn);
5579 rtx pat = PATTERN (next);
5580 rtx src = SET_SRC (pat);
5581 rtx t = XEXP (src,0);
5582 enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
5584 if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
5586 XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
5587 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
5588 INSN_CODE (next) = -1;
5589 INSN_CODE (insn) = -1;
5593 else if (true_regnum (SET_SRC (pattern)) >= 0)
5595 /* This is a tst insn */
5596 rtx next = next_real_insn (insn);
5597 rtx pat = PATTERN (next);
5598 rtx src = SET_SRC (pat);
5599 rtx t = XEXP (src,0);
5601 PUT_CODE (t, swap_condition (GET_CODE (t)));
5602 SET_SRC (pattern) = gen_rtx_NEG (GET_MODE (SET_SRC (pattern)),
5603 SET_SRC (pattern));
5604 INSN_CODE (next) = -1;
5605 INSN_CODE (insn) = -1;
5611 /* Returns register number for function return value.*/
5614 avr_ret_register (void)
5616 return 24;
5619 /* Ceate an RTX representing the place where a
5620 library function returns a value of mode MODE. */
5623 avr_libcall_value (enum machine_mode mode)
5625 int offs = GET_MODE_SIZE (mode);
5626 if (offs < 2)
5627 offs = 2;
5628 return gen_rtx_REG (mode, RET_REGISTER + 2 - offs);
5631 /* Create an RTX representing the place where a
5632 function returns a value of data type VALTYPE. */
5635 avr_function_value (tree type, tree func ATTRIBUTE_UNUSED)
5637 unsigned int offs;
5639 if (TYPE_MODE (type) != BLKmode)
5640 return avr_libcall_value (TYPE_MODE (type));
5642 offs = int_size_in_bytes (type);
5643 if (offs < 2)
5644 offs = 2;
5645 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
5646 offs = GET_MODE_SIZE (SImode);
5647 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
5648 offs = GET_MODE_SIZE (DImode);
5650 return gen_rtx_REG (BLKmode, RET_REGISTER + 2 - offs);
5653 /* Returns nonzero if the number MASK has only one bit set. */
5656 mask_one_bit_p (HOST_WIDE_INT mask)
5658 int i;
5659 unsigned HOST_WIDE_INT n=mask;
5660 for (i = 0; i < 32; ++i)
5662 if (n & 0x80000000L)
5664 if (n & 0x7fffffffL)
5665 return 0;
5666 else
5667 return 32-i;
5669 n<<=1;
5671 return 0;
5675 /* Places additional restrictions on the register class to
5676 use when it is necessary to copy value X into a register
5677 in class CLASS. */
5679 enum reg_class
5680 preferred_reload_class (rtx x ATTRIBUTE_UNUSED, enum reg_class class)
5682 return class;
5686 test_hard_reg_class (enum reg_class class, rtx x)
5688 int regno = true_regnum (x);
5689 if (regno < 0)
5690 return 0;
5692 if (TEST_HARD_REG_CLASS (class, regno))
5693 return 1;
5695 return 0;
5700 jump_over_one_insn_p (rtx insn, rtx dest)
5702 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
5703 ? XEXP (dest, 0)
5704 : dest);
5705 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
5706 int dest_addr = INSN_ADDRESSES (uid);
5707 return dest_addr - jump_addr == get_attr_length (insn) + 1;
5710 /* Returns 1 if a value of mode MODE can be stored starting with hard
5711 register number REGNO. On the enhanced core, anything larger than
5712 1 byte must start in even numbered register for "movw" to work
5713 (this way we don't have to check for odd registers everywhere). */
5716 avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
5718 /* The only thing that can go into registers r28:r29 is a Pmode. */
5719 if (regno == REG_Y && mode == Pmode)
5720 return 1;
5722 /* Otherwise disallow all regno/mode combinations that span r28:r29. */
5723 if (regno <= (REG_Y + 1) && (regno + GET_MODE_SIZE (mode)) >= (REG_Y + 1))
5724 return 0;
5726 if (mode == QImode)
5727 return 1;
5729 /* Modes larger than QImode occupy consecutive registers. */
5730 if (regno + GET_MODE_SIZE (mode) > FIRST_PSEUDO_REGISTER)
5731 return 0;
5733 /* All modes larger than QImode should start in an even register. */
5734 return !(regno & 1);
5737 /* Returns 1 if X is a valid address for an I/O register of size SIZE
5738 (1 or 2). Used for lds/sts -> in/out optimization. Add 0x20 to SIZE
5739 to check for the lower half of I/O space (for cbi/sbi/sbic/sbis). */
5742 avr_io_address_p (rtx x, int size)
5744 return (optimize > 0 && GET_CODE (x) == CONST_INT
5745 && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size);
5748 /* Returns nonzero (bit number + 1) if X, or -X, is a constant power of 2. */
5751 const_int_pow2_p (rtx x)
5753 if (GET_CODE (x) == CONST_INT)
5755 HOST_WIDE_INT d = INTVAL (x);
5756 HOST_WIDE_INT abs_d = (d >= 0) ? d : -d;
5757 return exact_log2 (abs_d) + 1;
5759 return 0;
5762 const char *
5763 output_reload_inhi (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
5765 int tmp;
5766 if (!len)
5767 len = &tmp;
5769 if (GET_CODE (operands[1]) == CONST_INT)
5771 int val = INTVAL (operands[1]);
5772 if ((val & 0xff) == 0)
5774 *len = 3;
5775 return (AS2 (mov,%A0,__zero_reg__) CR_TAB
5776 AS2 (ldi,%2,hi8(%1)) CR_TAB
5777 AS2 (mov,%B0,%2));
5779 else if ((val & 0xff00) == 0)
5781 *len = 3;
5782 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5783 AS2 (mov,%A0,%2) CR_TAB
5784 AS2 (mov,%B0,__zero_reg__));
5786 else if ((val & 0xff) == ((val & 0xff00) >> 8))
5788 *len = 3;
5789 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5790 AS2 (mov,%A0,%2) CR_TAB
5791 AS2 (mov,%B0,%2));
5794 *len = 4;
5795 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5796 AS2 (mov,%A0,%2) CR_TAB
5797 AS2 (ldi,%2,hi8(%1)) CR_TAB
5798 AS2 (mov,%B0,%2));
5802 const char *
5803 output_reload_insisf (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
5805 rtx src = operands[1];
5806 int cnst = (GET_CODE (src) == CONST_INT);
5808 if (len)
5810 if (cnst)
5811 *len = 4 + ((INTVAL (src) & 0xff) != 0)
5812 + ((INTVAL (src) & 0xff00) != 0)
5813 + ((INTVAL (src) & 0xff0000) != 0)
5814 + ((INTVAL (src) & 0xff000000) != 0);
5815 else
5816 *len = 8;
5818 return "";
5821 if (cnst && ((INTVAL (src) & 0xff) == 0))
5822 output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
5823 else
5825 output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
5826 output_asm_insn (AS2 (mov, %A0, %2), operands);
5828 if (cnst && ((INTVAL (src) & 0xff00) == 0))
5829 output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
5830 else
5832 output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
5833 output_asm_insn (AS2 (mov, %B0, %2), operands);
5835 if (cnst && ((INTVAL (src) & 0xff0000) == 0))
5836 output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
5837 else
5839 output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
5840 output_asm_insn (AS2 (mov, %C0, %2), operands);
5842 if (cnst && ((INTVAL (src) & 0xff000000) == 0))
5843 output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
5844 else
5846 output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
5847 output_asm_insn (AS2 (mov, %D0, %2), operands);
5849 return "";
5852 void
5853 avr_output_bld (rtx operands[], int bit_nr)
5855 static char s[] = "bld %A0,0";
5857 s[5] = 'A' + (bit_nr >> 3);
5858 s[8] = '0' + (bit_nr & 7);
5859 output_asm_insn (s, operands);
5862 void
5863 avr_output_addr_vec_elt (FILE *stream, int value)
5865 switch_to_section (progmem_section);
5866 if (AVR_MEGA)
5867 fprintf (stream, "\t.word pm(.L%d)\n", value);
5868 else
5869 fprintf (stream, "\trjmp .L%d\n", value);
5871 jump_tables_size++;
5874 /* Returns 1 if SCRATCH are safe to be allocated as a scratch
5875 registers (for a define_peephole2) in the current function. */
5878 avr_peep2_scratch_safe (rtx scratch)
5880 if ((interrupt_function_p (current_function_decl)
5881 || signal_function_p (current_function_decl))
5882 && leaf_function_p ())
5884 int first_reg = true_regnum (scratch);
5885 int last_reg = first_reg + GET_MODE_SIZE (GET_MODE (scratch)) - 1;
5886 int reg;
5888 for (reg = first_reg; reg <= last_reg; reg++)
5890 if (!regs_ever_live[reg])
5891 return 0;
5894 return 1;
5897 /* Output a branch that tests a single bit of a register (QI, HI or SImode)
5898 or memory location in the I/O space (QImode only).
5900 Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
5901 Operand 1: register operand to test, or CONST_INT memory address.
5902 Operand 2: bit number (for QImode operand) or mask (HImode, SImode).
5903 Operand 3: label to jump to if the test is true. */
5905 const char *
5906 avr_out_sbxx_branch (rtx insn, rtx operands[])
5908 enum rtx_code comp = GET_CODE (operands[0]);
5909 int long_jump = (get_attr_length (insn) >= 4);
5910 int reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
5912 if (comp == GE)
5913 comp = EQ;
5914 else if (comp == LT)
5915 comp = NE;
5917 if (reverse)
5918 comp = reverse_condition (comp);
5920 if (GET_CODE (operands[1]) == CONST_INT)
5922 if (INTVAL (operands[1]) < 0x40)
5924 if (comp == EQ)
5925 output_asm_insn (AS2 (sbis,%1-0x20,%2), operands);
5926 else
5927 output_asm_insn (AS2 (sbic,%1-0x20,%2), operands);
5929 else
5931 output_asm_insn (AS2 (in,__tmp_reg__,%1-0x20), operands);
5932 if (comp == EQ)
5933 output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands);
5934 else
5935 output_asm_insn (AS2 (sbrc,__tmp_reg__,%2), operands);
5938 else /* GET_CODE (operands[1]) == REG */
5940 if (GET_MODE (operands[1]) == QImode)
5942 if (comp == EQ)
5943 output_asm_insn (AS2 (sbrs,%1,%2), operands);
5944 else
5945 output_asm_insn (AS2 (sbrc,%1,%2), operands);
5947 else /* HImode or SImode */
5949 static char buf[] = "sbrc %A1,0";
5950 int bit_nr = exact_log2 (INTVAL (operands[2])
5951 & GET_MODE_MASK (GET_MODE (operands[1])));
5953 buf[3] = (comp == EQ) ? 's' : 'c';
5954 buf[6] = 'A' + (bit_nr >> 3);
5955 buf[9] = '0' + (bit_nr & 7);
5956 output_asm_insn (buf, operands);
5960 if (long_jump)
5961 return (AS1 (rjmp,.+4) CR_TAB
5962 AS1 (jmp,%3));
5963 if (!reverse)
5964 return AS1 (rjmp,%3);
5965 return "";
5968 /* Worker function for TARGET_ASM_CONSTRUCTOR. */
5970 static void
5971 avr_asm_out_ctor (rtx symbol, int priority)
5973 fputs ("\t.global __do_global_ctors\n", asm_out_file);
5974 default_ctor_section_asm_out_constructor (symbol, priority);
5977 /* Worker function for TARGET_ASM_DESTRUCTOR. */
5979 static void
5980 avr_asm_out_dtor (rtx symbol, int priority)
5982 fputs ("\t.global __do_global_dtors\n", asm_out_file);
5983 default_dtor_section_asm_out_destructor (symbol, priority);
5986 /* Worker function for TARGET_RETURN_IN_MEMORY. */
5988 static bool
5989 avr_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
5991 if (TYPE_MODE (type) == BLKmode)
5993 HOST_WIDE_INT size = int_size_in_bytes (type);
5994 return (size == -1 || size > 8);
5996 else
5997 return false;
6000 #include "gt-avr.h"