* config/avr/avr.c (commands_in_file, commands_in_prologues,
[official-gcc.git] / gcc / config / avr / avr.c
blob67c11c00e2cd9bc1e72623fb48379b5b93794300
1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007
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 3, 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 COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "rtl.h"
27 #include "regs.h"
28 #include "hard-reg-set.h"
29 #include "real.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-attr.h"
33 #include "flags.h"
34 #include "reload.h"
35 #include "tree.h"
36 #include "output.h"
37 #include "expr.h"
38 #include "toplev.h"
39 #include "obstack.h"
40 #include "function.h"
41 #include "recog.h"
42 #include "ggc.h"
43 #include "tm_p.h"
44 #include "target.h"
45 #include "target-def.h"
46 #include "df.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);
60 static RTX_CODE compare_condition (rtx insn);
61 static int compare_sign_p (rtx insn);
62 static tree avr_handle_progmem_attribute (tree *, tree, tree, int, bool *);
63 static tree avr_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
64 static tree avr_handle_fntype_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_asm_function_end_prologue (FILE *);
70 static void avr_asm_function_begin_epilogue (FILE *);
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 (const_tree, const_tree);
82 static struct machine_function * avr_init_machine_status (void);
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 /* Preprocessor macros to define depending on MCU type. */
99 const char *avr_base_arch_macro;
100 const char *avr_extra_arch_macro;
102 section *progmem_section;
104 /* More than 8K of program memory: use "call" and "jmp". */
105 int avr_mega_p = 0;
107 /* Core have 'MUL*' instructions. */
108 int avr_have_mul_p = 0;
110 /* Assembler only. */
111 int avr_asm_only_p = 0;
113 /* Core have 'MOVW' and 'LPM Rx,Z' instructions. */
114 int avr_have_movw_lpmx_p = 0;
116 struct base_arch_s {
117 int asm_only;
118 int have_mul;
119 int mega;
120 int have_movw_lpmx;
121 const char *const macro;
124 static const struct base_arch_s avr_arch_types[] = {
125 { 1, 0, 0, 0, NULL }, /* unknown device specified */
126 { 1, 0, 0, 0, "__AVR_ARCH__=1" },
127 { 0, 0, 0, 0, "__AVR_ARCH__=2" },
128 { 0, 0, 0, 1, "__AVR_ARCH__=25"},
129 { 0, 0, 1, 0, "__AVR_ARCH__=3" },
130 { 0, 1, 0, 1, "__AVR_ARCH__=4" },
131 { 0, 1, 1, 1, "__AVR_ARCH__=5" }
134 /* These names are used as the index into the avr_arch_types[] table
135 above. */
137 enum avr_arch
139 ARCH_UNKNOWN,
140 ARCH_AVR1,
141 ARCH_AVR2,
142 ARCH_AVR25,
143 ARCH_AVR3,
144 ARCH_AVR4,
145 ARCH_AVR5
148 struct mcu_type_s {
149 const char *const name;
150 int arch; /* index in avr_arch_types[] */
151 /* Must lie outside user's namespace. NULL == no macro. */
152 const char *const macro;
155 /* List of all known AVR MCU types - if updated, it has to be kept
156 in sync in several places (FIXME: is there a better way?):
157 - here
158 - avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
159 - t-avr (MULTILIB_MATCHES)
160 - gas/config/tc-avr.c
161 - avr-libc */
163 static const struct mcu_type_s avr_mcu_types[] = {
164 /* Classic, <= 8K. */
165 { "avr2", ARCH_AVR2, NULL },
166 { "at90s2313", ARCH_AVR2, "__AVR_AT90S2313__" },
167 { "at90s2323", ARCH_AVR2, "__AVR_AT90S2323__" },
168 { "at90s2333", ARCH_AVR2, "__AVR_AT90S2333__" },
169 { "at90s2343", ARCH_AVR2, "__AVR_AT90S2343__" },
170 { "attiny22", ARCH_AVR2, "__AVR_ATtiny22__" },
171 { "attiny26", ARCH_AVR2, "__AVR_ATtiny26__" },
172 { "at90s4414", ARCH_AVR2, "__AVR_AT90S4414__" },
173 { "at90s4433", ARCH_AVR2, "__AVR_AT90S4433__" },
174 { "at90s4434", ARCH_AVR2, "__AVR_AT90S4434__" },
175 { "at90s8515", ARCH_AVR2, "__AVR_AT90S8515__" },
176 { "at90c8534", ARCH_AVR2, "__AVR_AT90C8534__" },
177 { "at90s8535", ARCH_AVR2, "__AVR_AT90S8535__" },
178 /* Classic + MOVW, <= 8K. */
179 { "avr25", ARCH_AVR25, NULL },
180 { "attiny13", ARCH_AVR25, "__AVR_ATtiny13__" },
181 { "attiny2313", ARCH_AVR25, "__AVR_ATtiny2313__" },
182 { "attiny24", ARCH_AVR25, "__AVR_ATtiny24__" },
183 { "attiny44", ARCH_AVR25, "__AVR_ATtiny44__" },
184 { "attiny84", ARCH_AVR25, "__AVR_ATtiny84__" },
185 { "attiny25", ARCH_AVR25, "__AVR_ATtiny25__" },
186 { "attiny45", ARCH_AVR25, "__AVR_ATtiny45__" },
187 { "attiny85", ARCH_AVR25, "__AVR_ATtiny85__" },
188 { "attiny261", ARCH_AVR25, "__AVR_ATtiny261__" },
189 { "attiny461", ARCH_AVR25, "__AVR_ATtiny461__" },
190 { "attiny861", ARCH_AVR25, "__AVR_ATtiny861__" },
191 { "at86rf401", ARCH_AVR25, "__AVR_AT86RF401__" },
192 /* Classic, > 8K. */
193 { "avr3", ARCH_AVR3, NULL },
194 { "atmega103", ARCH_AVR3, "__AVR_ATmega103__" },
195 { "atmega603", ARCH_AVR3, "__AVR_ATmega603__" },
196 { "at43usb320", ARCH_AVR3, "__AVR_AT43USB320__" },
197 { "at43usb355", ARCH_AVR3, "__AVR_AT43USB355__" },
198 { "at76c711", ARCH_AVR3, "__AVR_AT76C711__" },
199 /* Enhanced, <= 8K. */
200 { "avr4", ARCH_AVR4, NULL },
201 { "atmega8", ARCH_AVR4, "__AVR_ATmega8__" },
202 { "atmega48", ARCH_AVR4, "__AVR_ATmega48__" },
203 { "atmega88", ARCH_AVR4, "__AVR_ATmega88__" },
204 { "atmega8515", ARCH_AVR4, "__AVR_ATmega8515__" },
205 { "atmega8535", ARCH_AVR4, "__AVR_ATmega8535__" },
206 { "atmega8hva", ARCH_AVR4, "__AVR_ATmega8HVA__" },
207 { "at90pwm1", ARCH_AVR4, "__AVR_AT90PWM1__" },
208 { "at90pwm2", ARCH_AVR4, "__AVR_AT90PWM2__" },
209 { "at90pwm3", ARCH_AVR4, "__AVR_AT90PWM3__" },
210 /* Enhanced, > 8K. */
211 { "avr5", ARCH_AVR5, NULL },
212 { "atmega16", ARCH_AVR5, "__AVR_ATmega16__" },
213 { "atmega161", ARCH_AVR5, "__AVR_ATmega161__" },
214 { "atmega162", ARCH_AVR5, "__AVR_ATmega162__" },
215 { "atmega163", ARCH_AVR5, "__AVR_ATmega163__" },
216 { "atmega164p", ARCH_AVR5, "__AVR_ATmega164P__" },
217 { "atmega165", ARCH_AVR5, "__AVR_ATmega165__" },
218 { "atmega165p", ARCH_AVR5, "__AVR_ATmega165P__" },
219 { "atmega168", ARCH_AVR5, "__AVR_ATmega168__" },
220 { "atmega169", ARCH_AVR5, "__AVR_ATmega169__" },
221 { "atmega169p", ARCH_AVR5, "__AVR_ATmega169P__" },
222 { "atmega32", ARCH_AVR5, "__AVR_ATmega32__" },
223 { "atmega323", ARCH_AVR5, "__AVR_ATmega323__" },
224 { "atmega324p", ARCH_AVR5, "__AVR_ATmega324P__" },
225 { "atmega325", ARCH_AVR5, "__AVR_ATmega325__" },
226 { "atmega325p", ARCH_AVR5, "__AVR_ATmega325P__" },
227 { "atmega3250", ARCH_AVR5, "__AVR_ATmega3250__" },
228 { "atmega3250p", ARCH_AVR5, "__AVR_ATmega3250P__" },
229 { "atmega329", ARCH_AVR5, "__AVR_ATmega329__" },
230 { "atmega329p", ARCH_AVR5, "__AVR_ATmega329P__" },
231 { "atmega3290", ARCH_AVR5, "__AVR_ATmega3290__" },
232 { "atmega3290p", ARCH_AVR5, "__AVR_ATmega3290P__" },
233 { "atmega406", ARCH_AVR5, "__AVR_ATmega406__" },
234 { "atmega64", ARCH_AVR5, "__AVR_ATmega64__" },
235 { "atmega640", ARCH_AVR5, "__AVR_ATmega640__" },
236 { "atmega644", ARCH_AVR5, "__AVR_ATmega644__" },
237 { "atmega644p", ARCH_AVR5, "__AVR_ATmega644P__" },
238 { "atmega645", ARCH_AVR5, "__AVR_ATmega645__" },
239 { "atmega6450", ARCH_AVR5, "__AVR_ATmega6450__" },
240 { "atmega649", ARCH_AVR5, "__AVR_ATmega649__" },
241 { "atmega6490", ARCH_AVR5, "__AVR_ATmega6490__" },
242 { "atmega128", ARCH_AVR5, "__AVR_ATmega128__" },
243 { "atmega1280", ARCH_AVR5, "__AVR_ATmega1280__" },
244 { "atmega1281", ARCH_AVR5, "__AVR_ATmega1281__" },
245 { "atmega16hva", ARCH_AVR5, "__AVR_ATmega16HVA__" },
246 { "at90can32", ARCH_AVR5, "__AVR_AT90CAN32__" },
247 { "at90can64", ARCH_AVR5, "__AVR_AT90CAN64__" },
248 { "at90can128", ARCH_AVR5, "__AVR_AT90CAN128__" },
249 { "at90usb82", ARCH_AVR5, "__AVR_AT90USB82__" },
250 { "at90usb162", ARCH_AVR5, "__AVR_AT90USB162__" },
251 { "at90usb646", ARCH_AVR5, "__AVR_AT90USB646__" },
252 { "at90usb647", ARCH_AVR5, "__AVR_AT90USB647__" },
253 { "at90usb1286", ARCH_AVR5, "__AVR_AT90USB1286__" },
254 { "at90usb1287", ARCH_AVR5, "__AVR_AT90USB1287__" },
255 { "at94k", ARCH_AVR5, "__AVR_AT94K__" },
256 /* Assembler only. */
257 { "avr1", ARCH_AVR1, NULL },
258 { "at90s1200", ARCH_AVR1, "__AVR_AT90S1200__" },
259 { "attiny11", ARCH_AVR1, "__AVR_ATtiny11__" },
260 { "attiny12", ARCH_AVR1, "__AVR_ATtiny12__" },
261 { "attiny15", ARCH_AVR1, "__AVR_ATtiny15__" },
262 { "attiny28", ARCH_AVR1, "__AVR_ATtiny28__" },
263 { NULL, ARCH_UNKNOWN, NULL }
266 int avr_case_values_threshold = 30000;
268 /* Initialize the GCC target structure. */
269 #undef TARGET_ASM_ALIGNED_HI_OP
270 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
271 #undef TARGET_ASM_ALIGNED_SI_OP
272 #define TARGET_ASM_ALIGNED_SI_OP "\t.long\t"
273 #undef TARGET_ASM_UNALIGNED_HI_OP
274 #define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
275 #undef TARGET_ASM_UNALIGNED_SI_OP
276 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
277 #undef TARGET_ASM_INTEGER
278 #define TARGET_ASM_INTEGER avr_assemble_integer
279 #undef TARGET_ASM_FILE_START
280 #define TARGET_ASM_FILE_START avr_file_start
281 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
282 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
283 #undef TARGET_ASM_FILE_END
284 #define TARGET_ASM_FILE_END avr_file_end
286 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
287 #define TARGET_ASM_FUNCTION_END_PROLOGUE avr_asm_function_end_prologue
288 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
289 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE avr_asm_function_begin_epilogue
290 #undef TARGET_ATTRIBUTE_TABLE
291 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
292 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
293 #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
294 #undef TARGET_INSERT_ATTRIBUTES
295 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
296 #undef TARGET_SECTION_TYPE_FLAGS
297 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
298 #undef TARGET_RTX_COSTS
299 #define TARGET_RTX_COSTS avr_rtx_costs
300 #undef TARGET_ADDRESS_COST
301 #define TARGET_ADDRESS_COST avr_address_cost
302 #undef TARGET_MACHINE_DEPENDENT_REORG
303 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
305 #undef TARGET_RETURN_IN_MEMORY
306 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
308 #undef TARGET_STRICT_ARGUMENT_NAMING
309 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
311 struct gcc_target targetm = TARGET_INITIALIZER;
313 void
314 avr_override_options (void)
316 const struct mcu_type_s *t;
317 const struct base_arch_s *base;
319 flag_delete_null_pointer_checks = 0;
321 for (t = avr_mcu_types; t->name; t++)
322 if (strcmp (t->name, avr_mcu_name) == 0)
323 break;
325 if (!t->name)
327 fprintf (stderr, "unknown MCU '%s' specified\nKnown MCU names:\n",
328 avr_mcu_name);
329 for (t = avr_mcu_types; t->name; t++)
330 fprintf (stderr," %s\n", t->name);
333 base = &avr_arch_types[t->arch];
334 avr_asm_only_p = base->asm_only;
335 avr_have_mul_p = base->have_mul;
336 avr_mega_p = base->mega;
337 avr_have_movw_lpmx_p = base->have_movw_lpmx;
338 avr_base_arch_macro = base->macro;
339 avr_extra_arch_macro = t->macro;
341 if (optimize && !TARGET_NO_TABLEJUMP)
342 avr_case_values_threshold = (!AVR_MEGA || TARGET_CALL_PROLOGUES) ? 8 : 17;
344 tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO);
345 zero_reg_rtx = gen_rtx_REG (QImode, ZERO_REGNO);
347 init_machine_status = avr_init_machine_status;
350 /* return register class from register number. */
352 static const int reg_class_tab[]={
353 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
354 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
355 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
356 GENERAL_REGS, /* r0 - r15 */
357 LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
358 LD_REGS, /* r16 - 23 */
359 ADDW_REGS,ADDW_REGS, /* r24,r25 */
360 POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
361 POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
362 POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
363 STACK_REG,STACK_REG /* SPL,SPH */
366 /* Function to set up the backend function structure. */
368 static struct machine_function *
369 avr_init_machine_status (void)
371 return ((struct machine_function *)
372 ggc_alloc_cleared (sizeof (struct machine_function)));
375 /* Return register class for register R. */
377 enum reg_class
378 avr_regno_reg_class (int r)
380 if (r <= 33)
381 return reg_class_tab[r];
382 return ALL_REGS;
385 /* Return nonzero if FUNC is a naked function. */
387 static int
388 avr_naked_function_p (tree func)
390 tree a;
392 gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
394 a = lookup_attribute ("naked", TYPE_ATTRIBUTES (TREE_TYPE (func)));
395 return a != NULL_TREE;
398 /* Return nonzero if FUNC is an interrupt function as specified
399 by the "interrupt" attribute. */
401 static int
402 interrupt_function_p (tree func)
404 tree a;
406 if (TREE_CODE (func) != FUNCTION_DECL)
407 return 0;
409 a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
410 return a != NULL_TREE;
413 /* Return nonzero if FUNC is a signal function as specified
414 by the "signal" attribute. */
416 static int
417 signal_function_p (tree func)
419 tree a;
421 if (TREE_CODE (func) != FUNCTION_DECL)
422 return 0;
424 a = lookup_attribute ("signal", DECL_ATTRIBUTES (func));
425 return a != NULL_TREE;
428 /* Return the number of hard registers to push/pop in the prologue/epilogue
429 of the current function, and optionally store these registers in SET. */
431 static int
432 avr_regs_to_save (HARD_REG_SET *set)
434 int reg, count;
435 int int_or_sig_p = (interrupt_function_p (current_function_decl)
436 || signal_function_p (current_function_decl));
437 int leaf_func_p = leaf_function_p ();
439 if (set)
440 CLEAR_HARD_REG_SET (*set);
441 count = 0;
443 /* No need to save any registers if the function never returns. */
444 if (TREE_THIS_VOLATILE (current_function_decl))
445 return 0;
447 for (reg = 0; reg < 32; reg++)
449 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
450 any global register variables. */
451 if (fixed_regs[reg])
452 continue;
454 if ((int_or_sig_p && !leaf_func_p && call_used_regs[reg])
455 || (df_regs_ever_live_p (reg)
456 && (int_or_sig_p || !call_used_regs[reg])
457 && !(frame_pointer_needed
458 && (reg == REG_Y || reg == (REG_Y+1)))))
460 if (set)
461 SET_HARD_REG_BIT (*set, reg);
462 count++;
465 return count;
468 /* Compute offset between arg_pointer and frame_pointer. */
471 initial_elimination_offset (int from, int to)
473 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
474 return 0;
475 else
477 int offset = frame_pointer_needed ? 2 : 0;
479 offset += avr_regs_to_save (NULL);
480 return get_frame_size () + 2 + 1 + offset;
484 /* Return 1 if the function epilogue is just a single "ret". */
487 avr_simple_epilogue (void)
489 return (! frame_pointer_needed
490 && get_frame_size () == 0
491 && avr_regs_to_save (NULL) == 0
492 && ! interrupt_function_p (current_function_decl)
493 && ! signal_function_p (current_function_decl)
494 && ! avr_naked_function_p (current_function_decl)
495 && ! MAIN_NAME_P (DECL_NAME (current_function_decl))
496 && ! TREE_THIS_VOLATILE (current_function_decl));
499 /* This function checks sequence of live registers. */
501 static int
502 sequent_regs_live (void)
504 int reg;
505 int live_seq=0;
506 int cur_seq=0;
508 for (reg = 0; reg < 18; ++reg)
510 if (!call_used_regs[reg])
512 if (df_regs_ever_live_p (reg))
514 ++live_seq;
515 ++cur_seq;
517 else
518 cur_seq = 0;
522 if (!frame_pointer_needed)
524 if (df_regs_ever_live_p (REG_Y))
526 ++live_seq;
527 ++cur_seq;
529 else
530 cur_seq = 0;
532 if (df_regs_ever_live_p (REG_Y+1))
534 ++live_seq;
535 ++cur_seq;
537 else
538 cur_seq = 0;
540 else
542 cur_seq += 2;
543 live_seq += 2;
545 return (cur_seq == live_seq) ? live_seq : 0;
548 /* Output function prologue. */
550 void
551 expand_prologue (void)
553 int live_seq;
554 int minimize;
555 HOST_WIDE_INT size = get_frame_size();
556 /* Define templates for push instructions. */
557 rtx pushbyte = gen_rtx_MEM (QImode,
558 gen_rtx_POST_DEC (HImode, stack_pointer_rtx));
559 rtx pushword = gen_rtx_MEM (HImode,
560 gen_rtx_POST_DEC (HImode, stack_pointer_rtx));
561 rtx insn;
563 last_insn_address = 0;
565 /* Init cfun->machine. */
566 cfun->machine->is_main = MAIN_NAME_P (DECL_NAME (current_function_decl));
567 cfun->machine->is_naked = avr_naked_function_p (current_function_decl);
568 cfun->machine->is_interrupt = interrupt_function_p (current_function_decl);
569 cfun->machine->is_signal = signal_function_p (current_function_decl);
571 /* Prologue: naked. */
572 if (cfun->machine->is_naked)
574 return;
577 live_seq = sequent_regs_live ();
578 minimize = (TARGET_CALL_PROLOGUES
579 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
580 && live_seq);
582 if (cfun->machine->is_interrupt || cfun->machine->is_signal)
584 if (cfun->machine->is_interrupt)
586 /* Enable interrupts. */
587 insn = emit_insn (gen_enable_interrupt ());
588 RTX_FRAME_RELATED_P (insn) = 1;
591 /* Push zero reg. */
592 insn = emit_move_insn (pushbyte, zero_reg_rtx);
593 RTX_FRAME_RELATED_P (insn) = 1;
595 /* Push tmp reg. */
596 insn = emit_move_insn (pushbyte, tmp_reg_rtx);
597 RTX_FRAME_RELATED_P (insn) = 1;
599 /* Push SREG. */
600 insn = emit_move_insn (tmp_reg_rtx,
601 gen_rtx_MEM (QImode, GEN_INT (SREG_ADDR)));
602 RTX_FRAME_RELATED_P (insn) = 1;
603 insn = emit_move_insn (pushbyte, tmp_reg_rtx);
604 RTX_FRAME_RELATED_P (insn) = 1;
606 /* Clear zero reg. */
607 insn = emit_move_insn (zero_reg_rtx, const0_rtx);
608 RTX_FRAME_RELATED_P (insn) = 1;
610 /* Prevent any attempt to delete the setting of ZERO_REG! */
611 emit_insn (gen_rtx_USE (VOIDmode, zero_reg_rtx));
613 if (cfun->machine->is_main)
615 char buffer[40];
616 sprintf (buffer, "%s - %d", avr_init_stack, (int) size);
617 rtx sym = gen_rtx_SYMBOL_REF (HImode, ggc_strdup (buffer));
618 /* Initialize stack pointer using frame pointer. */
619 insn = emit_move_insn (frame_pointer_rtx, sym);
620 RTX_FRAME_RELATED_P (insn) = 1;
621 insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
622 RTX_FRAME_RELATED_P (insn) = 1;
624 else if (minimize && (frame_pointer_needed || live_seq > 6))
626 insn = emit_move_insn (gen_rtx_REG (HImode, REG_X),
627 gen_int_mode (size, HImode));
628 RTX_FRAME_RELATED_P (insn) = 1;
630 insn =
631 emit_insn (gen_call_prologue_saves (gen_int_mode (live_seq, HImode),
632 gen_int_mode (size + live_seq, HImode)));
633 RTX_FRAME_RELATED_P (insn) = 1;
635 else
637 HARD_REG_SET set;
638 avr_regs_to_save (&set);
639 int reg;
640 for (reg = 0; reg < 32; ++reg)
642 if (TEST_HARD_REG_BIT (set, reg))
644 /* Emit push of register to save. */
645 insn=emit_move_insn (pushbyte, gen_rtx_REG (QImode, reg));
646 RTX_FRAME_RELATED_P (insn) = 1;
649 if (frame_pointer_needed)
651 /* Push frame pointer. */
652 insn = emit_move_insn (pushword, frame_pointer_rtx);
653 RTX_FRAME_RELATED_P (insn) = 1;
654 if (!size)
656 insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
657 RTX_FRAME_RELATED_P (insn) = 1;
659 else
661 /* Creating a frame can be done by direct manipulation of the
662 stack or via the frame pointer. These two methods are:
663 fp=sp
664 fp-=size
665 sp=fp
667 sp-=size
668 fp=sp
669 the optimum method depends on function type, stack and frame size.
670 To avoid a complex logic, both methods are tested and shortest
671 is selected. */
672 rtx myfp;
673 /* First method. */
674 if (TARGET_TINY_STACK)
676 if (size < -63 || size > 63)
677 warning (0, "large frame pointer change (%d) with -mtiny-stack", size);
679 /* The high byte (r29) doesn't change - prefer 'subi' (1 cycle)
680 over 'sbiw' (2 cycles, same size). */
681 myfp = gen_rtx_REG (QImode, REGNO (frame_pointer_rtx));
683 else
685 /* Normal sized addition. */
686 myfp = frame_pointer_rtx;
688 /* Calculate length. */
689 int method1_length;
690 method1_length =
691 get_attr_length (gen_move_insn (frame_pointer_rtx, stack_pointer_rtx));
692 method1_length +=
693 get_attr_length (gen_move_insn (myfp,
694 gen_rtx_PLUS (GET_MODE(myfp), myfp,
695 gen_int_mode (-size,
696 GET_MODE(myfp)))));
697 method1_length +=
698 get_attr_length (gen_move_insn (stack_pointer_rtx, frame_pointer_rtx));
700 /* Method 2-Adjust Stack pointer. */
701 int sp_plus_length = 0;
702 if (size <= 6)
704 sp_plus_length =
705 get_attr_length (gen_move_insn (stack_pointer_rtx,
706 gen_rtx_PLUS (HImode, stack_pointer_rtx,
707 gen_int_mode (-size,
708 HImode))));
709 sp_plus_length +=
710 get_attr_length (gen_move_insn (frame_pointer_rtx, stack_pointer_rtx));
712 /* Use shortest method. */
713 if (size <= 6 && (sp_plus_length < method1_length))
715 insn = emit_move_insn (stack_pointer_rtx,
716 gen_rtx_PLUS (HImode, stack_pointer_rtx,
717 gen_int_mode (-size, HImode)));
718 RTX_FRAME_RELATED_P (insn) = 1;
719 insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
720 RTX_FRAME_RELATED_P (insn) = 1;
722 else
724 insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
725 RTX_FRAME_RELATED_P (insn) = 1;
726 insn = emit_move_insn (myfp,
727 gen_rtx_PLUS (GET_MODE(myfp), frame_pointer_rtx,
728 gen_int_mode (-size, GET_MODE(myfp))));
729 RTX_FRAME_RELATED_P (insn) = 1;
730 insn = emit_move_insn ( stack_pointer_rtx, frame_pointer_rtx);
731 RTX_FRAME_RELATED_P (insn) = 1;
738 /* Output summary at end of function prologue. */
740 static void
741 avr_asm_function_end_prologue (FILE *file)
743 if (cfun->machine->is_naked)
745 fputs ("/* prologue: naked */\n", file);
747 else
749 if (cfun->machine->is_interrupt)
751 fputs ("/* prologue: Interrupt */\n", file);
753 else if (cfun->machine->is_signal)
755 fputs ("/* prologue: Signal */\n", file);
757 else if (cfun->machine->is_main)
759 fputs ("/* prologue: main */\n", file);
761 else
762 fputs ("/* prologue: function */\n", file);
764 fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n",
765 get_frame_size());
769 /* Implement EPILOGUE_USES. */
772 avr_epilogue_uses (int regno ATTRIBUTE_UNUSED)
774 if (reload_completed
775 && cfun->machine
776 && (cfun->machine->is_interrupt || cfun->machine->is_signal))
777 return 1;
778 return 0;
781 /* Output RTL epilogue. */
783 void
784 expand_epilogue (void)
786 int reg;
787 int live_seq;
788 int minimize;
789 HOST_WIDE_INT size = get_frame_size();
790 rtx insn;
792 /* epilogue: naked */
793 if (cfun->machine->is_naked)
795 insn = emit_jump_insn (gen_return ());
796 RTX_FRAME_RELATED_P (insn) = 1;
797 return;
800 live_seq = sequent_regs_live ();
801 minimize = (TARGET_CALL_PROLOGUES
802 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
803 && live_seq);
805 if (cfun->machine->is_main)
807 /* Return value from main() is already in the correct registers
808 (r25:r24) as the exit() argument. */
809 insn = emit_jump_insn (gen_return ());
810 RTX_FRAME_RELATED_P (insn) = 1;
812 else if (minimize && (frame_pointer_needed || live_seq > 4))
814 if (frame_pointer_needed)
816 /* Get rid of frame. */
817 insn =
818 emit_move_insn(frame_pointer_rtx,
819 gen_rtx_PLUS (HImode, frame_pointer_rtx,
820 gen_int_mode (size, HImode)));
821 RTX_FRAME_RELATED_P (insn) = 1;
823 else
825 insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
826 RTX_FRAME_RELATED_P (insn) = 1;
829 insn =
830 emit_insn (gen_epilogue_restores (gen_int_mode (live_seq, HImode)));
831 RTX_FRAME_RELATED_P (insn) = 1;
833 else
835 if (frame_pointer_needed)
837 if (size)
839 /* Try two methods to adjust stack and select shortest. */
840 int fp_plus_length;
841 /* Method 1-Adjust frame pointer. */
842 fp_plus_length =
843 get_attr_length (gen_move_insn (frame_pointer_rtx,
844 gen_rtx_PLUS (HImode, frame_pointer_rtx,
845 gen_int_mode (size,
846 HImode))));
847 /* Copy to stack pointer. */
848 fp_plus_length +=
849 get_attr_length (gen_move_insn (stack_pointer_rtx, frame_pointer_rtx));
851 /* Method 2-Adjust Stack pointer. */
852 int sp_plus_length = 0;
853 if (size <= 5)
855 sp_plus_length =
856 get_attr_length (gen_move_insn (stack_pointer_rtx,
857 gen_rtx_PLUS (HImode, stack_pointer_rtx,
858 gen_int_mode (size,
859 HImode))));
861 /* Use shortest method. */
862 if (size <= 5 && (sp_plus_length < fp_plus_length))
864 insn = emit_move_insn (stack_pointer_rtx,
865 gen_rtx_PLUS (HImode, stack_pointer_rtx,
866 gen_int_mode (size, HImode)));
867 RTX_FRAME_RELATED_P (insn) = 1;
869 else
871 insn = emit_move_insn (frame_pointer_rtx,
872 gen_rtx_PLUS (HImode, frame_pointer_rtx,
873 gen_int_mode (size, HImode)));
874 RTX_FRAME_RELATED_P (insn) = 1;
875 /* Copy to stack pointer. */
876 insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
877 RTX_FRAME_RELATED_P (insn) = 1;
881 /* Restore previous frame_pointer. */
882 insn = emit_insn (gen_pophi (frame_pointer_rtx));
883 RTX_FRAME_RELATED_P (insn) = 1;
885 /* Restore used registers. */
886 HARD_REG_SET set;
887 avr_regs_to_save (&set);
888 for (reg = 31; reg >= 0; --reg)
890 if (TEST_HARD_REG_BIT (set, reg))
892 insn = emit_insn (gen_popqi (gen_rtx_REG (QImode, reg)));
893 RTX_FRAME_RELATED_P (insn) = 1;
896 if (cfun->machine->is_interrupt || cfun->machine->is_signal)
899 /* Restore SREG using tmp reg as scratch. */
900 insn = emit_insn (gen_popqi (tmp_reg_rtx));
901 RTX_FRAME_RELATED_P (insn) = 1;
903 insn = emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(SREG_ADDR)),
904 tmp_reg_rtx);
905 RTX_FRAME_RELATED_P (insn) = 1;
907 /* Restore tmp REG. */
908 insn = emit_insn (gen_popqi (tmp_reg_rtx));
909 RTX_FRAME_RELATED_P (insn) = 1;
911 /* Restore zero REG. */
912 insn = emit_insn (gen_popqi (zero_reg_rtx));
913 RTX_FRAME_RELATED_P (insn) = 1;
916 insn = emit_jump_insn (gen_return ());
917 RTX_FRAME_RELATED_P (insn) = 1;
921 /* Output summary messages at beginning of function epilogue. */
923 static void
924 avr_asm_function_begin_epilogue (FILE *file)
926 fprintf (file, "/* epilogue start */\n");
929 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
930 machine for a memory operand of mode MODE. */
933 legitimate_address_p (enum machine_mode mode, rtx x, int strict)
935 enum reg_class r = NO_REGS;
937 if (TARGET_ALL_DEBUG)
939 fprintf (stderr, "mode: (%s) %s %s %s %s:",
940 GET_MODE_NAME(mode),
941 strict ? "(strict)": "",
942 reload_completed ? "(reload_completed)": "",
943 reload_in_progress ? "(reload_in_progress)": "",
944 reg_renumber ? "(reg_renumber)" : "");
945 if (GET_CODE (x) == PLUS
946 && REG_P (XEXP (x, 0))
947 && GET_CODE (XEXP (x, 1)) == CONST_INT
948 && INTVAL (XEXP (x, 1)) >= 0
949 && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
950 && reg_renumber
952 fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
953 true_regnum (XEXP (x, 0)));
954 debug_rtx (x);
956 if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
957 : REG_OK_FOR_BASE_NOSTRICT_P (x)))
958 r = POINTER_REGS;
959 else if (CONSTANT_ADDRESS_P (x))
960 r = ALL_REGS;
961 else if (GET_CODE (x) == PLUS
962 && REG_P (XEXP (x, 0))
963 && GET_CODE (XEXP (x, 1)) == CONST_INT
964 && INTVAL (XEXP (x, 1)) >= 0)
966 int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
967 if (fit)
969 if (! strict
970 || REGNO (XEXP (x,0)) == REG_Y
971 || REGNO (XEXP (x,0)) == REG_Z)
972 r = BASE_POINTER_REGS;
973 if (XEXP (x,0) == frame_pointer_rtx
974 || XEXP (x,0) == arg_pointer_rtx)
975 r = BASE_POINTER_REGS;
977 else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
978 r = POINTER_Y_REGS;
980 else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
981 && REG_P (XEXP (x, 0))
982 && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
983 : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
985 r = POINTER_REGS;
987 if (TARGET_ALL_DEBUG)
989 fprintf (stderr, " ret = %c\n", r + '0');
991 return r == NO_REGS ? 0 : (int)r;
994 /* Attempts to replace X with a valid
995 memory address for an operand of mode MODE */
998 legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
1000 x = oldx;
1001 if (TARGET_ALL_DEBUG)
1003 fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
1004 debug_rtx (oldx);
1007 if (GET_CODE (oldx) == PLUS
1008 && REG_P (XEXP (oldx,0)))
1010 if (REG_P (XEXP (oldx,1)))
1011 x = force_reg (GET_MODE (oldx), oldx);
1012 else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
1014 int offs = INTVAL (XEXP (oldx,1));
1015 if (frame_pointer_rtx != XEXP (oldx,0))
1016 if (offs > MAX_LD_OFFSET (mode))
1018 if (TARGET_ALL_DEBUG)
1019 fprintf (stderr, "force_reg (big offset)\n");
1020 x = force_reg (GET_MODE (oldx), oldx);
1024 return x;
1028 /* Return a pointer register name as a string. */
1030 static const char *
1031 ptrreg_to_str (int regno)
1033 switch (regno)
1035 case REG_X: return "X";
1036 case REG_Y: return "Y";
1037 case REG_Z: return "Z";
1038 default:
1039 output_operand_lossage ("address operand requires constraint for X, Y, or Z register");
1041 return NULL;
1044 /* Return the condition name as a string.
1045 Used in conditional jump constructing */
1047 static const char *
1048 cond_string (enum rtx_code code)
1050 switch (code)
1052 case NE:
1053 return "ne";
1054 case EQ:
1055 return "eq";
1056 case GE:
1057 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1058 return "pl";
1059 else
1060 return "ge";
1061 case LT:
1062 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1063 return "mi";
1064 else
1065 return "lt";
1066 case GEU:
1067 return "sh";
1068 case LTU:
1069 return "lo";
1070 default:
1071 gcc_unreachable ();
1075 /* Output ADDR to FILE as address. */
1077 void
1078 print_operand_address (FILE *file, rtx addr)
1080 switch (GET_CODE (addr))
1082 case REG:
1083 fprintf (file, ptrreg_to_str (REGNO (addr)));
1084 break;
1086 case PRE_DEC:
1087 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1088 break;
1090 case POST_INC:
1091 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1092 break;
1094 default:
1095 if (CONSTANT_ADDRESS_P (addr)
1096 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (addr))
1097 || GET_CODE (addr) == LABEL_REF))
1099 fprintf (file, "pm(");
1100 output_addr_const (file,addr);
1101 fprintf (file ,")");
1103 else
1104 output_addr_const (file, addr);
1109 /* Output X as assembler operand to file FILE. */
1111 void
1112 print_operand (FILE *file, rtx x, int code)
1114 int abcd = 0;
1116 if (code >= 'A' && code <= 'D')
1117 abcd = code - 'A';
1119 if (code == '~')
1121 if (!AVR_MEGA)
1122 fputc ('r', file);
1124 else if (REG_P (x))
1126 if (x == zero_reg_rtx)
1127 fprintf (file, "__zero_reg__");
1128 else
1129 fprintf (file, reg_names[true_regnum (x) + abcd]);
1131 else if (GET_CODE (x) == CONST_INT)
1132 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd);
1133 else if (GET_CODE (x) == MEM)
1135 rtx addr = XEXP (x,0);
1137 if (CONSTANT_P (addr) && abcd)
1139 fputc ('(', file);
1140 output_address (addr);
1141 fprintf (file, ")+%d", abcd);
1143 else if (code == 'o')
1145 if (GET_CODE (addr) != PLUS)
1146 fatal_insn ("bad address, not (reg+disp):", addr);
1148 print_operand (file, XEXP (addr, 1), 0);
1150 else if (code == 'p' || code == 'r')
1152 if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
1153 fatal_insn ("bad address, not post_inc or pre_dec:", addr);
1155 if (code == 'p')
1156 print_operand_address (file, XEXP (addr, 0)); /* X, Y, Z */
1157 else
1158 print_operand (file, XEXP (addr, 0), 0); /* r26, r28, r30 */
1160 else if (GET_CODE (addr) == PLUS)
1162 print_operand_address (file, XEXP (addr,0));
1163 if (REGNO (XEXP (addr, 0)) == REG_X)
1164 fatal_insn ("internal compiler error. Bad address:"
1165 ,addr);
1166 fputc ('+', file);
1167 print_operand (file, XEXP (addr,1), code);
1169 else
1170 print_operand_address (file, addr);
1172 else if (GET_CODE (x) == CONST_DOUBLE)
1174 long val;
1175 REAL_VALUE_TYPE rv;
1176 if (GET_MODE (x) != SFmode)
1177 fatal_insn ("internal compiler error. Unknown mode:", x);
1178 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1179 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1180 fprintf (file, "0x%lx", val);
1182 else if (code == 'j')
1183 fputs (cond_string (GET_CODE (x)), file);
1184 else if (code == 'k')
1185 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
1186 else
1187 print_operand_address (file, x);
1190 /* Update the condition code in the INSN. */
1192 void
1193 notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
1195 rtx set;
1197 switch (get_attr_cc (insn))
1199 case CC_NONE:
1200 /* Insn does not affect CC at all. */
1201 break;
1203 case CC_SET_N:
1204 CC_STATUS_INIT;
1205 break;
1207 case CC_SET_ZN:
1208 set = single_set (insn);
1209 CC_STATUS_INIT;
1210 if (set)
1212 cc_status.flags |= CC_NO_OVERFLOW;
1213 cc_status.value1 = SET_DEST (set);
1215 break;
1217 case CC_SET_CZN:
1218 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1219 The V flag may or may not be known but that's ok because
1220 alter_cond will change tests to use EQ/NE. */
1221 set = single_set (insn);
1222 CC_STATUS_INIT;
1223 if (set)
1225 cc_status.value1 = SET_DEST (set);
1226 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1228 break;
1230 case CC_COMPARE:
1231 set = single_set (insn);
1232 CC_STATUS_INIT;
1233 if (set)
1234 cc_status.value1 = SET_SRC (set);
1235 break;
1237 case CC_CLOBBER:
1238 /* Insn doesn't leave CC in a usable state. */
1239 CC_STATUS_INIT;
1241 /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1242 set = single_set (insn);
1243 if (set)
1245 rtx src = SET_SRC (set);
1247 if (GET_CODE (src) == ASHIFTRT
1248 && GET_MODE (src) == QImode)
1250 rtx x = XEXP (src, 1);
1252 if (GET_CODE (x) == CONST_INT
1253 && INTVAL (x) > 0
1254 && INTVAL (x) != 6)
1256 cc_status.value1 = SET_DEST (set);
1257 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1261 break;
1265 /* Return maximum number of consecutive registers of
1266 class CLASS needed to hold a value of mode MODE. */
1269 class_max_nregs (enum reg_class class ATTRIBUTE_UNUSED,enum machine_mode mode)
1271 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1274 /* Choose mode for jump insn:
1275 1 - relative jump in range -63 <= x <= 62 ;
1276 2 - relative jump in range -2046 <= x <= 2045 ;
1277 3 - absolute jump (only for ATmega[16]03). */
1280 avr_jump_mode (rtx x, rtx insn)
1282 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1283 ? XEXP (x, 0) : x));
1284 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1285 int jump_distance = cur_addr - dest_addr;
1287 if (-63 <= jump_distance && jump_distance <= 62)
1288 return 1;
1289 else if (-2046 <= jump_distance && jump_distance <= 2045)
1290 return 2;
1291 else if (AVR_MEGA)
1292 return 3;
1294 return 2;
1297 /* return an AVR condition jump commands.
1298 X is a comparison RTX.
1299 LEN is a number returned by avr_jump_mode function.
1300 if REVERSE nonzero then condition code in X must be reversed. */
1302 const char *
1303 ret_cond_branch (rtx x, int len, int reverse)
1305 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1307 switch (cond)
1309 case GT:
1310 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1311 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1312 AS1 (brpl,%0)) :
1313 len == 2 ? (AS1 (breq,.+4) CR_TAB
1314 AS1 (brmi,.+2) CR_TAB
1315 AS1 (rjmp,%0)) :
1316 (AS1 (breq,.+6) CR_TAB
1317 AS1 (brmi,.+4) CR_TAB
1318 AS1 (jmp,%0)));
1320 else
1321 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1322 AS1 (brge,%0)) :
1323 len == 2 ? (AS1 (breq,.+4) CR_TAB
1324 AS1 (brlt,.+2) CR_TAB
1325 AS1 (rjmp,%0)) :
1326 (AS1 (breq,.+6) CR_TAB
1327 AS1 (brlt,.+4) CR_TAB
1328 AS1 (jmp,%0)));
1329 case GTU:
1330 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1331 AS1 (brsh,%0)) :
1332 len == 2 ? (AS1 (breq,.+4) CR_TAB
1333 AS1 (brlo,.+2) CR_TAB
1334 AS1 (rjmp,%0)) :
1335 (AS1 (breq,.+6) CR_TAB
1336 AS1 (brlo,.+4) CR_TAB
1337 AS1 (jmp,%0)));
1338 case LE:
1339 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1340 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1341 AS1 (brmi,%0)) :
1342 len == 2 ? (AS1 (breq,.+2) CR_TAB
1343 AS1 (brpl,.+2) CR_TAB
1344 AS1 (rjmp,%0)) :
1345 (AS1 (breq,.+2) CR_TAB
1346 AS1 (brpl,.+4) CR_TAB
1347 AS1 (jmp,%0)));
1348 else
1349 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1350 AS1 (brlt,%0)) :
1351 len == 2 ? (AS1 (breq,.+2) CR_TAB
1352 AS1 (brge,.+2) CR_TAB
1353 AS1 (rjmp,%0)) :
1354 (AS1 (breq,.+2) CR_TAB
1355 AS1 (brge,.+4) CR_TAB
1356 AS1 (jmp,%0)));
1357 case LEU:
1358 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1359 AS1 (brlo,%0)) :
1360 len == 2 ? (AS1 (breq,.+2) CR_TAB
1361 AS1 (brsh,.+2) CR_TAB
1362 AS1 (rjmp,%0)) :
1363 (AS1 (breq,.+2) CR_TAB
1364 AS1 (brsh,.+4) CR_TAB
1365 AS1 (jmp,%0)));
1366 default:
1367 if (reverse)
1369 switch (len)
1371 case 1:
1372 return AS1 (br%k1,%0);
1373 case 2:
1374 return (AS1 (br%j1,.+2) CR_TAB
1375 AS1 (rjmp,%0));
1376 default:
1377 return (AS1 (br%j1,.+4) CR_TAB
1378 AS1 (jmp,%0));
1381 else
1383 switch (len)
1385 case 1:
1386 return AS1 (br%j1,%0);
1387 case 2:
1388 return (AS1 (br%k1,.+2) CR_TAB
1389 AS1 (rjmp,%0));
1390 default:
1391 return (AS1 (br%k1,.+4) CR_TAB
1392 AS1 (jmp,%0));
1396 return "";
1399 /* Predicate function for immediate operand which fits to byte (8bit) */
1402 byte_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1404 return (GET_CODE (op) == CONST_INT
1405 && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1408 /* Output all insn addresses and their sizes into the assembly language
1409 output file. This is helpful for debugging whether the length attributes
1410 in the md file are correct.
1411 Output insn cost for next insn. */
1413 void
1414 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
1415 int num_operands ATTRIBUTE_UNUSED)
1417 int uid = INSN_UID (insn);
1419 if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1421 fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1422 INSN_ADDRESSES (uid),
1423 INSN_ADDRESSES (uid) - last_insn_address,
1424 rtx_cost (PATTERN (insn), INSN));
1426 last_insn_address = INSN_ADDRESSES (uid);
1429 /* Return 0 if undefined, 1 if always true or always false. */
1432 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE operator, rtx x)
1434 unsigned int max = (mode == QImode ? 0xff :
1435 mode == HImode ? 0xffff :
1436 mode == SImode ? 0xffffffff : 0);
1437 if (max && operator && GET_CODE (x) == CONST_INT)
1439 if (unsigned_condition (operator) != operator)
1440 max >>= 1;
1442 if (max != (INTVAL (x) & max)
1443 && INTVAL (x) != 0xff)
1444 return 1;
1446 return 0;
1450 /* Returns nonzero if REGNO is the number of a hard
1451 register in which function arguments are sometimes passed. */
1454 function_arg_regno_p(int r)
1456 return (r >= 8 && r <= 25);
1459 /* Initializing the variable cum for the state at the beginning
1460 of the argument list. */
1462 void
1463 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
1464 tree fndecl ATTRIBUTE_UNUSED)
1466 cum->nregs = 18;
1467 cum->regno = FIRST_CUM_REG;
1468 if (!libname && fntype)
1470 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1471 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1472 != void_type_node));
1473 if (stdarg)
1474 cum->nregs = 0;
1478 /* Returns the number of registers to allocate for a function argument. */
1480 static int
1481 avr_num_arg_regs (enum machine_mode mode, tree type)
1483 int size;
1485 if (mode == BLKmode)
1486 size = int_size_in_bytes (type);
1487 else
1488 size = GET_MODE_SIZE (mode);
1490 /* Align all function arguments to start in even-numbered registers.
1491 Odd-sized arguments leave holes above them. */
1493 return (size + 1) & ~1;
1496 /* Controls whether a function argument is passed
1497 in a register, and which register. */
1500 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1501 int named ATTRIBUTE_UNUSED)
1503 int bytes = avr_num_arg_regs (mode, type);
1505 if (cum->nregs && bytes <= cum->nregs)
1506 return gen_rtx_REG (mode, cum->regno - bytes);
1508 return NULL_RTX;
1511 /* Update the summarizer variable CUM to advance past an argument
1512 in the argument list. */
1514 void
1515 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1516 int named ATTRIBUTE_UNUSED)
1518 int bytes = avr_num_arg_regs (mode, type);
1520 cum->nregs -= bytes;
1521 cum->regno -= bytes;
1523 if (cum->nregs <= 0)
1525 cum->nregs = 0;
1526 cum->regno = FIRST_CUM_REG;
1530 /***********************************************************************
1531 Functions for outputting various mov's for a various modes
1532 ************************************************************************/
1533 const char *
1534 output_movqi (rtx insn, rtx operands[], int *l)
1536 int dummy;
1537 rtx dest = operands[0];
1538 rtx src = operands[1];
1539 int *real_l = l;
1541 if (!l)
1542 l = &dummy;
1544 *l = 1;
1546 if (register_operand (dest, QImode))
1548 if (register_operand (src, QImode)) /* mov r,r */
1550 if (test_hard_reg_class (STACK_REG, dest))
1551 return AS2 (out,%0,%1);
1552 else if (test_hard_reg_class (STACK_REG, src))
1553 return AS2 (in,%0,%1);
1555 return AS2 (mov,%0,%1);
1557 else if (CONSTANT_P (src))
1559 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1560 return AS2 (ldi,%0,lo8(%1));
1562 if (GET_CODE (src) == CONST_INT)
1564 if (src == const0_rtx) /* mov r,L */
1565 return AS1 (clr,%0);
1566 else if (src == const1_rtx)
1568 *l = 2;
1569 return (AS1 (clr,%0) CR_TAB
1570 AS1 (inc,%0));
1572 else if (src == constm1_rtx)
1574 /* Immediate constants -1 to any register */
1575 *l = 2;
1576 return (AS1 (clr,%0) CR_TAB
1577 AS1 (dec,%0));
1579 else
1581 int bit_nr = exact_log2 (INTVAL (src));
1583 if (bit_nr >= 0)
1585 *l = 3;
1586 if (!real_l)
1587 output_asm_insn ((AS1 (clr,%0) CR_TAB
1588 "set"), operands);
1589 if (!real_l)
1590 avr_output_bld (operands, bit_nr);
1592 return "";
1597 /* Last resort, larger than loading from memory. */
1598 *l = 4;
1599 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1600 AS2 (ldi,r31,lo8(%1)) CR_TAB
1601 AS2 (mov,%0,r31) CR_TAB
1602 AS2 (mov,r31,__tmp_reg__));
1604 else if (GET_CODE (src) == MEM)
1605 return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1607 else if (GET_CODE (dest) == MEM)
1609 const char *template;
1611 if (src == const0_rtx)
1612 operands[1] = zero_reg_rtx;
1614 template = out_movqi_mr_r (insn, operands, real_l);
1616 if (!real_l)
1617 output_asm_insn (template, operands);
1619 operands[1] = src;
1621 return "";
1625 const char *
1626 output_movhi (rtx insn, rtx operands[], int *l)
1628 int dummy;
1629 rtx dest = operands[0];
1630 rtx src = operands[1];
1631 int *real_l = l;
1633 if (!l)
1634 l = &dummy;
1636 if (register_operand (dest, HImode))
1638 if (register_operand (src, HImode)) /* mov r,r */
1640 if (test_hard_reg_class (STACK_REG, dest))
1642 if (TARGET_TINY_STACK)
1644 *l = 1;
1645 return AS2 (out,__SP_L__,%A1);
1647 /* Use simple load of stack pointer if no interrupts are used
1648 or inside main or signal function prologue where they disabled. */
1649 else if (TARGET_NO_INTERRUPTS
1650 || (reload_completed
1651 && cfun->machine->is_main
1652 && prologue_epilogue_contains (insn))
1653 || (reload_completed
1654 && cfun->machine->is_signal
1655 && prologue_epilogue_contains (insn)))
1657 *l = 2;
1658 return (AS2 (out,__SP_H__,%B1) CR_TAB
1659 AS2 (out,__SP_L__,%A1));
1661 /* In interrupt prolog we know interrupts are enabled. */
1662 else if (reload_completed
1663 && cfun->machine->is_interrupt
1664 && prologue_epilogue_contains (insn))
1666 *l = 4;
1667 return ("cli" CR_TAB
1668 AS2 (out,__SP_H__,%B1) CR_TAB
1669 "sei" CR_TAB
1670 AS2 (out,__SP_L__,%A1));
1672 *l = 5;
1673 return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB
1674 "cli" CR_TAB
1675 AS2 (out,__SP_H__,%B1) CR_TAB
1676 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1677 AS2 (out,__SP_L__,%A1));
1679 else if (test_hard_reg_class (STACK_REG, src))
1681 *l = 2;
1682 return (AS2 (in,%A0,__SP_L__) CR_TAB
1683 AS2 (in,%B0,__SP_H__));
1686 if (AVR_HAVE_MOVW)
1688 *l = 1;
1689 return (AS2 (movw,%0,%1));
1691 else
1693 *l = 2;
1694 return (AS2 (mov,%A0,%A1) CR_TAB
1695 AS2 (mov,%B0,%B1));
1698 else if (CONSTANT_P (src))
1700 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1702 *l = 2;
1703 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1704 AS2 (ldi,%B0,hi8(%1)));
1707 if (GET_CODE (src) == CONST_INT)
1709 if (src == const0_rtx) /* mov r,L */
1711 *l = 2;
1712 return (AS1 (clr,%A0) CR_TAB
1713 AS1 (clr,%B0));
1715 else if (src == const1_rtx)
1717 *l = 3;
1718 return (AS1 (clr,%A0) CR_TAB
1719 AS1 (clr,%B0) CR_TAB
1720 AS1 (inc,%A0));
1722 else if (src == constm1_rtx)
1724 /* Immediate constants -1 to any register */
1725 *l = 3;
1726 return (AS1 (clr,%0) CR_TAB
1727 AS1 (dec,%A0) CR_TAB
1728 AS2 (mov,%B0,%A0));
1730 else
1732 int bit_nr = exact_log2 (INTVAL (src));
1734 if (bit_nr >= 0)
1736 *l = 4;
1737 if (!real_l)
1738 output_asm_insn ((AS1 (clr,%A0) CR_TAB
1739 AS1 (clr,%B0) CR_TAB
1740 "set"), operands);
1741 if (!real_l)
1742 avr_output_bld (operands, bit_nr);
1744 return "";
1748 if ((INTVAL (src) & 0xff) == 0)
1750 *l = 5;
1751 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1752 AS1 (clr,%A0) 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 ((INTVAL (src) & 0xff00) == 0)
1759 *l = 5;
1760 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1761 AS2 (ldi,r31,lo8(%1)) CR_TAB
1762 AS2 (mov,%A0,r31) CR_TAB
1763 AS1 (clr,%B0) CR_TAB
1764 AS2 (mov,r31,__tmp_reg__));
1768 /* Last resort, equal to loading from memory. */
1769 *l = 6;
1770 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1771 AS2 (ldi,r31,lo8(%1)) CR_TAB
1772 AS2 (mov,%A0,r31) CR_TAB
1773 AS2 (ldi,r31,hi8(%1)) CR_TAB
1774 AS2 (mov,%B0,r31) CR_TAB
1775 AS2 (mov,r31,__tmp_reg__));
1777 else if (GET_CODE (src) == MEM)
1778 return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1780 else if (GET_CODE (dest) == MEM)
1782 const char *template;
1784 if (src == const0_rtx)
1785 operands[1] = zero_reg_rtx;
1787 template = out_movhi_mr_r (insn, operands, real_l);
1789 if (!real_l)
1790 output_asm_insn (template, operands);
1792 operands[1] = src;
1793 return "";
1795 fatal_insn ("invalid insn:", insn);
1796 return "";
1799 const char *
1800 out_movqi_r_mr (rtx insn, rtx op[], int *l)
1802 rtx dest = op[0];
1803 rtx src = op[1];
1804 rtx x = XEXP (src, 0);
1805 int dummy;
1807 if (!l)
1808 l = &dummy;
1810 if (CONSTANT_ADDRESS_P (x))
1812 if (CONST_INT_P (x) && INTVAL (x) == SREG_ADDR)
1814 *l = 1;
1815 return AS2 (in,%0,__SREG__);
1817 if (avr_io_address_p (x, 1))
1819 *l = 1;
1820 return AS2 (in,%0,%1-0x20);
1822 *l = 2;
1823 return AS2 (lds,%0,%1);
1825 /* memory access by reg+disp */
1826 else if (GET_CODE (x) == PLUS
1827 && REG_P (XEXP (x,0))
1828 && GET_CODE (XEXP (x,1)) == CONST_INT)
1830 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1832 int disp = INTVAL (XEXP (x,1));
1833 if (REGNO (XEXP (x,0)) != REG_Y)
1834 fatal_insn ("incorrect insn:",insn);
1836 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1837 return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
1838 AS2 (ldd,%0,Y+63) CR_TAB
1839 AS2 (sbiw,r28,%o1-63));
1841 return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1842 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1843 AS2 (ld,%0,Y) CR_TAB
1844 AS2 (subi,r28,lo8(%o1)) CR_TAB
1845 AS2 (sbci,r29,hi8(%o1)));
1847 else if (REGNO (XEXP (x,0)) == REG_X)
1849 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1850 it but I have this situation with extremal optimizing options. */
1851 if (reg_overlap_mentioned_p (dest, XEXP (x,0))
1852 || reg_unused_after (insn, XEXP (x,0)))
1853 return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
1854 AS2 (ld,%0,X));
1856 return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
1857 AS2 (ld,%0,X) CR_TAB
1858 AS2 (sbiw,r26,%o1));
1860 *l = 1;
1861 return AS2 (ldd,%0,%1);
1863 *l = 1;
1864 return AS2 (ld,%0,%1);
1867 const char *
1868 out_movhi_r_mr (rtx insn, rtx op[], int *l)
1870 rtx dest = op[0];
1871 rtx src = op[1];
1872 rtx base = XEXP (src, 0);
1873 int reg_dest = true_regnum (dest);
1874 int reg_base = true_regnum (base);
1875 /* "volatile" forces reading low byte first, even if less efficient,
1876 for correct operation with 16-bit I/O registers. */
1877 int mem_volatile_p = MEM_VOLATILE_P (src);
1878 int tmp;
1880 if (!l)
1881 l = &tmp;
1883 if (reg_base > 0)
1885 if (reg_dest == reg_base) /* R = (R) */
1887 *l = 3;
1888 return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1889 AS2 (ld,%B0,%1) CR_TAB
1890 AS2 (mov,%A0,__tmp_reg__));
1892 else if (reg_base == REG_X) /* (R26) */
1894 if (reg_unused_after (insn, base))
1896 *l = 2;
1897 return (AS2 (ld,%A0,X+) CR_TAB
1898 AS2 (ld,%B0,X));
1900 *l = 3;
1901 return (AS2 (ld,%A0,X+) CR_TAB
1902 AS2 (ld,%B0,X) CR_TAB
1903 AS2 (sbiw,r26,1));
1905 else /* (R) */
1907 *l = 2;
1908 return (AS2 (ld,%A0,%1) CR_TAB
1909 AS2 (ldd,%B0,%1+1));
1912 else if (GET_CODE (base) == PLUS) /* (R + i) */
1914 int disp = INTVAL (XEXP (base, 1));
1915 int reg_base = true_regnum (XEXP (base, 0));
1917 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
1919 if (REGNO (XEXP (base, 0)) != REG_Y)
1920 fatal_insn ("incorrect insn:",insn);
1922 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1923 return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
1924 AS2 (ldd,%A0,Y+62) CR_TAB
1925 AS2 (ldd,%B0,Y+63) CR_TAB
1926 AS2 (sbiw,r28,%o1-62));
1928 return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1929 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1930 AS2 (ld,%A0,Y) CR_TAB
1931 AS2 (ldd,%B0,Y+1) CR_TAB
1932 AS2 (subi,r28,lo8(%o1)) CR_TAB
1933 AS2 (sbci,r29,hi8(%o1)));
1935 if (reg_base == REG_X)
1937 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1938 it but I have this situation with extremal
1939 optimization options. */
1941 *l = 4;
1942 if (reg_base == reg_dest)
1943 return (AS2 (adiw,r26,%o1) CR_TAB
1944 AS2 (ld,__tmp_reg__,X+) CR_TAB
1945 AS2 (ld,%B0,X) CR_TAB
1946 AS2 (mov,%A0,__tmp_reg__));
1948 return (AS2 (adiw,r26,%o1) CR_TAB
1949 AS2 (ld,%A0,X+) CR_TAB
1950 AS2 (ld,%B0,X) CR_TAB
1951 AS2 (sbiw,r26,%o1+1));
1954 if (reg_base == reg_dest)
1956 *l = 3;
1957 return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
1958 AS2 (ldd,%B0,%B1) CR_TAB
1959 AS2 (mov,%A0,__tmp_reg__));
1962 *l = 2;
1963 return (AS2 (ldd,%A0,%A1) CR_TAB
1964 AS2 (ldd,%B0,%B1));
1966 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
1968 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1969 fatal_insn ("incorrect insn:", insn);
1971 if (mem_volatile_p)
1973 if (REGNO (XEXP (base, 0)) == REG_X)
1975 *l = 4;
1976 return (AS2 (sbiw,r26,2) CR_TAB
1977 AS2 (ld,%A0,X+) CR_TAB
1978 AS2 (ld,%B0,X) CR_TAB
1979 AS2 (sbiw,r26,1));
1981 else
1983 *l = 3;
1984 return (AS2 (sbiw,%r1,2) CR_TAB
1985 AS2 (ld,%A0,%p1) CR_TAB
1986 AS2 (ldd,%B0,%p1+1));
1990 *l = 2;
1991 return (AS2 (ld,%B0,%1) CR_TAB
1992 AS2 (ld,%A0,%1));
1994 else if (GET_CODE (base) == POST_INC) /* (R++) */
1996 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1997 fatal_insn ("incorrect insn:", insn);
1999 *l = 2;
2000 return (AS2 (ld,%A0,%1) CR_TAB
2001 AS2 (ld,%B0,%1));
2003 else if (CONSTANT_ADDRESS_P (base))
2005 if (avr_io_address_p (base, 2))
2007 *l = 2;
2008 return (AS2 (in,%A0,%A1-0x20) CR_TAB
2009 AS2 (in,%B0,%B1-0x20));
2011 *l = 4;
2012 return (AS2 (lds,%A0,%A1) CR_TAB
2013 AS2 (lds,%B0,%B1));
2016 fatal_insn ("unknown move insn:",insn);
2017 return "";
2020 const char *
2021 out_movsi_r_mr (rtx insn, rtx op[], int *l)
2023 rtx dest = op[0];
2024 rtx src = op[1];
2025 rtx base = XEXP (src, 0);
2026 int reg_dest = true_regnum (dest);
2027 int reg_base = true_regnum (base);
2028 int tmp;
2030 if (!l)
2031 l = &tmp;
2033 if (reg_base > 0)
2035 if (reg_base == REG_X) /* (R26) */
2037 if (reg_dest == REG_X)
2038 /* "ld r26,-X" is undefined */
2039 return *l=7, (AS2 (adiw,r26,3) CR_TAB
2040 AS2 (ld,r29,X) CR_TAB
2041 AS2 (ld,r28,-X) CR_TAB
2042 AS2 (ld,__tmp_reg__,-X) CR_TAB
2043 AS2 (sbiw,r26,1) CR_TAB
2044 AS2 (ld,r26,X) CR_TAB
2045 AS2 (mov,r27,__tmp_reg__));
2046 else if (reg_dest == REG_X - 2)
2047 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2048 AS2 (ld,%B0,X+) CR_TAB
2049 AS2 (ld,__tmp_reg__,X+) CR_TAB
2050 AS2 (ld,%D0,X) CR_TAB
2051 AS2 (mov,%C0,__tmp_reg__));
2052 else if (reg_unused_after (insn, base))
2053 return *l=4, (AS2 (ld,%A0,X+) CR_TAB
2054 AS2 (ld,%B0,X+) CR_TAB
2055 AS2 (ld,%C0,X+) CR_TAB
2056 AS2 (ld,%D0,X));
2057 else
2058 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2059 AS2 (ld,%B0,X+) CR_TAB
2060 AS2 (ld,%C0,X+) CR_TAB
2061 AS2 (ld,%D0,X) CR_TAB
2062 AS2 (sbiw,r26,3));
2064 else
2066 if (reg_dest == reg_base)
2067 return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
2068 AS2 (ldd,%C0,%1+2) CR_TAB
2069 AS2 (ldd,__tmp_reg__,%1+1) CR_TAB
2070 AS2 (ld,%A0,%1) CR_TAB
2071 AS2 (mov,%B0,__tmp_reg__));
2072 else if (reg_base == reg_dest + 2)
2073 return *l=5, (AS2 (ld ,%A0,%1) CR_TAB
2074 AS2 (ldd,%B0,%1+1) CR_TAB
2075 AS2 (ldd,__tmp_reg__,%1+2) CR_TAB
2076 AS2 (ldd,%D0,%1+3) CR_TAB
2077 AS2 (mov,%C0,__tmp_reg__));
2078 else
2079 return *l=4, (AS2 (ld ,%A0,%1) CR_TAB
2080 AS2 (ldd,%B0,%1+1) CR_TAB
2081 AS2 (ldd,%C0,%1+2) CR_TAB
2082 AS2 (ldd,%D0,%1+3));
2085 else if (GET_CODE (base) == PLUS) /* (R + i) */
2087 int disp = INTVAL (XEXP (base, 1));
2089 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2091 if (REGNO (XEXP (base, 0)) != REG_Y)
2092 fatal_insn ("incorrect insn:",insn);
2094 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2095 return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2096 AS2 (ldd,%A0,Y+60) CR_TAB
2097 AS2 (ldd,%B0,Y+61) CR_TAB
2098 AS2 (ldd,%C0,Y+62) CR_TAB
2099 AS2 (ldd,%D0,Y+63) CR_TAB
2100 AS2 (sbiw,r28,%o1-60));
2102 return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2103 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2104 AS2 (ld,%A0,Y) CR_TAB
2105 AS2 (ldd,%B0,Y+1) CR_TAB
2106 AS2 (ldd,%C0,Y+2) CR_TAB
2107 AS2 (ldd,%D0,Y+3) CR_TAB
2108 AS2 (subi,r28,lo8(%o1)) CR_TAB
2109 AS2 (sbci,r29,hi8(%o1)));
2112 reg_base = true_regnum (XEXP (base, 0));
2113 if (reg_base == REG_X)
2115 /* R = (X + d) */
2116 if (reg_dest == REG_X)
2118 *l = 7;
2119 /* "ld r26,-X" is undefined */
2120 return (AS2 (adiw,r26,%o1+3) CR_TAB
2121 AS2 (ld,r29,X) CR_TAB
2122 AS2 (ld,r28,-X) CR_TAB
2123 AS2 (ld,__tmp_reg__,-X) CR_TAB
2124 AS2 (sbiw,r26,1) CR_TAB
2125 AS2 (ld,r26,X) CR_TAB
2126 AS2 (mov,r27,__tmp_reg__));
2128 *l = 6;
2129 if (reg_dest == REG_X - 2)
2130 return (AS2 (adiw,r26,%o1) CR_TAB
2131 AS2 (ld,r24,X+) CR_TAB
2132 AS2 (ld,r25,X+) CR_TAB
2133 AS2 (ld,__tmp_reg__,X+) CR_TAB
2134 AS2 (ld,r27,X) CR_TAB
2135 AS2 (mov,r26,__tmp_reg__));
2137 return (AS2 (adiw,r26,%o1) CR_TAB
2138 AS2 (ld,%A0,X+) CR_TAB
2139 AS2 (ld,%B0,X+) CR_TAB
2140 AS2 (ld,%C0,X+) CR_TAB
2141 AS2 (ld,%D0,X) CR_TAB
2142 AS2 (sbiw,r26,%o1+3));
2144 if (reg_dest == reg_base)
2145 return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2146 AS2 (ldd,%C0,%C1) CR_TAB
2147 AS2 (ldd,__tmp_reg__,%B1) CR_TAB
2148 AS2 (ldd,%A0,%A1) CR_TAB
2149 AS2 (mov,%B0,__tmp_reg__));
2150 else if (reg_dest == reg_base - 2)
2151 return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2152 AS2 (ldd,%B0,%B1) CR_TAB
2153 AS2 (ldd,__tmp_reg__,%C1) CR_TAB
2154 AS2 (ldd,%D0,%D1) CR_TAB
2155 AS2 (mov,%C0,__tmp_reg__));
2156 return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2157 AS2 (ldd,%B0,%B1) CR_TAB
2158 AS2 (ldd,%C0,%C1) CR_TAB
2159 AS2 (ldd,%D0,%D1));
2161 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2162 return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2163 AS2 (ld,%C0,%1) CR_TAB
2164 AS2 (ld,%B0,%1) CR_TAB
2165 AS2 (ld,%A0,%1));
2166 else if (GET_CODE (base) == POST_INC) /* (R++) */
2167 return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2168 AS2 (ld,%B0,%1) CR_TAB
2169 AS2 (ld,%C0,%1) CR_TAB
2170 AS2 (ld,%D0,%1));
2171 else if (CONSTANT_ADDRESS_P (base))
2172 return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2173 AS2 (lds,%B0,%B1) CR_TAB
2174 AS2 (lds,%C0,%C1) CR_TAB
2175 AS2 (lds,%D0,%D1));
2177 fatal_insn ("unknown move insn:",insn);
2178 return "";
2181 const char *
2182 out_movsi_mr_r (rtx insn, rtx op[], int *l)
2184 rtx dest = op[0];
2185 rtx src = op[1];
2186 rtx base = XEXP (dest, 0);
2187 int reg_base = true_regnum (base);
2188 int reg_src = true_regnum (src);
2189 int tmp;
2191 if (!l)
2192 l = &tmp;
2194 if (CONSTANT_ADDRESS_P (base))
2195 return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2196 AS2 (sts,%B0,%B1) CR_TAB
2197 AS2 (sts,%C0,%C1) CR_TAB
2198 AS2 (sts,%D0,%D1));
2199 if (reg_base > 0) /* (r) */
2201 if (reg_base == REG_X) /* (R26) */
2203 if (reg_src == REG_X)
2205 /* "st X+,r26" is undefined */
2206 if (reg_unused_after (insn, base))
2207 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2208 AS2 (st,X,r26) CR_TAB
2209 AS2 (adiw,r26,1) CR_TAB
2210 AS2 (st,X+,__tmp_reg__) CR_TAB
2211 AS2 (st,X+,r28) CR_TAB
2212 AS2 (st,X,r29));
2213 else
2214 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2215 AS2 (st,X,r26) CR_TAB
2216 AS2 (adiw,r26,1) CR_TAB
2217 AS2 (st,X+,__tmp_reg__) CR_TAB
2218 AS2 (st,X+,r28) CR_TAB
2219 AS2 (st,X,r29) CR_TAB
2220 AS2 (sbiw,r26,3));
2222 else if (reg_base == reg_src + 2)
2224 if (reg_unused_after (insn, base))
2225 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2226 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2227 AS2 (st,%0+,%A1) CR_TAB
2228 AS2 (st,%0+,%B1) CR_TAB
2229 AS2 (st,%0+,__zero_reg__) CR_TAB
2230 AS2 (st,%0,__tmp_reg__) CR_TAB
2231 AS1 (clr,__zero_reg__));
2232 else
2233 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2234 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2235 AS2 (st,%0+,%A1) CR_TAB
2236 AS2 (st,%0+,%B1) CR_TAB
2237 AS2 (st,%0+,__zero_reg__) CR_TAB
2238 AS2 (st,%0,__tmp_reg__) CR_TAB
2239 AS1 (clr,__zero_reg__) CR_TAB
2240 AS2 (sbiw,r26,3));
2242 return *l=5, (AS2 (st,%0+,%A1) CR_TAB
2243 AS2 (st,%0+,%B1) CR_TAB
2244 AS2 (st,%0+,%C1) CR_TAB
2245 AS2 (st,%0,%D1) CR_TAB
2246 AS2 (sbiw,r26,3));
2248 else
2249 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2250 AS2 (std,%0+1,%B1) CR_TAB
2251 AS2 (std,%0+2,%C1) CR_TAB
2252 AS2 (std,%0+3,%D1));
2254 else if (GET_CODE (base) == PLUS) /* (R + i) */
2256 int disp = INTVAL (XEXP (base, 1));
2257 reg_base = REGNO (XEXP (base, 0));
2258 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2260 if (reg_base != REG_Y)
2261 fatal_insn ("incorrect insn:",insn);
2263 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2264 return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2265 AS2 (std,Y+60,%A1) CR_TAB
2266 AS2 (std,Y+61,%B1) CR_TAB
2267 AS2 (std,Y+62,%C1) CR_TAB
2268 AS2 (std,Y+63,%D1) CR_TAB
2269 AS2 (sbiw,r28,%o0-60));
2271 return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2272 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2273 AS2 (st,Y,%A1) CR_TAB
2274 AS2 (std,Y+1,%B1) CR_TAB
2275 AS2 (std,Y+2,%C1) CR_TAB
2276 AS2 (std,Y+3,%D1) CR_TAB
2277 AS2 (subi,r28,lo8(%o0)) CR_TAB
2278 AS2 (sbci,r29,hi8(%o0)));
2280 if (reg_base == REG_X)
2282 /* (X + d) = R */
2283 if (reg_src == REG_X)
2285 *l = 9;
2286 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2287 AS2 (mov,__zero_reg__,r27) CR_TAB
2288 AS2 (adiw,r26,%o0) CR_TAB
2289 AS2 (st,X+,__tmp_reg__) CR_TAB
2290 AS2 (st,X+,__zero_reg__) CR_TAB
2291 AS2 (st,X+,r28) CR_TAB
2292 AS2 (st,X,r29) CR_TAB
2293 AS1 (clr,__zero_reg__) CR_TAB
2294 AS2 (sbiw,r26,%o0+3));
2296 else if (reg_src == REG_X - 2)
2298 *l = 9;
2299 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2300 AS2 (mov,__zero_reg__,r27) CR_TAB
2301 AS2 (adiw,r26,%o0) CR_TAB
2302 AS2 (st,X+,r24) CR_TAB
2303 AS2 (st,X+,r25) CR_TAB
2304 AS2 (st,X+,__tmp_reg__) CR_TAB
2305 AS2 (st,X,__zero_reg__) CR_TAB
2306 AS1 (clr,__zero_reg__) CR_TAB
2307 AS2 (sbiw,r26,%o0+3));
2309 *l = 6;
2310 return (AS2 (adiw,r26,%o0) CR_TAB
2311 AS2 (st,X+,%A1) CR_TAB
2312 AS2 (st,X+,%B1) CR_TAB
2313 AS2 (st,X+,%C1) CR_TAB
2314 AS2 (st,X,%D1) CR_TAB
2315 AS2 (sbiw,r26,%o0+3));
2317 return *l=4, (AS2 (std,%A0,%A1) CR_TAB
2318 AS2 (std,%B0,%B1) CR_TAB
2319 AS2 (std,%C0,%C1) CR_TAB
2320 AS2 (std,%D0,%D1));
2322 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2323 return *l=4, (AS2 (st,%0,%D1) CR_TAB
2324 AS2 (st,%0,%C1) CR_TAB
2325 AS2 (st,%0,%B1) CR_TAB
2326 AS2 (st,%0,%A1));
2327 else if (GET_CODE (base) == POST_INC) /* (R++) */
2328 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2329 AS2 (st,%0,%B1) CR_TAB
2330 AS2 (st,%0,%C1) CR_TAB
2331 AS2 (st,%0,%D1));
2332 fatal_insn ("unknown move insn:",insn);
2333 return "";
2336 const char *
2337 output_movsisf(rtx insn, rtx operands[], int *l)
2339 int dummy;
2340 rtx dest = operands[0];
2341 rtx src = operands[1];
2342 int *real_l = l;
2344 if (!l)
2345 l = &dummy;
2347 if (register_operand (dest, VOIDmode))
2349 if (register_operand (src, VOIDmode)) /* mov r,r */
2351 if (true_regnum (dest) > true_regnum (src))
2353 if (AVR_HAVE_MOVW)
2355 *l = 2;
2356 return (AS2 (movw,%C0,%C1) CR_TAB
2357 AS2 (movw,%A0,%A1));
2359 *l = 4;
2360 return (AS2 (mov,%D0,%D1) CR_TAB
2361 AS2 (mov,%C0,%C1) CR_TAB
2362 AS2 (mov,%B0,%B1) CR_TAB
2363 AS2 (mov,%A0,%A1));
2365 else
2367 if (AVR_HAVE_MOVW)
2369 *l = 2;
2370 return (AS2 (movw,%A0,%A1) CR_TAB
2371 AS2 (movw,%C0,%C1));
2373 *l = 4;
2374 return (AS2 (mov,%A0,%A1) CR_TAB
2375 AS2 (mov,%B0,%B1) CR_TAB
2376 AS2 (mov,%C0,%C1) CR_TAB
2377 AS2 (mov,%D0,%D1));
2380 else if (CONSTANT_P (src))
2382 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2384 *l = 4;
2385 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
2386 AS2 (ldi,%B0,hi8(%1)) CR_TAB
2387 AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2388 AS2 (ldi,%D0,hhi8(%1)));
2391 if (GET_CODE (src) == CONST_INT)
2393 const char *const clr_op0 =
2394 AVR_HAVE_MOVW ? (AS1 (clr,%A0) CR_TAB
2395 AS1 (clr,%B0) CR_TAB
2396 AS2 (movw,%C0,%A0))
2397 : (AS1 (clr,%A0) CR_TAB
2398 AS1 (clr,%B0) CR_TAB
2399 AS1 (clr,%C0) CR_TAB
2400 AS1 (clr,%D0));
2402 if (src == const0_rtx) /* mov r,L */
2404 *l = AVR_HAVE_MOVW ? 3 : 4;
2405 return clr_op0;
2407 else if (src == const1_rtx)
2409 if (!real_l)
2410 output_asm_insn (clr_op0, operands);
2411 *l = AVR_HAVE_MOVW ? 4 : 5;
2412 return AS1 (inc,%A0);
2414 else if (src == constm1_rtx)
2416 /* Immediate constants -1 to any register */
2417 if (AVR_HAVE_MOVW)
2419 *l = 4;
2420 return (AS1 (clr,%A0) CR_TAB
2421 AS1 (dec,%A0) CR_TAB
2422 AS2 (mov,%B0,%A0) CR_TAB
2423 AS2 (movw,%C0,%A0));
2425 *l = 5;
2426 return (AS1 (clr,%A0) CR_TAB
2427 AS1 (dec,%A0) CR_TAB
2428 AS2 (mov,%B0,%A0) CR_TAB
2429 AS2 (mov,%C0,%A0) CR_TAB
2430 AS2 (mov,%D0,%A0));
2432 else
2434 int bit_nr = exact_log2 (INTVAL (src));
2436 if (bit_nr >= 0)
2438 *l = AVR_HAVE_MOVW ? 5 : 6;
2439 if (!real_l)
2441 output_asm_insn (clr_op0, operands);
2442 output_asm_insn ("set", operands);
2444 if (!real_l)
2445 avr_output_bld (operands, bit_nr);
2447 return "";
2452 /* Last resort, better than loading from memory. */
2453 *l = 10;
2454 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2455 AS2 (ldi,r31,lo8(%1)) CR_TAB
2456 AS2 (mov,%A0,r31) CR_TAB
2457 AS2 (ldi,r31,hi8(%1)) CR_TAB
2458 AS2 (mov,%B0,r31) CR_TAB
2459 AS2 (ldi,r31,hlo8(%1)) CR_TAB
2460 AS2 (mov,%C0,r31) CR_TAB
2461 AS2 (ldi,r31,hhi8(%1)) CR_TAB
2462 AS2 (mov,%D0,r31) CR_TAB
2463 AS2 (mov,r31,__tmp_reg__));
2465 else if (GET_CODE (src) == MEM)
2466 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2468 else if (GET_CODE (dest) == MEM)
2470 const char *template;
2472 if (src == const0_rtx)
2473 operands[1] = zero_reg_rtx;
2475 template = out_movsi_mr_r (insn, operands, real_l);
2477 if (!real_l)
2478 output_asm_insn (template, operands);
2480 operands[1] = src;
2481 return "";
2483 fatal_insn ("invalid insn:", insn);
2484 return "";
2487 const char *
2488 out_movqi_mr_r (rtx insn, rtx op[], int *l)
2490 rtx dest = op[0];
2491 rtx src = op[1];
2492 rtx x = XEXP (dest, 0);
2493 int dummy;
2495 if (!l)
2496 l = &dummy;
2498 if (CONSTANT_ADDRESS_P (x))
2500 if (CONST_INT_P (x) && INTVAL (x) == SREG_ADDR)
2502 *l = 1;
2503 return AS2 (out,__SREG__,%1);
2505 if (avr_io_address_p (x, 1))
2507 *l = 1;
2508 return AS2 (out,%0-0x20,%1);
2510 *l = 2;
2511 return AS2 (sts,%0,%1);
2513 /* memory access by reg+disp */
2514 else if (GET_CODE (x) == PLUS
2515 && REG_P (XEXP (x,0))
2516 && GET_CODE (XEXP (x,1)) == CONST_INT)
2518 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2520 int disp = INTVAL (XEXP (x,1));
2521 if (REGNO (XEXP (x,0)) != REG_Y)
2522 fatal_insn ("incorrect insn:",insn);
2524 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2525 return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2526 AS2 (std,Y+63,%1) CR_TAB
2527 AS2 (sbiw,r28,%o0-63));
2529 return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2530 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2531 AS2 (st,Y,%1) CR_TAB
2532 AS2 (subi,r28,lo8(%o0)) CR_TAB
2533 AS2 (sbci,r29,hi8(%o0)));
2535 else if (REGNO (XEXP (x,0)) == REG_X)
2537 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2539 if (reg_unused_after (insn, XEXP (x,0)))
2540 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2541 AS2 (adiw,r26,%o0) CR_TAB
2542 AS2 (st,X,__tmp_reg__));
2544 return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2545 AS2 (adiw,r26,%o0) CR_TAB
2546 AS2 (st,X,__tmp_reg__) CR_TAB
2547 AS2 (sbiw,r26,%o0));
2549 else
2551 if (reg_unused_after (insn, XEXP (x,0)))
2552 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2553 AS2 (st,X,%1));
2555 return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2556 AS2 (st,X,%1) CR_TAB
2557 AS2 (sbiw,r26,%o0));
2560 *l = 1;
2561 return AS2 (std,%0,%1);
2563 *l = 1;
2564 return AS2 (st,%0,%1);
2567 const char *
2568 out_movhi_mr_r (rtx insn, rtx op[], int *l)
2570 rtx dest = op[0];
2571 rtx src = op[1];
2572 rtx base = XEXP (dest, 0);
2573 int reg_base = true_regnum (base);
2574 int reg_src = true_regnum (src);
2575 /* "volatile" forces writing high byte first, even if less efficient,
2576 for correct operation with 16-bit I/O registers. */
2577 int mem_volatile_p = MEM_VOLATILE_P (dest);
2578 int tmp;
2580 if (!l)
2581 l = &tmp;
2582 if (CONSTANT_ADDRESS_P (base))
2584 if (avr_io_address_p (base, 2))
2586 *l = 2;
2587 return (AS2 (out,%B0-0x20,%B1) CR_TAB
2588 AS2 (out,%A0-0x20,%A1));
2590 return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2591 AS2 (sts,%A0,%A1));
2593 if (reg_base > 0)
2595 if (reg_base == REG_X)
2597 if (reg_src == REG_X)
2599 /* "st X+,r26" and "st -X,r26" are undefined. */
2600 if (!mem_volatile_p && reg_unused_after (insn, src))
2601 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2602 AS2 (st,X,r26) CR_TAB
2603 AS2 (adiw,r26,1) CR_TAB
2604 AS2 (st,X,__tmp_reg__));
2605 else
2606 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2607 AS2 (adiw,r26,1) CR_TAB
2608 AS2 (st,X,__tmp_reg__) CR_TAB
2609 AS2 (sbiw,r26,1) CR_TAB
2610 AS2 (st,X,r26));
2612 else
2614 if (!mem_volatile_p && reg_unused_after (insn, base))
2615 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2616 AS2 (st,X,%B1));
2617 else
2618 return *l=3, (AS2 (adiw,r26,1) CR_TAB
2619 AS2 (st,X,%B1) CR_TAB
2620 AS2 (st,-X,%A1));
2623 else
2624 return *l=2, (AS2 (std,%0+1,%B1) CR_TAB
2625 AS2 (st,%0,%A1));
2627 else if (GET_CODE (base) == PLUS)
2629 int disp = INTVAL (XEXP (base, 1));
2630 reg_base = REGNO (XEXP (base, 0));
2631 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2633 if (reg_base != REG_Y)
2634 fatal_insn ("incorrect insn:",insn);
2636 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2637 return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2638 AS2 (std,Y+63,%B1) CR_TAB
2639 AS2 (std,Y+62,%A1) CR_TAB
2640 AS2 (sbiw,r28,%o0-62));
2642 return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2643 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2644 AS2 (std,Y+1,%B1) CR_TAB
2645 AS2 (st,Y,%A1) CR_TAB
2646 AS2 (subi,r28,lo8(%o0)) CR_TAB
2647 AS2 (sbci,r29,hi8(%o0)));
2649 if (reg_base == REG_X)
2651 /* (X + d) = R */
2652 if (reg_src == REG_X)
2654 *l = 7;
2655 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2656 AS2 (mov,__zero_reg__,r27) CR_TAB
2657 AS2 (adiw,r26,%o0+1) CR_TAB
2658 AS2 (st,X,__zero_reg__) CR_TAB
2659 AS2 (st,-X,__tmp_reg__) CR_TAB
2660 AS1 (clr,__zero_reg__) CR_TAB
2661 AS2 (sbiw,r26,%o0));
2663 *l = 4;
2664 return (AS2 (adiw,r26,%o0+1) CR_TAB
2665 AS2 (st,X,%B1) CR_TAB
2666 AS2 (st,-X,%A1) CR_TAB
2667 AS2 (sbiw,r26,%o0));
2669 return *l=2, (AS2 (std,%B0,%B1) CR_TAB
2670 AS2 (std,%A0,%A1));
2672 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2673 return *l=2, (AS2 (st,%0,%B1) CR_TAB
2674 AS2 (st,%0,%A1));
2675 else if (GET_CODE (base) == POST_INC) /* (R++) */
2677 if (mem_volatile_p)
2679 if (REGNO (XEXP (base, 0)) == REG_X)
2681 *l = 4;
2682 return (AS2 (adiw,r26,1) CR_TAB
2683 AS2 (st,X,%B1) CR_TAB
2684 AS2 (st,-X,%A1) CR_TAB
2685 AS2 (adiw,r26,2));
2687 else
2689 *l = 3;
2690 return (AS2 (std,%p0+1,%B1) CR_TAB
2691 AS2 (st,%p0,%A1) CR_TAB
2692 AS2 (adiw,%r0,2));
2696 *l = 2;
2697 return (AS2 (st,%0,%A1) CR_TAB
2698 AS2 (st,%0,%B1));
2700 fatal_insn ("unknown move insn:",insn);
2701 return "";
2704 /* Return 1 if frame pointer for current function required. */
2707 frame_pointer_required_p (void)
2709 return (current_function_calls_alloca
2710 || current_function_args_info.nregs == 0
2711 || get_frame_size () > 0);
2714 /* Returns the condition of compare insn INSN, or UNKNOWN. */
2716 static RTX_CODE
2717 compare_condition (rtx insn)
2719 rtx next = next_real_insn (insn);
2720 RTX_CODE cond = UNKNOWN;
2721 if (next && GET_CODE (next) == JUMP_INSN)
2723 rtx pat = PATTERN (next);
2724 rtx src = SET_SRC (pat);
2725 rtx t = XEXP (src, 0);
2726 cond = GET_CODE (t);
2728 return cond;
2731 /* Returns nonzero if INSN is a tst insn that only tests the sign. */
2733 static int
2734 compare_sign_p (rtx insn)
2736 RTX_CODE cond = compare_condition (insn);
2737 return (cond == GE || cond == LT);
2740 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
2741 that needs to be swapped (GT, GTU, LE, LEU). */
2744 compare_diff_p (rtx insn)
2746 RTX_CODE cond = compare_condition (insn);
2747 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2750 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition. */
2753 compare_eq_p (rtx insn)
2755 RTX_CODE cond = compare_condition (insn);
2756 return (cond == EQ || cond == NE);
2760 /* Output test instruction for HImode. */
2762 const char *
2763 out_tsthi (rtx insn, int *l)
2765 if (compare_sign_p (insn))
2767 if (l) *l = 1;
2768 return AS1 (tst,%B0);
2770 if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
2771 && compare_eq_p (insn))
2773 /* Faster than sbiw if we can clobber the operand. */
2774 if (l) *l = 1;
2775 return AS2 (or,%A0,%B0);
2777 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2779 if (l) *l = 1;
2780 return AS2 (sbiw,%0,0);
2782 if (l) *l = 2;
2783 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2784 AS2 (cpc,%B0,__zero_reg__));
2788 /* Output test instruction for SImode. */
2790 const char *
2791 out_tstsi (rtx insn, int *l)
2793 if (compare_sign_p (insn))
2795 if (l) *l = 1;
2796 return AS1 (tst,%D0);
2798 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2800 if (l) *l = 3;
2801 return (AS2 (sbiw,%A0,0) CR_TAB
2802 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2803 AS2 (cpc,%D0,__zero_reg__));
2805 if (l) *l = 4;
2806 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2807 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2808 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2809 AS2 (cpc,%D0,__zero_reg__));
2813 /* Generate asm equivalent for various shifts.
2814 Shift count is a CONST_INT, MEM or REG.
2815 This only handles cases that are not already
2816 carefully hand-optimized in ?sh??i3_out. */
2818 void
2819 out_shift_with_cnt (const char *template, rtx insn, rtx operands[],
2820 int *len, int t_len)
2822 rtx op[10];
2823 char str[500];
2824 int second_label = 1;
2825 int saved_in_tmp = 0;
2826 int use_zero_reg = 0;
2828 op[0] = operands[0];
2829 op[1] = operands[1];
2830 op[2] = operands[2];
2831 op[3] = operands[3];
2832 str[0] = 0;
2834 if (len)
2835 *len = 1;
2837 if (GET_CODE (operands[2]) == CONST_INT)
2839 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2840 int count = INTVAL (operands[2]);
2841 int max_len = 10; /* If larger than this, always use a loop. */
2843 if (count <= 0)
2845 if (len)
2846 *len = 0;
2847 return;
2850 if (count < 8 && !scratch)
2851 use_zero_reg = 1;
2853 if (optimize_size)
2854 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
2856 if (t_len * count <= max_len)
2858 /* Output shifts inline with no loop - faster. */
2859 if (len)
2860 *len = t_len * count;
2861 else
2863 while (count-- > 0)
2864 output_asm_insn (template, op);
2867 return;
2870 if (scratch)
2872 if (!len)
2873 strcat (str, AS2 (ldi,%3,%2));
2875 else if (use_zero_reg)
2877 /* Hack to save one word: use __zero_reg__ as loop counter.
2878 Set one bit, then shift in a loop until it is 0 again. */
2880 op[3] = zero_reg_rtx;
2881 if (len)
2882 *len = 2;
2883 else
2884 strcat (str, ("set" CR_TAB
2885 AS2 (bld,%3,%2-1)));
2887 else
2889 /* No scratch register available, use one from LD_REGS (saved in
2890 __tmp_reg__) that doesn't overlap with registers to shift. */
2892 op[3] = gen_rtx_REG (QImode,
2893 ((true_regnum (operands[0]) - 1) & 15) + 16);
2894 op[4] = tmp_reg_rtx;
2895 saved_in_tmp = 1;
2897 if (len)
2898 *len = 3; /* Includes "mov %3,%4" after the loop. */
2899 else
2900 strcat (str, (AS2 (mov,%4,%3) CR_TAB
2901 AS2 (ldi,%3,%2)));
2904 second_label = 0;
2906 else if (GET_CODE (operands[2]) == MEM)
2908 rtx op_mov[10];
2910 op[3] = op_mov[0] = tmp_reg_rtx;
2911 op_mov[1] = op[2];
2913 if (len)
2914 out_movqi_r_mr (insn, op_mov, len);
2915 else
2916 output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2918 else if (register_operand (operands[2], QImode))
2920 if (reg_unused_after (insn, operands[2]))
2921 op[3] = op[2];
2922 else
2924 op[3] = tmp_reg_rtx;
2925 if (!len)
2926 strcat (str, (AS2 (mov,%3,%2) CR_TAB));
2929 else
2930 fatal_insn ("bad shift insn:", insn);
2932 if (second_label)
2934 if (len)
2935 ++*len;
2936 else
2937 strcat (str, AS1 (rjmp,2f));
2940 if (len)
2941 *len += t_len + 2; /* template + dec + brXX */
2942 else
2944 strcat (str, "\n1:\t");
2945 strcat (str, template);
2946 strcat (str, second_label ? "\n2:\t" : "\n\t");
2947 strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
2948 strcat (str, CR_TAB);
2949 strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
2950 if (saved_in_tmp)
2951 strcat (str, (CR_TAB AS2 (mov,%3,%4)));
2952 output_asm_insn (str, op);
2957 /* 8bit shift left ((char)x << i) */
2959 const char *
2960 ashlqi3_out (rtx insn, rtx operands[], int *len)
2962 if (GET_CODE (operands[2]) == CONST_INT)
2964 int k;
2966 if (!len)
2967 len = &k;
2969 switch (INTVAL (operands[2]))
2971 default:
2972 if (INTVAL (operands[2]) < 8)
2973 break;
2975 *len = 1;
2976 return AS1 (clr,%0);
2978 case 1:
2979 *len = 1;
2980 return AS1 (lsl,%0);
2982 case 2:
2983 *len = 2;
2984 return (AS1 (lsl,%0) CR_TAB
2985 AS1 (lsl,%0));
2987 case 3:
2988 *len = 3;
2989 return (AS1 (lsl,%0) CR_TAB
2990 AS1 (lsl,%0) CR_TAB
2991 AS1 (lsl,%0));
2993 case 4:
2994 if (test_hard_reg_class (LD_REGS, operands[0]))
2996 *len = 2;
2997 return (AS1 (swap,%0) CR_TAB
2998 AS2 (andi,%0,0xf0));
3000 *len = 4;
3001 return (AS1 (lsl,%0) CR_TAB
3002 AS1 (lsl,%0) CR_TAB
3003 AS1 (lsl,%0) CR_TAB
3004 AS1 (lsl,%0));
3006 case 5:
3007 if (test_hard_reg_class (LD_REGS, operands[0]))
3009 *len = 3;
3010 return (AS1 (swap,%0) CR_TAB
3011 AS1 (lsl,%0) CR_TAB
3012 AS2 (andi,%0,0xe0));
3014 *len = 5;
3015 return (AS1 (lsl,%0) CR_TAB
3016 AS1 (lsl,%0) CR_TAB
3017 AS1 (lsl,%0) CR_TAB
3018 AS1 (lsl,%0) CR_TAB
3019 AS1 (lsl,%0));
3021 case 6:
3022 if (test_hard_reg_class (LD_REGS, operands[0]))
3024 *len = 4;
3025 return (AS1 (swap,%0) CR_TAB
3026 AS1 (lsl,%0) CR_TAB
3027 AS1 (lsl,%0) CR_TAB
3028 AS2 (andi,%0,0xc0));
3030 *len = 6;
3031 return (AS1 (lsl,%0) CR_TAB
3032 AS1 (lsl,%0) CR_TAB
3033 AS1 (lsl,%0) CR_TAB
3034 AS1 (lsl,%0) CR_TAB
3035 AS1 (lsl,%0) CR_TAB
3036 AS1 (lsl,%0));
3038 case 7:
3039 *len = 3;
3040 return (AS1 (ror,%0) CR_TAB
3041 AS1 (clr,%0) CR_TAB
3042 AS1 (ror,%0));
3045 else if (CONSTANT_P (operands[2]))
3046 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3048 out_shift_with_cnt (AS1 (lsl,%0),
3049 insn, operands, len, 1);
3050 return "";
3054 /* 16bit shift left ((short)x << i) */
3056 const char *
3057 ashlhi3_out (rtx insn, rtx operands[], int *len)
3059 if (GET_CODE (operands[2]) == CONST_INT)
3061 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3062 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3063 int k;
3064 int *t = len;
3066 if (!len)
3067 len = &k;
3069 switch (INTVAL (operands[2]))
3071 default:
3072 if (INTVAL (operands[2]) < 16)
3073 break;
3075 *len = 2;
3076 return (AS1 (clr,%B0) CR_TAB
3077 AS1 (clr,%A0));
3079 case 4:
3080 if (optimize_size && scratch)
3081 break; /* 5 */
3082 if (ldi_ok)
3084 *len = 6;
3085 return (AS1 (swap,%A0) CR_TAB
3086 AS1 (swap,%B0) CR_TAB
3087 AS2 (andi,%B0,0xf0) CR_TAB
3088 AS2 (eor,%B0,%A0) CR_TAB
3089 AS2 (andi,%A0,0xf0) CR_TAB
3090 AS2 (eor,%B0,%A0));
3092 if (scratch)
3094 *len = 7;
3095 return (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; /* optimize_size ? 6 : 8 */
3105 case 5:
3106 if (optimize_size)
3107 break; /* scratch ? 5 : 6 */
3108 if (ldi_ok)
3110 *len = 8;
3111 return (AS1 (lsl,%A0) CR_TAB
3112 AS1 (rol,%B0) CR_TAB
3113 AS1 (swap,%A0) CR_TAB
3114 AS1 (swap,%B0) CR_TAB
3115 AS2 (andi,%B0,0xf0) CR_TAB
3116 AS2 (eor,%B0,%A0) CR_TAB
3117 AS2 (andi,%A0,0xf0) CR_TAB
3118 AS2 (eor,%B0,%A0));
3120 if (scratch)
3122 *len = 9;
3123 return (AS1 (lsl,%A0) CR_TAB
3124 AS1 (rol,%B0) CR_TAB
3125 AS1 (swap,%A0) CR_TAB
3126 AS1 (swap,%B0) CR_TAB
3127 AS2 (ldi,%3,0xf0) CR_TAB
3128 AS2 (and,%B0,%3) CR_TAB
3129 AS2 (eor,%B0,%A0) CR_TAB
3130 AS2 (and,%A0,%3) CR_TAB
3131 AS2 (eor,%B0,%A0));
3133 break; /* 10 */
3135 case 6:
3136 if (optimize_size)
3137 break; /* scratch ? 5 : 6 */
3138 *len = 9;
3139 return (AS1 (clr,__tmp_reg__) CR_TAB
3140 AS1 (lsr,%B0) CR_TAB
3141 AS1 (ror,%A0) CR_TAB
3142 AS1 (ror,__tmp_reg__) CR_TAB
3143 AS1 (lsr,%B0) CR_TAB
3144 AS1 (ror,%A0) CR_TAB
3145 AS1 (ror,__tmp_reg__) CR_TAB
3146 AS2 (mov,%B0,%A0) CR_TAB
3147 AS2 (mov,%A0,__tmp_reg__));
3149 case 7:
3150 *len = 5;
3151 return (AS1 (lsr,%B0) CR_TAB
3152 AS2 (mov,%B0,%A0) CR_TAB
3153 AS1 (clr,%A0) CR_TAB
3154 AS1 (ror,%B0) CR_TAB
3155 AS1 (ror,%A0));
3157 case 8:
3158 return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3159 AS1 (clr,%A0));
3161 case 9:
3162 *len = 3;
3163 return (AS2 (mov,%B0,%A0) CR_TAB
3164 AS1 (clr,%A0) CR_TAB
3165 AS1 (lsl,%B0));
3167 case 10:
3168 *len = 4;
3169 return (AS2 (mov,%B0,%A0) CR_TAB
3170 AS1 (clr,%A0) CR_TAB
3171 AS1 (lsl,%B0) CR_TAB
3172 AS1 (lsl,%B0));
3174 case 11:
3175 *len = 5;
3176 return (AS2 (mov,%B0,%A0) CR_TAB
3177 AS1 (clr,%A0) CR_TAB
3178 AS1 (lsl,%B0) CR_TAB
3179 AS1 (lsl,%B0) CR_TAB
3180 AS1 (lsl,%B0));
3182 case 12:
3183 if (ldi_ok)
3185 *len = 4;
3186 return (AS2 (mov,%B0,%A0) CR_TAB
3187 AS1 (clr,%A0) CR_TAB
3188 AS1 (swap,%B0) CR_TAB
3189 AS2 (andi,%B0,0xf0));
3191 if (scratch)
3193 *len = 5;
3194 return (AS2 (mov,%B0,%A0) CR_TAB
3195 AS1 (clr,%A0) CR_TAB
3196 AS1 (swap,%B0) CR_TAB
3197 AS2 (ldi,%3,0xf0) CR_TAB
3198 AS2 (and,%B0,%3));
3200 *len = 6;
3201 return (AS2 (mov,%B0,%A0) CR_TAB
3202 AS1 (clr,%A0) CR_TAB
3203 AS1 (lsl,%B0) CR_TAB
3204 AS1 (lsl,%B0) CR_TAB
3205 AS1 (lsl,%B0) CR_TAB
3206 AS1 (lsl,%B0));
3208 case 13:
3209 if (ldi_ok)
3211 *len = 5;
3212 return (AS2 (mov,%B0,%A0) CR_TAB
3213 AS1 (clr,%A0) CR_TAB
3214 AS1 (swap,%B0) CR_TAB
3215 AS1 (lsl,%B0) CR_TAB
3216 AS2 (andi,%B0,0xe0));
3218 if (AVR_HAVE_MUL && scratch)
3220 *len = 5;
3221 return (AS2 (ldi,%3,0x20) CR_TAB
3222 AS2 (mul,%A0,%3) CR_TAB
3223 AS2 (mov,%B0,r0) CR_TAB
3224 AS1 (clr,%A0) CR_TAB
3225 AS1 (clr,__zero_reg__));
3227 if (optimize_size && scratch)
3228 break; /* 5 */
3229 if (scratch)
3231 *len = 6;
3232 return (AS2 (mov,%B0,%A0) CR_TAB
3233 AS1 (clr,%A0) CR_TAB
3234 AS1 (swap,%B0) CR_TAB
3235 AS1 (lsl,%B0) CR_TAB
3236 AS2 (ldi,%3,0xe0) CR_TAB
3237 AS2 (and,%B0,%3));
3239 if (AVR_HAVE_MUL)
3241 *len = 6;
3242 return ("set" CR_TAB
3243 AS2 (bld,r1,5) CR_TAB
3244 AS2 (mul,%A0,r1) CR_TAB
3245 AS2 (mov,%B0,r0) CR_TAB
3246 AS1 (clr,%A0) CR_TAB
3247 AS1 (clr,__zero_reg__));
3249 *len = 7;
3250 return (AS2 (mov,%B0,%A0) CR_TAB
3251 AS1 (clr,%A0) CR_TAB
3252 AS1 (lsl,%B0) CR_TAB
3253 AS1 (lsl,%B0) CR_TAB
3254 AS1 (lsl,%B0) CR_TAB
3255 AS1 (lsl,%B0) CR_TAB
3256 AS1 (lsl,%B0));
3258 case 14:
3259 if (AVR_HAVE_MUL && ldi_ok)
3261 *len = 5;
3262 return (AS2 (ldi,%B0,0x40) CR_TAB
3263 AS2 (mul,%A0,%B0) CR_TAB
3264 AS2 (mov,%B0,r0) CR_TAB
3265 AS1 (clr,%A0) CR_TAB
3266 AS1 (clr,__zero_reg__));
3268 if (AVR_HAVE_MUL && scratch)
3270 *len = 5;
3271 return (AS2 (ldi,%3,0x40) CR_TAB
3272 AS2 (mul,%A0,%3) CR_TAB
3273 AS2 (mov,%B0,r0) CR_TAB
3274 AS1 (clr,%A0) CR_TAB
3275 AS1 (clr,__zero_reg__));
3277 if (optimize_size && ldi_ok)
3279 *len = 5;
3280 return (AS2 (mov,%B0,%A0) CR_TAB
3281 AS2 (ldi,%A0,6) "\n1:\t"
3282 AS1 (lsl,%B0) CR_TAB
3283 AS1 (dec,%A0) CR_TAB
3284 AS1 (brne,1b));
3286 if (optimize_size && scratch)
3287 break; /* 5 */
3288 *len = 6;
3289 return (AS1 (clr,%B0) CR_TAB
3290 AS1 (lsr,%A0) CR_TAB
3291 AS1 (ror,%B0) CR_TAB
3292 AS1 (lsr,%A0) CR_TAB
3293 AS1 (ror,%B0) CR_TAB
3294 AS1 (clr,%A0));
3296 case 15:
3297 *len = 4;
3298 return (AS1 (clr,%B0) CR_TAB
3299 AS1 (lsr,%A0) CR_TAB
3300 AS1 (ror,%B0) CR_TAB
3301 AS1 (clr,%A0));
3303 len = t;
3305 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3306 AS1 (rol,%B0)),
3307 insn, operands, len, 2);
3308 return "";
3312 /* 32bit shift left ((long)x << i) */
3314 const char *
3315 ashlsi3_out (rtx insn, rtx operands[], int *len)
3317 if (GET_CODE (operands[2]) == CONST_INT)
3319 int k;
3320 int *t = len;
3322 if (!len)
3323 len = &k;
3325 switch (INTVAL (operands[2]))
3327 default:
3328 if (INTVAL (operands[2]) < 32)
3329 break;
3331 if (AVR_HAVE_MOVW)
3332 return *len = 3, (AS1 (clr,%D0) CR_TAB
3333 AS1 (clr,%C0) CR_TAB
3334 AS2 (movw,%A0,%C0));
3335 *len = 4;
3336 return (AS1 (clr,%D0) CR_TAB
3337 AS1 (clr,%C0) CR_TAB
3338 AS1 (clr,%B0) CR_TAB
3339 AS1 (clr,%A0));
3341 case 8:
3343 int reg0 = true_regnum (operands[0]);
3344 int reg1 = true_regnum (operands[1]);
3345 *len = 4;
3346 if (reg0 >= reg1)
3347 return (AS2 (mov,%D0,%C1) CR_TAB
3348 AS2 (mov,%C0,%B1) CR_TAB
3349 AS2 (mov,%B0,%A1) CR_TAB
3350 AS1 (clr,%A0));
3351 else
3352 return (AS1 (clr,%A0) CR_TAB
3353 AS2 (mov,%B0,%A1) CR_TAB
3354 AS2 (mov,%C0,%B1) CR_TAB
3355 AS2 (mov,%D0,%C1));
3358 case 16:
3360 int reg0 = true_regnum (operands[0]);
3361 int reg1 = true_regnum (operands[1]);
3362 if (reg0 + 2 == reg1)
3363 return *len = 2, (AS1 (clr,%B0) CR_TAB
3364 AS1 (clr,%A0));
3365 if (AVR_HAVE_MOVW)
3366 return *len = 3, (AS2 (movw,%C0,%A1) CR_TAB
3367 AS1 (clr,%B0) CR_TAB
3368 AS1 (clr,%A0));
3369 else
3370 return *len = 4, (AS2 (mov,%C0,%A1) CR_TAB
3371 AS2 (mov,%D0,%B1) CR_TAB
3372 AS1 (clr,%B0) CR_TAB
3373 AS1 (clr,%A0));
3376 case 24:
3377 *len = 4;
3378 return (AS2 (mov,%D0,%A1) CR_TAB
3379 AS1 (clr,%C0) CR_TAB
3380 AS1 (clr,%B0) CR_TAB
3381 AS1 (clr,%A0));
3383 case 31:
3384 *len = 6;
3385 return (AS1 (clr,%D0) CR_TAB
3386 AS1 (lsr,%A0) CR_TAB
3387 AS1 (ror,%D0) CR_TAB
3388 AS1 (clr,%C0) CR_TAB
3389 AS1 (clr,%B0) CR_TAB
3390 AS1 (clr,%A0));
3392 len = t;
3394 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3395 AS1 (rol,%B0) CR_TAB
3396 AS1 (rol,%C0) CR_TAB
3397 AS1 (rol,%D0)),
3398 insn, operands, len, 4);
3399 return "";
3402 /* 8bit arithmetic shift right ((signed char)x >> i) */
3404 const char *
3405 ashrqi3_out (rtx insn, rtx operands[], int *len)
3407 if (GET_CODE (operands[2]) == CONST_INT)
3409 int k;
3411 if (!len)
3412 len = &k;
3414 switch (INTVAL (operands[2]))
3416 case 1:
3417 *len = 1;
3418 return AS1 (asr,%0);
3420 case 2:
3421 *len = 2;
3422 return (AS1 (asr,%0) CR_TAB
3423 AS1 (asr,%0));
3425 case 3:
3426 *len = 3;
3427 return (AS1 (asr,%0) CR_TAB
3428 AS1 (asr,%0) CR_TAB
3429 AS1 (asr,%0));
3431 case 4:
3432 *len = 4;
3433 return (AS1 (asr,%0) CR_TAB
3434 AS1 (asr,%0) CR_TAB
3435 AS1 (asr,%0) CR_TAB
3436 AS1 (asr,%0));
3438 case 5:
3439 *len = 5;
3440 return (AS1 (asr,%0) CR_TAB
3441 AS1 (asr,%0) CR_TAB
3442 AS1 (asr,%0) CR_TAB
3443 AS1 (asr,%0) CR_TAB
3444 AS1 (asr,%0));
3446 case 6:
3447 *len = 4;
3448 return (AS2 (bst,%0,6) CR_TAB
3449 AS1 (lsl,%0) CR_TAB
3450 AS2 (sbc,%0,%0) CR_TAB
3451 AS2 (bld,%0,0));
3453 default:
3454 if (INTVAL (operands[2]) < 8)
3455 break;
3457 /* fall through */
3459 case 7:
3460 *len = 2;
3461 return (AS1 (lsl,%0) CR_TAB
3462 AS2 (sbc,%0,%0));
3465 else if (CONSTANT_P (operands[2]))
3466 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3468 out_shift_with_cnt (AS1 (asr,%0),
3469 insn, operands, len, 1);
3470 return "";
3474 /* 16bit arithmetic shift right ((signed short)x >> i) */
3476 const char *
3477 ashrhi3_out (rtx insn, rtx operands[], int *len)
3479 if (GET_CODE (operands[2]) == CONST_INT)
3481 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3482 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3483 int k;
3484 int *t = len;
3486 if (!len)
3487 len = &k;
3489 switch (INTVAL (operands[2]))
3491 case 4:
3492 case 5:
3493 /* XXX try to optimize this too? */
3494 break;
3496 case 6:
3497 if (optimize_size)
3498 break; /* scratch ? 5 : 6 */
3499 *len = 8;
3500 return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3501 AS2 (mov,%A0,%B0) CR_TAB
3502 AS1 (lsl,__tmp_reg__) CR_TAB
3503 AS1 (rol,%A0) CR_TAB
3504 AS2 (sbc,%B0,%B0) CR_TAB
3505 AS1 (lsl,__tmp_reg__) CR_TAB
3506 AS1 (rol,%A0) CR_TAB
3507 AS1 (rol,%B0));
3509 case 7:
3510 *len = 4;
3511 return (AS1 (lsl,%A0) CR_TAB
3512 AS2 (mov,%A0,%B0) CR_TAB
3513 AS1 (rol,%A0) CR_TAB
3514 AS2 (sbc,%B0,%B0));
3516 case 8:
3518 int reg0 = true_regnum (operands[0]);
3519 int reg1 = true_regnum (operands[1]);
3521 if (reg0 == reg1)
3522 return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3523 AS1 (lsl,%B0) CR_TAB
3524 AS2 (sbc,%B0,%B0));
3525 else
3526 return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3527 AS1 (clr,%B0) CR_TAB
3528 AS2 (sbrc,%A0,7) CR_TAB
3529 AS1 (dec,%B0));
3532 case 9:
3533 *len = 4;
3534 return (AS2 (mov,%A0,%B0) CR_TAB
3535 AS1 (lsl,%B0) CR_TAB
3536 AS2 (sbc,%B0,%B0) CR_TAB
3537 AS1 (asr,%A0));
3539 case 10:
3540 *len = 5;
3541 return (AS2 (mov,%A0,%B0) CR_TAB
3542 AS1 (lsl,%B0) CR_TAB
3543 AS2 (sbc,%B0,%B0) CR_TAB
3544 AS1 (asr,%A0) CR_TAB
3545 AS1 (asr,%A0));
3547 case 11:
3548 if (AVR_HAVE_MUL && ldi_ok)
3550 *len = 5;
3551 return (AS2 (ldi,%A0,0x20) CR_TAB
3552 AS2 (muls,%B0,%A0) CR_TAB
3553 AS2 (mov,%A0,r1) CR_TAB
3554 AS2 (sbc,%B0,%B0) CR_TAB
3555 AS1 (clr,__zero_reg__));
3557 if (optimize_size && scratch)
3558 break; /* 5 */
3559 *len = 6;
3560 return (AS2 (mov,%A0,%B0) CR_TAB
3561 AS1 (lsl,%B0) CR_TAB
3562 AS2 (sbc,%B0,%B0) CR_TAB
3563 AS1 (asr,%A0) CR_TAB
3564 AS1 (asr,%A0) CR_TAB
3565 AS1 (asr,%A0));
3567 case 12:
3568 if (AVR_HAVE_MUL && ldi_ok)
3570 *len = 5;
3571 return (AS2 (ldi,%A0,0x10) CR_TAB
3572 AS2 (muls,%B0,%A0) CR_TAB
3573 AS2 (mov,%A0,r1) CR_TAB
3574 AS2 (sbc,%B0,%B0) CR_TAB
3575 AS1 (clr,__zero_reg__));
3577 if (optimize_size && scratch)
3578 break; /* 5 */
3579 *len = 7;
3580 return (AS2 (mov,%A0,%B0) CR_TAB
3581 AS1 (lsl,%B0) CR_TAB
3582 AS2 (sbc,%B0,%B0) CR_TAB
3583 AS1 (asr,%A0) CR_TAB
3584 AS1 (asr,%A0) CR_TAB
3585 AS1 (asr,%A0) CR_TAB
3586 AS1 (asr,%A0));
3588 case 13:
3589 if (AVR_HAVE_MUL && ldi_ok)
3591 *len = 5;
3592 return (AS2 (ldi,%A0,0x08) CR_TAB
3593 AS2 (muls,%B0,%A0) CR_TAB
3594 AS2 (mov,%A0,r1) CR_TAB
3595 AS2 (sbc,%B0,%B0) CR_TAB
3596 AS1 (clr,__zero_reg__));
3598 if (optimize_size)
3599 break; /* scratch ? 5 : 7 */
3600 *len = 8;
3601 return (AS2 (mov,%A0,%B0) CR_TAB
3602 AS1 (lsl,%B0) CR_TAB
3603 AS2 (sbc,%B0,%B0) CR_TAB
3604 AS1 (asr,%A0) CR_TAB
3605 AS1 (asr,%A0) CR_TAB
3606 AS1 (asr,%A0) CR_TAB
3607 AS1 (asr,%A0) CR_TAB
3608 AS1 (asr,%A0));
3610 case 14:
3611 *len = 5;
3612 return (AS1 (lsl,%B0) CR_TAB
3613 AS2 (sbc,%A0,%A0) CR_TAB
3614 AS1 (lsl,%B0) CR_TAB
3615 AS2 (mov,%B0,%A0) CR_TAB
3616 AS1 (rol,%A0));
3618 default:
3619 if (INTVAL (operands[2]) < 16)
3620 break;
3622 /* fall through */
3624 case 15:
3625 return *len = 3, (AS1 (lsl,%B0) CR_TAB
3626 AS2 (sbc,%A0,%A0) CR_TAB
3627 AS2 (mov,%B0,%A0));
3629 len = t;
3631 out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3632 AS1 (ror,%A0)),
3633 insn, operands, len, 2);
3634 return "";
3638 /* 32bit arithmetic shift right ((signed long)x >> i) */
3640 const char *
3641 ashrsi3_out (rtx insn, rtx operands[], int *len)
3643 if (GET_CODE (operands[2]) == CONST_INT)
3645 int k;
3646 int *t = len;
3648 if (!len)
3649 len = &k;
3651 switch (INTVAL (operands[2]))
3653 case 8:
3655 int reg0 = true_regnum (operands[0]);
3656 int reg1 = true_regnum (operands[1]);
3657 *len=6;
3658 if (reg0 <= reg1)
3659 return (AS2 (mov,%A0,%B1) CR_TAB
3660 AS2 (mov,%B0,%C1) CR_TAB
3661 AS2 (mov,%C0,%D1) CR_TAB
3662 AS1 (clr,%D0) CR_TAB
3663 AS2 (sbrc,%C0,7) CR_TAB
3664 AS1 (dec,%D0));
3665 else
3666 return (AS1 (clr,%D0) CR_TAB
3667 AS2 (sbrc,%D1,7) CR_TAB
3668 AS1 (dec,%D0) CR_TAB
3669 AS2 (mov,%C0,%D1) CR_TAB
3670 AS2 (mov,%B0,%C1) CR_TAB
3671 AS2 (mov,%A0,%B1));
3674 case 16:
3676 int reg0 = true_regnum (operands[0]);
3677 int reg1 = true_regnum (operands[1]);
3679 if (reg0 == reg1 + 2)
3680 return *len = 4, (AS1 (clr,%D0) CR_TAB
3681 AS2 (sbrc,%B0,7) CR_TAB
3682 AS1 (com,%D0) CR_TAB
3683 AS2 (mov,%C0,%D0));
3684 if (AVR_HAVE_MOVW)
3685 return *len = 5, (AS2 (movw,%A0,%C1) CR_TAB
3686 AS1 (clr,%D0) CR_TAB
3687 AS2 (sbrc,%B0,7) CR_TAB
3688 AS1 (com,%D0) CR_TAB
3689 AS2 (mov,%C0,%D0));
3690 else
3691 return *len = 6, (AS2 (mov,%B0,%D1) CR_TAB
3692 AS2 (mov,%A0,%C1) CR_TAB
3693 AS1 (clr,%D0) CR_TAB
3694 AS2 (sbrc,%B0,7) CR_TAB
3695 AS1 (com,%D0) CR_TAB
3696 AS2 (mov,%C0,%D0));
3699 case 24:
3700 return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3701 AS1 (clr,%D0) CR_TAB
3702 AS2 (sbrc,%A0,7) CR_TAB
3703 AS1 (com,%D0) CR_TAB
3704 AS2 (mov,%B0,%D0) CR_TAB
3705 AS2 (mov,%C0,%D0));
3707 default:
3708 if (INTVAL (operands[2]) < 32)
3709 break;
3711 /* fall through */
3713 case 31:
3714 if (AVR_HAVE_MOVW)
3715 return *len = 4, (AS1 (lsl,%D0) CR_TAB
3716 AS2 (sbc,%A0,%A0) CR_TAB
3717 AS2 (mov,%B0,%A0) CR_TAB
3718 AS2 (movw,%C0,%A0));
3719 else
3720 return *len = 5, (AS1 (lsl,%D0) CR_TAB
3721 AS2 (sbc,%A0,%A0) CR_TAB
3722 AS2 (mov,%B0,%A0) CR_TAB
3723 AS2 (mov,%C0,%A0) CR_TAB
3724 AS2 (mov,%D0,%A0));
3726 len = t;
3728 out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
3729 AS1 (ror,%C0) CR_TAB
3730 AS1 (ror,%B0) CR_TAB
3731 AS1 (ror,%A0)),
3732 insn, operands, len, 4);
3733 return "";
3736 /* 8bit logic shift right ((unsigned char)x >> i) */
3738 const char *
3739 lshrqi3_out (rtx insn, rtx operands[], int *len)
3741 if (GET_CODE (operands[2]) == CONST_INT)
3743 int k;
3745 if (!len)
3746 len = &k;
3748 switch (INTVAL (operands[2]))
3750 default:
3751 if (INTVAL (operands[2]) < 8)
3752 break;
3754 *len = 1;
3755 return AS1 (clr,%0);
3757 case 1:
3758 *len = 1;
3759 return AS1 (lsr,%0);
3761 case 2:
3762 *len = 2;
3763 return (AS1 (lsr,%0) CR_TAB
3764 AS1 (lsr,%0));
3765 case 3:
3766 *len = 3;
3767 return (AS1 (lsr,%0) CR_TAB
3768 AS1 (lsr,%0) CR_TAB
3769 AS1 (lsr,%0));
3771 case 4:
3772 if (test_hard_reg_class (LD_REGS, operands[0]))
3774 *len=2;
3775 return (AS1 (swap,%0) CR_TAB
3776 AS2 (andi,%0,0x0f));
3778 *len = 4;
3779 return (AS1 (lsr,%0) CR_TAB
3780 AS1 (lsr,%0) CR_TAB
3781 AS1 (lsr,%0) CR_TAB
3782 AS1 (lsr,%0));
3784 case 5:
3785 if (test_hard_reg_class (LD_REGS, operands[0]))
3787 *len = 3;
3788 return (AS1 (swap,%0) CR_TAB
3789 AS1 (lsr,%0) CR_TAB
3790 AS2 (andi,%0,0x7));
3792 *len = 5;
3793 return (AS1 (lsr,%0) CR_TAB
3794 AS1 (lsr,%0) CR_TAB
3795 AS1 (lsr,%0) CR_TAB
3796 AS1 (lsr,%0) CR_TAB
3797 AS1 (lsr,%0));
3799 case 6:
3800 if (test_hard_reg_class (LD_REGS, operands[0]))
3802 *len = 4;
3803 return (AS1 (swap,%0) CR_TAB
3804 AS1 (lsr,%0) CR_TAB
3805 AS1 (lsr,%0) CR_TAB
3806 AS2 (andi,%0,0x3));
3808 *len = 6;
3809 return (AS1 (lsr,%0) CR_TAB
3810 AS1 (lsr,%0) CR_TAB
3811 AS1 (lsr,%0) CR_TAB
3812 AS1 (lsr,%0) CR_TAB
3813 AS1 (lsr,%0) CR_TAB
3814 AS1 (lsr,%0));
3816 case 7:
3817 *len = 3;
3818 return (AS1 (rol,%0) CR_TAB
3819 AS1 (clr,%0) CR_TAB
3820 AS1 (rol,%0));
3823 else if (CONSTANT_P (operands[2]))
3824 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3826 out_shift_with_cnt (AS1 (lsr,%0),
3827 insn, operands, len, 1);
3828 return "";
3831 /* 16bit logic shift right ((unsigned short)x >> i) */
3833 const char *
3834 lshrhi3_out (rtx insn, rtx operands[], int *len)
3836 if (GET_CODE (operands[2]) == CONST_INT)
3838 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3839 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3840 int k;
3841 int *t = len;
3843 if (!len)
3844 len = &k;
3846 switch (INTVAL (operands[2]))
3848 default:
3849 if (INTVAL (operands[2]) < 16)
3850 break;
3852 *len = 2;
3853 return (AS1 (clr,%B0) CR_TAB
3854 AS1 (clr,%A0));
3856 case 4:
3857 if (optimize_size && scratch)
3858 break; /* 5 */
3859 if (ldi_ok)
3861 *len = 6;
3862 return (AS1 (swap,%B0) CR_TAB
3863 AS1 (swap,%A0) CR_TAB
3864 AS2 (andi,%A0,0x0f) CR_TAB
3865 AS2 (eor,%A0,%B0) CR_TAB
3866 AS2 (andi,%B0,0x0f) CR_TAB
3867 AS2 (eor,%A0,%B0));
3869 if (scratch)
3871 *len = 7;
3872 return (AS1 (swap,%B0) CR_TAB
3873 AS1 (swap,%A0) CR_TAB
3874 AS2 (ldi,%3,0x0f) CR_TAB
3875 AS2 (and,%A0,%3) CR_TAB
3876 AS2 (eor,%A0,%B0) CR_TAB
3877 AS2 (and,%B0,%3) CR_TAB
3878 AS2 (eor,%A0,%B0));
3880 break; /* optimize_size ? 6 : 8 */
3882 case 5:
3883 if (optimize_size)
3884 break; /* scratch ? 5 : 6 */
3885 if (ldi_ok)
3887 *len = 8;
3888 return (AS1 (lsr,%B0) CR_TAB
3889 AS1 (ror,%A0) CR_TAB
3890 AS1 (swap,%B0) CR_TAB
3891 AS1 (swap,%A0) CR_TAB
3892 AS2 (andi,%A0,0x0f) CR_TAB
3893 AS2 (eor,%A0,%B0) CR_TAB
3894 AS2 (andi,%B0,0x0f) CR_TAB
3895 AS2 (eor,%A0,%B0));
3897 if (scratch)
3899 *len = 9;
3900 return (AS1 (lsr,%B0) CR_TAB
3901 AS1 (ror,%A0) CR_TAB
3902 AS1 (swap,%B0) CR_TAB
3903 AS1 (swap,%A0) CR_TAB
3904 AS2 (ldi,%3,0x0f) CR_TAB
3905 AS2 (and,%A0,%3) CR_TAB
3906 AS2 (eor,%A0,%B0) CR_TAB
3907 AS2 (and,%B0,%3) CR_TAB
3908 AS2 (eor,%A0,%B0));
3910 break; /* 10 */
3912 case 6:
3913 if (optimize_size)
3914 break; /* scratch ? 5 : 6 */
3915 *len = 9;
3916 return (AS1 (clr,__tmp_reg__) CR_TAB
3917 AS1 (lsl,%A0) CR_TAB
3918 AS1 (rol,%B0) CR_TAB
3919 AS1 (rol,__tmp_reg__) CR_TAB
3920 AS1 (lsl,%A0) CR_TAB
3921 AS1 (rol,%B0) CR_TAB
3922 AS1 (rol,__tmp_reg__) CR_TAB
3923 AS2 (mov,%A0,%B0) CR_TAB
3924 AS2 (mov,%B0,__tmp_reg__));
3926 case 7:
3927 *len = 5;
3928 return (AS1 (lsl,%A0) CR_TAB
3929 AS2 (mov,%A0,%B0) CR_TAB
3930 AS1 (rol,%A0) CR_TAB
3931 AS2 (sbc,%B0,%B0) CR_TAB
3932 AS1 (neg,%B0));
3934 case 8:
3935 return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
3936 AS1 (clr,%B0));
3938 case 9:
3939 *len = 3;
3940 return (AS2 (mov,%A0,%B0) CR_TAB
3941 AS1 (clr,%B0) CR_TAB
3942 AS1 (lsr,%A0));
3944 case 10:
3945 *len = 4;
3946 return (AS2 (mov,%A0,%B0) CR_TAB
3947 AS1 (clr,%B0) CR_TAB
3948 AS1 (lsr,%A0) CR_TAB
3949 AS1 (lsr,%A0));
3951 case 11:
3952 *len = 5;
3953 return (AS2 (mov,%A0,%B0) CR_TAB
3954 AS1 (clr,%B0) CR_TAB
3955 AS1 (lsr,%A0) CR_TAB
3956 AS1 (lsr,%A0) CR_TAB
3957 AS1 (lsr,%A0));
3959 case 12:
3960 if (ldi_ok)
3962 *len = 4;
3963 return (AS2 (mov,%A0,%B0) CR_TAB
3964 AS1 (clr,%B0) CR_TAB
3965 AS1 (swap,%A0) CR_TAB
3966 AS2 (andi,%A0,0x0f));
3968 if (scratch)
3970 *len = 5;
3971 return (AS2 (mov,%A0,%B0) CR_TAB
3972 AS1 (clr,%B0) CR_TAB
3973 AS1 (swap,%A0) CR_TAB
3974 AS2 (ldi,%3,0x0f) CR_TAB
3975 AS2 (and,%A0,%3));
3977 *len = 6;
3978 return (AS2 (mov,%A0,%B0) CR_TAB
3979 AS1 (clr,%B0) CR_TAB
3980 AS1 (lsr,%A0) CR_TAB
3981 AS1 (lsr,%A0) CR_TAB
3982 AS1 (lsr,%A0) CR_TAB
3983 AS1 (lsr,%A0));
3985 case 13:
3986 if (ldi_ok)
3988 *len = 5;
3989 return (AS2 (mov,%A0,%B0) CR_TAB
3990 AS1 (clr,%B0) CR_TAB
3991 AS1 (swap,%A0) CR_TAB
3992 AS1 (lsr,%A0) CR_TAB
3993 AS2 (andi,%A0,0x07));
3995 if (AVR_HAVE_MUL && scratch)
3997 *len = 5;
3998 return (AS2 (ldi,%3,0x08) CR_TAB
3999 AS2 (mul,%B0,%3) CR_TAB
4000 AS2 (mov,%A0,r1) CR_TAB
4001 AS1 (clr,%B0) CR_TAB
4002 AS1 (clr,__zero_reg__));
4004 if (optimize_size && scratch)
4005 break; /* 5 */
4006 if (scratch)
4008 *len = 6;
4009 return (AS2 (mov,%A0,%B0) CR_TAB
4010 AS1 (clr,%B0) CR_TAB
4011 AS1 (swap,%A0) CR_TAB
4012 AS1 (lsr,%A0) CR_TAB
4013 AS2 (ldi,%3,0x07) CR_TAB
4014 AS2 (and,%A0,%3));
4016 if (AVR_HAVE_MUL)
4018 *len = 6;
4019 return ("set" CR_TAB
4020 AS2 (bld,r1,3) CR_TAB
4021 AS2 (mul,%B0,r1) CR_TAB
4022 AS2 (mov,%A0,r1) CR_TAB
4023 AS1 (clr,%B0) CR_TAB
4024 AS1 (clr,__zero_reg__));
4026 *len = 7;
4027 return (AS2 (mov,%A0,%B0) CR_TAB
4028 AS1 (clr,%B0) CR_TAB
4029 AS1 (lsr,%A0) CR_TAB
4030 AS1 (lsr,%A0) CR_TAB
4031 AS1 (lsr,%A0) CR_TAB
4032 AS1 (lsr,%A0) CR_TAB
4033 AS1 (lsr,%A0));
4035 case 14:
4036 if (AVR_HAVE_MUL && ldi_ok)
4038 *len = 5;
4039 return (AS2 (ldi,%A0,0x04) CR_TAB
4040 AS2 (mul,%B0,%A0) CR_TAB
4041 AS2 (mov,%A0,r1) CR_TAB
4042 AS1 (clr,%B0) CR_TAB
4043 AS1 (clr,__zero_reg__));
4045 if (AVR_HAVE_MUL && scratch)
4047 *len = 5;
4048 return (AS2 (ldi,%3,0x04) CR_TAB
4049 AS2 (mul,%B0,%3) CR_TAB
4050 AS2 (mov,%A0,r1) CR_TAB
4051 AS1 (clr,%B0) CR_TAB
4052 AS1 (clr,__zero_reg__));
4054 if (optimize_size && ldi_ok)
4056 *len = 5;
4057 return (AS2 (mov,%A0,%B0) CR_TAB
4058 AS2 (ldi,%B0,6) "\n1:\t"
4059 AS1 (lsr,%A0) CR_TAB
4060 AS1 (dec,%B0) CR_TAB
4061 AS1 (brne,1b));
4063 if (optimize_size && scratch)
4064 break; /* 5 */
4065 *len = 6;
4066 return (AS1 (clr,%A0) CR_TAB
4067 AS1 (lsl,%B0) CR_TAB
4068 AS1 (rol,%A0) CR_TAB
4069 AS1 (lsl,%B0) CR_TAB
4070 AS1 (rol,%A0) CR_TAB
4071 AS1 (clr,%B0));
4073 case 15:
4074 *len = 4;
4075 return (AS1 (clr,%A0) CR_TAB
4076 AS1 (lsl,%B0) CR_TAB
4077 AS1 (rol,%A0) CR_TAB
4078 AS1 (clr,%B0));
4080 len = t;
4082 out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
4083 AS1 (ror,%A0)),
4084 insn, operands, len, 2);
4085 return "";
4088 /* 32bit logic shift right ((unsigned int)x >> i) */
4090 const char *
4091 lshrsi3_out (rtx insn, rtx operands[], int *len)
4093 if (GET_CODE (operands[2]) == CONST_INT)
4095 int k;
4096 int *t = len;
4098 if (!len)
4099 len = &k;
4101 switch (INTVAL (operands[2]))
4103 default:
4104 if (INTVAL (operands[2]) < 32)
4105 break;
4107 if (AVR_HAVE_MOVW)
4108 return *len = 3, (AS1 (clr,%D0) CR_TAB
4109 AS1 (clr,%C0) CR_TAB
4110 AS2 (movw,%A0,%C0));
4111 *len = 4;
4112 return (AS1 (clr,%D0) CR_TAB
4113 AS1 (clr,%C0) CR_TAB
4114 AS1 (clr,%B0) CR_TAB
4115 AS1 (clr,%A0));
4117 case 8:
4119 int reg0 = true_regnum (operands[0]);
4120 int reg1 = true_regnum (operands[1]);
4121 *len = 4;
4122 if (reg0 <= reg1)
4123 return (AS2 (mov,%A0,%B1) CR_TAB
4124 AS2 (mov,%B0,%C1) CR_TAB
4125 AS2 (mov,%C0,%D1) CR_TAB
4126 AS1 (clr,%D0));
4127 else
4128 return (AS1 (clr,%D0) CR_TAB
4129 AS2 (mov,%C0,%D1) CR_TAB
4130 AS2 (mov,%B0,%C1) CR_TAB
4131 AS2 (mov,%A0,%B1));
4134 case 16:
4136 int reg0 = true_regnum (operands[0]);
4137 int reg1 = true_regnum (operands[1]);
4139 if (reg0 == reg1 + 2)
4140 return *len = 2, (AS1 (clr,%C0) CR_TAB
4141 AS1 (clr,%D0));
4142 if (AVR_HAVE_MOVW)
4143 return *len = 3, (AS2 (movw,%A0,%C1) CR_TAB
4144 AS1 (clr,%C0) CR_TAB
4145 AS1 (clr,%D0));
4146 else
4147 return *len = 4, (AS2 (mov,%B0,%D1) CR_TAB
4148 AS2 (mov,%A0,%C1) CR_TAB
4149 AS1 (clr,%C0) CR_TAB
4150 AS1 (clr,%D0));
4153 case 24:
4154 return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4155 AS1 (clr,%B0) CR_TAB
4156 AS1 (clr,%C0) CR_TAB
4157 AS1 (clr,%D0));
4159 case 31:
4160 *len = 6;
4161 return (AS1 (clr,%A0) CR_TAB
4162 AS2 (sbrc,%D0,7) CR_TAB
4163 AS1 (inc,%A0) CR_TAB
4164 AS1 (clr,%B0) CR_TAB
4165 AS1 (clr,%C0) CR_TAB
4166 AS1 (clr,%D0));
4168 len = t;
4170 out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4171 AS1 (ror,%C0) CR_TAB
4172 AS1 (ror,%B0) CR_TAB
4173 AS1 (ror,%A0)),
4174 insn, operands, len, 4);
4175 return "";
4178 /* Modifies the length assigned to instruction INSN
4179 LEN is the initially computed length of the insn. */
4182 adjust_insn_length (rtx insn, int len)
4184 rtx patt = PATTERN (insn);
4185 rtx set;
4187 if (GET_CODE (patt) == SET)
4189 rtx op[10];
4190 op[1] = SET_SRC (patt);
4191 op[0] = SET_DEST (patt);
4192 if (general_operand (op[1], VOIDmode)
4193 && general_operand (op[0], VOIDmode))
4195 switch (GET_MODE (op[0]))
4197 case QImode:
4198 output_movqi (insn, op, &len);
4199 break;
4200 case HImode:
4201 output_movhi (insn, op, &len);
4202 break;
4203 case SImode:
4204 case SFmode:
4205 output_movsisf (insn, op, &len);
4206 break;
4207 default:
4208 break;
4211 else if (op[0] == cc0_rtx && REG_P (op[1]))
4213 switch (GET_MODE (op[1]))
4215 case HImode: out_tsthi (insn,&len); break;
4216 case SImode: out_tstsi (insn,&len); break;
4217 default: break;
4220 else if (GET_CODE (op[1]) == AND)
4222 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4224 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4225 if (GET_MODE (op[1]) == SImode)
4226 len = (((mask & 0xff) != 0xff)
4227 + ((mask & 0xff00) != 0xff00)
4228 + ((mask & 0xff0000L) != 0xff0000L)
4229 + ((mask & 0xff000000L) != 0xff000000L));
4230 else if (GET_MODE (op[1]) == HImode)
4231 len = (((mask & 0xff) != 0xff)
4232 + ((mask & 0xff00) != 0xff00));
4235 else if (GET_CODE (op[1]) == IOR)
4237 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4239 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4240 if (GET_MODE (op[1]) == SImode)
4241 len = (((mask & 0xff) != 0)
4242 + ((mask & 0xff00) != 0)
4243 + ((mask & 0xff0000L) != 0)
4244 + ((mask & 0xff000000L) != 0));
4245 else if (GET_MODE (op[1]) == HImode)
4246 len = (((mask & 0xff) != 0)
4247 + ((mask & 0xff00) != 0));
4251 set = single_set (insn);
4252 if (set)
4254 rtx op[10];
4256 op[1] = SET_SRC (set);
4257 op[0] = SET_DEST (set);
4259 if (GET_CODE (patt) == PARALLEL
4260 && general_operand (op[1], VOIDmode)
4261 && general_operand (op[0], VOIDmode))
4263 if (XVECLEN (patt, 0) == 2)
4264 op[2] = XVECEXP (patt, 0, 1);
4266 switch (GET_MODE (op[0]))
4268 case QImode:
4269 len = 2;
4270 break;
4271 case HImode:
4272 output_reload_inhi (insn, op, &len);
4273 break;
4274 case SImode:
4275 case SFmode:
4276 output_reload_insisf (insn, op, &len);
4277 break;
4278 default:
4279 break;
4282 else if (GET_CODE (op[1]) == ASHIFT
4283 || GET_CODE (op[1]) == ASHIFTRT
4284 || GET_CODE (op[1]) == LSHIFTRT)
4286 rtx ops[10];
4287 ops[0] = op[0];
4288 ops[1] = XEXP (op[1],0);
4289 ops[2] = XEXP (op[1],1);
4290 switch (GET_CODE (op[1]))
4292 case ASHIFT:
4293 switch (GET_MODE (op[0]))
4295 case QImode: ashlqi3_out (insn,ops,&len); break;
4296 case HImode: ashlhi3_out (insn,ops,&len); break;
4297 case SImode: ashlsi3_out (insn,ops,&len); break;
4298 default: break;
4300 break;
4301 case ASHIFTRT:
4302 switch (GET_MODE (op[0]))
4304 case QImode: ashrqi3_out (insn,ops,&len); break;
4305 case HImode: ashrhi3_out (insn,ops,&len); break;
4306 case SImode: ashrsi3_out (insn,ops,&len); break;
4307 default: break;
4309 break;
4310 case LSHIFTRT:
4311 switch (GET_MODE (op[0]))
4313 case QImode: lshrqi3_out (insn,ops,&len); break;
4314 case HImode: lshrhi3_out (insn,ops,&len); break;
4315 case SImode: lshrsi3_out (insn,ops,&len); break;
4316 default: break;
4318 break;
4319 default:
4320 break;
4324 return len;
4327 /* Return nonzero if register REG dead after INSN. */
4330 reg_unused_after (rtx insn, rtx reg)
4332 return (dead_or_set_p (insn, reg)
4333 || (REG_P(reg) && _reg_unused_after (insn, reg)));
4336 /* Return nonzero if REG is not used after INSN.
4337 We assume REG is a reload reg, and therefore does
4338 not live past labels. It may live past calls or jumps though. */
4341 _reg_unused_after (rtx insn, rtx reg)
4343 enum rtx_code code;
4344 rtx set;
4346 /* If the reg is set by this instruction, then it is safe for our
4347 case. Disregard the case where this is a store to memory, since
4348 we are checking a register used in the store address. */
4349 set = single_set (insn);
4350 if (set && GET_CODE (SET_DEST (set)) != MEM
4351 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4352 return 1;
4354 while ((insn = NEXT_INSN (insn)))
4356 rtx set;
4357 code = GET_CODE (insn);
4359 #if 0
4360 /* If this is a label that existed before reload, then the register
4361 if dead here. However, if this is a label added by reorg, then
4362 the register may still be live here. We can't tell the difference,
4363 so we just ignore labels completely. */
4364 if (code == CODE_LABEL)
4365 return 1;
4366 /* else */
4367 #endif
4369 if (!INSN_P (insn))
4370 continue;
4372 if (code == JUMP_INSN)
4373 return 0;
4375 /* If this is a sequence, we must handle them all at once.
4376 We could have for instance a call that sets the target register,
4377 and an insn in a delay slot that uses the register. In this case,
4378 we must return 0. */
4379 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
4381 int i;
4382 int retval = 0;
4384 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
4386 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
4387 rtx set = single_set (this_insn);
4389 if (GET_CODE (this_insn) == CALL_INSN)
4390 code = CALL_INSN;
4391 else if (GET_CODE (this_insn) == JUMP_INSN)
4393 if (INSN_ANNULLED_BRANCH_P (this_insn))
4394 return 0;
4395 code = JUMP_INSN;
4398 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4399 return 0;
4400 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4402 if (GET_CODE (SET_DEST (set)) != MEM)
4403 retval = 1;
4404 else
4405 return 0;
4407 if (set == 0
4408 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
4409 return 0;
4411 if (retval == 1)
4412 return 1;
4413 else if (code == JUMP_INSN)
4414 return 0;
4417 if (code == CALL_INSN)
4419 rtx tem;
4420 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4421 if (GET_CODE (XEXP (tem, 0)) == USE
4422 && REG_P (XEXP (XEXP (tem, 0), 0))
4423 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
4424 return 0;
4425 if (call_used_regs[REGNO (reg)])
4426 return 1;
4429 set = single_set (insn);
4431 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4432 return 0;
4433 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4434 return GET_CODE (SET_DEST (set)) != MEM;
4435 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
4436 return 0;
4438 return 1;
4441 /* Target hook for assembling integer objects. The AVR version needs
4442 special handling for references to certain labels. */
4444 static bool
4445 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
4447 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
4448 && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x))
4449 || GET_CODE (x) == LABEL_REF))
4451 fputs ("\t.word\tpm(", asm_out_file);
4452 output_addr_const (asm_out_file, x);
4453 fputs (")\n", asm_out_file);
4454 return true;
4456 return default_assemble_integer (x, size, aligned_p);
4459 /* The routine used to output NUL terminated strings. We use a special
4460 version of this for most svr4 targets because doing so makes the
4461 generated assembly code more compact (and thus faster to assemble)
4462 as well as more readable, especially for targets like the i386
4463 (where the only alternative is to output character sequences as
4464 comma separated lists of numbers). */
4466 void
4467 gas_output_limited_string(FILE *file, const char *str)
4469 const unsigned char *_limited_str = (const unsigned char *) str;
4470 unsigned ch;
4471 fprintf (file, "%s\"", STRING_ASM_OP);
4472 for (; (ch = *_limited_str); _limited_str++)
4474 int escape;
4475 switch (escape = ESCAPES[ch])
4477 case 0:
4478 putc (ch, file);
4479 break;
4480 case 1:
4481 fprintf (file, "\\%03o", ch);
4482 break;
4483 default:
4484 putc ('\\', file);
4485 putc (escape, file);
4486 break;
4489 fprintf (file, "\"\n");
4492 /* The routine used to output sequences of byte values. We use a special
4493 version of this for most svr4 targets because doing so makes the
4494 generated assembly code more compact (and thus faster to assemble)
4495 as well as more readable. Note that if we find subparts of the
4496 character sequence which end with NUL (and which are shorter than
4497 STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
4499 void
4500 gas_output_ascii(FILE *file, const char *str, size_t length)
4502 const unsigned char *_ascii_bytes = (const unsigned char *) str;
4503 const unsigned char *limit = _ascii_bytes + length;
4504 unsigned bytes_in_chunk = 0;
4505 for (; _ascii_bytes < limit; _ascii_bytes++)
4507 const unsigned char *p;
4508 if (bytes_in_chunk >= 60)
4510 fprintf (file, "\"\n");
4511 bytes_in_chunk = 0;
4513 for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
4514 continue;
4515 if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
4517 if (bytes_in_chunk > 0)
4519 fprintf (file, "\"\n");
4520 bytes_in_chunk = 0;
4522 gas_output_limited_string (file, (const char*)_ascii_bytes);
4523 _ascii_bytes = p;
4525 else
4527 int escape;
4528 unsigned ch;
4529 if (bytes_in_chunk == 0)
4530 fprintf (file, "\t.ascii\t\"");
4531 switch (escape = ESCAPES[ch = *_ascii_bytes])
4533 case 0:
4534 putc (ch, file);
4535 bytes_in_chunk++;
4536 break;
4537 case 1:
4538 fprintf (file, "\\%03o", ch);
4539 bytes_in_chunk += 4;
4540 break;
4541 default:
4542 putc ('\\', file);
4543 putc (escape, file);
4544 bytes_in_chunk += 2;
4545 break;
4549 if (bytes_in_chunk > 0)
4550 fprintf (file, "\"\n");
4553 /* Return value is nonzero if pseudos that have been
4554 assigned to registers of class CLASS would likely be spilled
4555 because registers of CLASS are needed for spill registers. */
4557 enum reg_class
4558 class_likely_spilled_p (int c)
4560 return (c != ALL_REGS && c != ADDW_REGS);
4563 /* Valid attributes:
4564 progmem - put data to program memory;
4565 signal - make a function to be hardware interrupt. After function
4566 prologue interrupts are disabled;
4567 interrupt - make a function to be hardware interrupt. After function
4568 prologue interrupts are enabled;
4569 naked - don't generate function prologue/epilogue and `ret' command.
4571 Only `progmem' attribute valid for type. */
4573 const struct attribute_spec avr_attribute_table[] =
4575 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
4576 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute },
4577 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4578 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4579 { "naked", 0, 0, false, true, true, avr_handle_fntype_attribute },
4580 { NULL, 0, 0, false, false, false, NULL }
4583 /* Handle a "progmem" attribute; arguments as in
4584 struct attribute_spec.handler. */
4585 static tree
4586 avr_handle_progmem_attribute (tree *node, tree name,
4587 tree args ATTRIBUTE_UNUSED,
4588 int flags ATTRIBUTE_UNUSED,
4589 bool *no_add_attrs)
4591 if (DECL_P (*node))
4593 if (TREE_CODE (*node) == TYPE_DECL)
4595 /* This is really a decl attribute, not a type attribute,
4596 but try to handle it for GCC 3.0 backwards compatibility. */
4598 tree type = TREE_TYPE (*node);
4599 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
4600 tree newtype = build_type_attribute_variant (type, attr);
4602 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
4603 TREE_TYPE (*node) = newtype;
4604 *no_add_attrs = true;
4606 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
4608 if (DECL_INITIAL (*node) == NULL_TREE && !DECL_EXTERNAL (*node))
4610 warning (0, "only initialized variables can be placed into "
4611 "program memory area");
4612 *no_add_attrs = true;
4615 else
4617 warning (OPT_Wattributes, "%qs attribute ignored",
4618 IDENTIFIER_POINTER (name));
4619 *no_add_attrs = true;
4623 return NULL_TREE;
4626 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
4627 struct attribute_spec.handler. */
4629 static tree
4630 avr_handle_fndecl_attribute (tree *node, tree name,
4631 tree args ATTRIBUTE_UNUSED,
4632 int flags ATTRIBUTE_UNUSED,
4633 bool *no_add_attrs)
4635 if (TREE_CODE (*node) != FUNCTION_DECL)
4637 warning (OPT_Wattributes, "%qs attribute only applies to functions",
4638 IDENTIFIER_POINTER (name));
4639 *no_add_attrs = true;
4641 else
4643 const char *func_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (*node));
4644 const char *attr = IDENTIFIER_POINTER (name);
4646 /* If the function has the 'signal' or 'interrupt' attribute, test to
4647 make sure that the name of the function is "__vector_NN" so as to
4648 catch when the user misspells the interrupt vector name. */
4650 if (strncmp (attr, "interrupt", strlen ("interrupt")) == 0)
4652 if (strncmp (func_name, "__vector", strlen ("__vector")) != 0)
4654 warning (0, "%qs appears to be a misspelled interrupt handler",
4655 func_name);
4658 else if (strncmp (attr, "signal", strlen ("signal")) == 0)
4660 if (strncmp (func_name, "__vector", strlen ("__vector")) != 0)
4662 warning (0, "%qs appears to be a misspelled signal handler",
4663 func_name);
4668 return NULL_TREE;
4671 static tree
4672 avr_handle_fntype_attribute (tree *node, tree name,
4673 tree args ATTRIBUTE_UNUSED,
4674 int flags ATTRIBUTE_UNUSED,
4675 bool *no_add_attrs)
4677 if (TREE_CODE (*node) != FUNCTION_TYPE)
4679 warning (OPT_Wattributes, "%qs attribute only applies to functions",
4680 IDENTIFIER_POINTER (name));
4681 *no_add_attrs = true;
4684 return NULL_TREE;
4687 /* Look for attribute `progmem' in DECL
4688 if found return 1, otherwise 0. */
4691 avr_progmem_p (tree decl, tree attributes)
4693 tree a;
4695 if (TREE_CODE (decl) != VAR_DECL)
4696 return 0;
4698 if (NULL_TREE
4699 != lookup_attribute ("progmem", attributes))
4700 return 1;
4702 a=decl;
4704 a = TREE_TYPE(a);
4705 while (TREE_CODE (a) == ARRAY_TYPE);
4707 if (a == error_mark_node)
4708 return 0;
4710 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
4711 return 1;
4713 return 0;
4716 /* Add the section attribute if the variable is in progmem. */
4718 static void
4719 avr_insert_attributes (tree node, tree *attributes)
4721 if (TREE_CODE (node) == VAR_DECL
4722 && (TREE_STATIC (node) || DECL_EXTERNAL (node))
4723 && avr_progmem_p (node, *attributes))
4725 static const char dsec[] = ".progmem.data";
4726 *attributes = tree_cons (get_identifier ("section"),
4727 build_tree_list (NULL, build_string (strlen (dsec), dsec)),
4728 *attributes);
4730 /* ??? This seems sketchy. Why can't the user declare the
4731 thing const in the first place? */
4732 TREE_READONLY (node) = 1;
4736 /* A get_unnamed_section callback for switching to progmem_section. */
4738 static void
4739 avr_output_progmem_section_asm_op (const void *arg ATTRIBUTE_UNUSED)
4741 fprintf (asm_out_file,
4742 "\t.section .progmem.gcc_sw_table, \"%s\", @progbits\n",
4743 AVR_MEGA ? "a" : "ax");
4744 /* Should already be aligned, this is just to be safe if it isn't. */
4745 fprintf (asm_out_file, "\t.p2align 1\n");
4748 /* Implement TARGET_ASM_INIT_SECTIONS. */
4750 static void
4751 avr_asm_init_sections (void)
4753 progmem_section = get_unnamed_section (AVR_MEGA ? 0 : SECTION_CODE,
4754 avr_output_progmem_section_asm_op,
4755 NULL);
4756 readonly_data_section = data_section;
4759 static unsigned int
4760 avr_section_type_flags (tree decl, const char *name, int reloc)
4762 unsigned int flags = default_section_type_flags (decl, name, reloc);
4764 if (strncmp (name, ".noinit", 7) == 0)
4766 if (decl && TREE_CODE (decl) == VAR_DECL
4767 && DECL_INITIAL (decl) == NULL_TREE)
4768 flags |= SECTION_BSS; /* @nobits */
4769 else
4770 warning (0, "only uninitialized variables can be placed in the "
4771 ".noinit section");
4774 return flags;
4777 /* Outputs some appropriate text to go at the start of an assembler
4778 file. */
4780 static void
4781 avr_file_start (void)
4783 if (avr_asm_only_p)
4784 error ("MCU %qs supported for assembler only", avr_mcu_name);
4786 default_file_start ();
4788 /* fprintf (asm_out_file, "\t.arch %s\n", avr_mcu_name);*/
4789 fputs ("__SREG__ = 0x3f\n"
4790 "__SP_H__ = 0x3e\n"
4791 "__SP_L__ = 0x3d\n", asm_out_file);
4793 fputs ("__tmp_reg__ = 0\n"
4794 "__zero_reg__ = 1\n", asm_out_file);
4796 /* FIXME: output these only if there is anything in the .data / .bss
4797 sections - some code size could be saved by not linking in the
4798 initialization code from libgcc if one or both sections are empty. */
4799 fputs ("\t.global __do_copy_data\n", asm_out_file);
4800 fputs ("\t.global __do_clear_bss\n", asm_out_file);
4803 /* Outputs to the stdio stream FILE some
4804 appropriate text to go at the end of an assembler file. */
4806 static void
4807 avr_file_end (void)
4811 /* Choose the order in which to allocate hard registers for
4812 pseudo-registers local to a basic block.
4814 Store the desired register order in the array `reg_alloc_order'.
4815 Element 0 should be the register to allocate first; element 1, the
4816 next register; and so on. */
4818 void
4819 order_regs_for_local_alloc (void)
4821 unsigned int i;
4822 static const int order_0[] = {
4823 24,25,
4824 18,19,
4825 20,21,
4826 22,23,
4827 30,31,
4828 26,27,
4829 28,29,
4830 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4831 0,1,
4832 32,33,34,35
4834 static const int order_1[] = {
4835 18,19,
4836 20,21,
4837 22,23,
4838 24,25,
4839 30,31,
4840 26,27,
4841 28,29,
4842 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4843 0,1,
4844 32,33,34,35
4846 static const int order_2[] = {
4847 25,24,
4848 23,22,
4849 21,20,
4850 19,18,
4851 30,31,
4852 26,27,
4853 28,29,
4854 17,16,
4855 15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4856 1,0,
4857 32,33,34,35
4860 const int *order = (TARGET_ORDER_1 ? order_1 :
4861 TARGET_ORDER_2 ? order_2 :
4862 order_0);
4863 for (i=0; i < ARRAY_SIZE (order_0); ++i)
4864 reg_alloc_order[i] = order[i];
4868 /* Mutually recursive subroutine of avr_rtx_cost for calculating the
4869 cost of an RTX operand given its context. X is the rtx of the
4870 operand, MODE is its mode, and OUTER is the rtx_code of this
4871 operand's parent operator. */
4873 static int
4874 avr_operand_rtx_cost (rtx x, enum machine_mode mode, enum rtx_code outer)
4876 enum rtx_code code = GET_CODE (x);
4877 int total;
4879 switch (code)
4881 case REG:
4882 case SUBREG:
4883 return 0;
4885 case CONST_INT:
4886 case CONST_DOUBLE:
4887 return COSTS_N_INSNS (GET_MODE_SIZE (mode));
4889 default:
4890 break;
4893 total = 0;
4894 avr_rtx_costs (x, code, outer, &total);
4895 return total;
4898 /* The AVR backend's rtx_cost function. X is rtx expression whose cost
4899 is to be calculated. Return true if the complete cost has been
4900 computed, and false if subexpressions should be scanned. In either
4901 case, *TOTAL contains the cost result. */
4903 static bool
4904 avr_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total)
4906 enum machine_mode mode = GET_MODE (x);
4907 HOST_WIDE_INT val;
4909 switch (code)
4911 case CONST_INT:
4912 case CONST_DOUBLE:
4913 /* Immediate constants are as cheap as registers. */
4914 *total = 0;
4915 return true;
4917 case MEM:
4918 case CONST:
4919 case LABEL_REF:
4920 case SYMBOL_REF:
4921 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
4922 return true;
4924 case NEG:
4925 switch (mode)
4927 case QImode:
4928 case SFmode:
4929 *total = COSTS_N_INSNS (1);
4930 break;
4932 case HImode:
4933 *total = COSTS_N_INSNS (3);
4934 break;
4936 case SImode:
4937 *total = COSTS_N_INSNS (7);
4938 break;
4940 default:
4941 return false;
4943 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
4944 return true;
4946 case ABS:
4947 switch (mode)
4949 case QImode:
4950 case SFmode:
4951 *total = COSTS_N_INSNS (1);
4952 break;
4954 default:
4955 return false;
4957 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
4958 return true;
4960 case NOT:
4961 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
4962 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
4963 return true;
4965 case ZERO_EXTEND:
4966 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
4967 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
4968 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
4969 return true;
4971 case SIGN_EXTEND:
4972 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
4973 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
4974 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
4975 return true;
4977 case PLUS:
4978 switch (mode)
4980 case QImode:
4981 *total = COSTS_N_INSNS (1);
4982 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4983 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
4984 break;
4986 case HImode:
4987 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4989 *total = COSTS_N_INSNS (2);
4990 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
4992 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
4993 *total = COSTS_N_INSNS (1);
4994 else
4995 *total = COSTS_N_INSNS (2);
4996 break;
4998 case SImode:
4999 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5001 *total = COSTS_N_INSNS (4);
5002 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5004 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
5005 *total = COSTS_N_INSNS (1);
5006 else
5007 *total = COSTS_N_INSNS (4);
5008 break;
5010 default:
5011 return false;
5013 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5014 return true;
5016 case MINUS:
5017 case AND:
5018 case IOR:
5019 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5020 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5021 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5022 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5023 return true;
5025 case XOR:
5026 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5027 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5028 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5029 return true;
5031 case MULT:
5032 switch (mode)
5034 case QImode:
5035 if (AVR_HAVE_MUL)
5036 *total = COSTS_N_INSNS (optimize_size ? 3 : 4);
5037 else if (optimize_size)
5038 *total = COSTS_N_INSNS (AVR_MEGA ? 2 : 1);
5039 else
5040 return false;
5041 break;
5043 case HImode:
5044 if (AVR_HAVE_MUL)
5045 *total = COSTS_N_INSNS (optimize_size ? 7 : 10);
5046 else if (optimize_size)
5047 *total = COSTS_N_INSNS (AVR_MEGA ? 2 : 1);
5048 else
5049 return false;
5050 break;
5052 default:
5053 return false;
5055 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5056 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5057 return true;
5059 case DIV:
5060 case MOD:
5061 case UDIV:
5062 case UMOD:
5063 if (optimize_size)
5064 *total = COSTS_N_INSNS (AVR_MEGA ? 2 : 1);
5065 else
5066 return false;
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 ASHIFT:
5072 switch (mode)
5074 case QImode:
5075 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5077 *total = COSTS_N_INSNS (optimize_size ? 4 : 17);
5078 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5080 else
5082 val = INTVAL (XEXP (x, 1));
5083 if (val == 7)
5084 *total = COSTS_N_INSNS (3);
5085 else if (val >= 0 && val <= 7)
5086 *total = COSTS_N_INSNS (val);
5087 else
5088 *total = COSTS_N_INSNS (1);
5090 break;
5092 case HImode:
5093 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5095 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5096 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5098 else
5099 switch (INTVAL (XEXP (x, 1)))
5101 case 0:
5102 *total = 0;
5103 break;
5104 case 1:
5105 case 8:
5106 *total = COSTS_N_INSNS (2);
5107 break;
5108 case 9:
5109 *total = COSTS_N_INSNS (3);
5110 break;
5111 case 2:
5112 case 3:
5113 case 10:
5114 case 15:
5115 *total = COSTS_N_INSNS (4);
5116 break;
5117 case 7:
5118 case 11:
5119 case 12:
5120 *total = COSTS_N_INSNS (5);
5121 break;
5122 case 4:
5123 *total = COSTS_N_INSNS (optimize_size ? 5 : 8);
5124 break;
5125 case 6:
5126 *total = COSTS_N_INSNS (optimize_size ? 5 : 9);
5127 break;
5128 case 5:
5129 *total = COSTS_N_INSNS (optimize_size ? 5 : 10);
5130 break;
5131 default:
5132 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5133 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5135 break;
5137 case SImode:
5138 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5140 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5141 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5143 else
5144 switch (INTVAL (XEXP (x, 1)))
5146 case 0:
5147 *total = 0;
5148 break;
5149 case 24:
5150 *total = COSTS_N_INSNS (3);
5151 break;
5152 case 1:
5153 case 8:
5154 case 16:
5155 *total = COSTS_N_INSNS (4);
5156 break;
5157 case 31:
5158 *total = COSTS_N_INSNS (6);
5159 break;
5160 case 2:
5161 *total = COSTS_N_INSNS (optimize_size ? 7 : 8);
5162 break;
5163 default:
5164 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5165 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5167 break;
5169 default:
5170 return false;
5172 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5173 return true;
5175 case ASHIFTRT:
5176 switch (mode)
5178 case QImode:
5179 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5181 *total = COSTS_N_INSNS (optimize_size ? 4 : 17);
5182 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5184 else
5186 val = INTVAL (XEXP (x, 1));
5187 if (val == 6)
5188 *total = COSTS_N_INSNS (4);
5189 else if (val == 7)
5190 *total = COSTS_N_INSNS (2);
5191 else if (val >= 0 && val <= 7)
5192 *total = COSTS_N_INSNS (val);
5193 else
5194 *total = COSTS_N_INSNS (1);
5196 break;
5198 case HImode:
5199 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5201 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5202 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5204 else
5205 switch (INTVAL (XEXP (x, 1)))
5207 case 0:
5208 *total = 0;
5209 break;
5210 case 1:
5211 *total = COSTS_N_INSNS (2);
5212 break;
5213 case 15:
5214 *total = COSTS_N_INSNS (3);
5215 break;
5216 case 2:
5217 case 7:
5218 case 8:
5219 case 9:
5220 *total = COSTS_N_INSNS (4);
5221 break;
5222 case 10:
5223 case 14:
5224 *total = COSTS_N_INSNS (5);
5225 break;
5226 case 11:
5227 *total = COSTS_N_INSNS (optimize_size ? 5 : 6);
5228 break;
5229 case 12:
5230 *total = COSTS_N_INSNS (optimize_size ? 5 : 7);
5231 break;
5232 case 6:
5233 case 13:
5234 *total = COSTS_N_INSNS (optimize_size ? 5 : 8);
5235 break;
5236 default:
5237 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5238 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5240 break;
5242 case SImode:
5243 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5245 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5246 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5248 else
5249 switch (INTVAL (XEXP (x, 1)))
5251 case 0:
5252 *total = 0;
5253 break;
5254 case 1:
5255 *total = COSTS_N_INSNS (4);
5256 break;
5257 case 8:
5258 case 16:
5259 case 24:
5260 *total = COSTS_N_INSNS (6);
5261 break;
5262 case 2:
5263 *total = COSTS_N_INSNS (optimize_size ? 7 : 8);
5264 break;
5265 case 31:
5266 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 5);
5267 break;
5268 default:
5269 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5270 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5272 break;
5274 default:
5275 return false;
5277 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5278 return true;
5280 case LSHIFTRT:
5281 switch (mode)
5283 case QImode:
5284 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5286 *total = COSTS_N_INSNS (optimize_size ? 4 : 17);
5287 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5289 else
5291 val = INTVAL (XEXP (x, 1));
5292 if (val == 7)
5293 *total = COSTS_N_INSNS (3);
5294 else if (val >= 0 && val <= 7)
5295 *total = COSTS_N_INSNS (val);
5296 else
5297 *total = COSTS_N_INSNS (1);
5299 break;
5301 case HImode:
5302 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5304 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5305 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5307 else
5308 switch (INTVAL (XEXP (x, 1)))
5310 case 0:
5311 *total = 0;
5312 break;
5313 case 1:
5314 case 8:
5315 *total = COSTS_N_INSNS (2);
5316 break;
5317 case 9:
5318 *total = COSTS_N_INSNS (3);
5319 break;
5320 case 2:
5321 case 10:
5322 case 15:
5323 *total = COSTS_N_INSNS (4);
5324 break;
5325 case 7:
5326 case 11:
5327 *total = COSTS_N_INSNS (5);
5328 break;
5329 case 3:
5330 case 12:
5331 case 13:
5332 case 14:
5333 *total = COSTS_N_INSNS (optimize_size ? 5 : 6);
5334 break;
5335 case 4:
5336 *total = COSTS_N_INSNS (optimize_size ? 5 : 7);
5337 break;
5338 case 5:
5339 case 6:
5340 *total = COSTS_N_INSNS (optimize_size ? 5 : 9);
5341 break;
5342 default:
5343 *total = COSTS_N_INSNS (optimize_size ? 5 : 41);
5344 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5346 break;
5348 case SImode:
5349 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5351 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5352 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5354 else
5355 switch (INTVAL (XEXP (x, 1)))
5357 case 0:
5358 *total = 0;
5359 break;
5360 case 1:
5361 *total = COSTS_N_INSNS (4);
5362 break;
5363 case 2:
5364 *total = COSTS_N_INSNS (optimize_size ? 7 : 8);
5365 break;
5366 case 8:
5367 case 16:
5368 case 24:
5369 *total = COSTS_N_INSNS (4);
5370 break;
5371 case 31:
5372 *total = COSTS_N_INSNS (6);
5373 break;
5374 default:
5375 *total = COSTS_N_INSNS (optimize_size ? 7 : 113);
5376 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5378 break;
5380 default:
5381 return false;
5383 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5384 return true;
5386 case COMPARE:
5387 switch (GET_MODE (XEXP (x, 0)))
5389 case QImode:
5390 *total = COSTS_N_INSNS (1);
5391 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5392 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5393 break;
5395 case HImode:
5396 *total = COSTS_N_INSNS (2);
5397 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5398 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5399 else if (INTVAL (XEXP (x, 1)) != 0)
5400 *total += COSTS_N_INSNS (1);
5401 break;
5403 case SImode:
5404 *total = COSTS_N_INSNS (4);
5405 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5406 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code);
5407 else if (INTVAL (XEXP (x, 1)) != 0)
5408 *total += COSTS_N_INSNS (3);
5409 break;
5411 default:
5412 return false;
5414 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code);
5415 return true;
5417 default:
5418 break;
5420 return false;
5423 /* Calculate the cost of a memory address. */
5425 static int
5426 avr_address_cost (rtx x)
5428 if (GET_CODE (x) == PLUS
5429 && GET_CODE (XEXP (x,1)) == CONST_INT
5430 && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
5431 && INTVAL (XEXP (x,1)) >= 61)
5432 return 18;
5433 if (CONSTANT_ADDRESS_P (x))
5435 if (avr_io_address_p (x, 1))
5436 return 2;
5437 return 4;
5439 return 4;
5442 /* Test for extra memory constraint 'Q'.
5443 It's a memory address based on Y or Z pointer with valid displacement. */
5446 extra_constraint_Q (rtx x)
5448 if (GET_CODE (XEXP (x,0)) == PLUS
5449 && REG_P (XEXP (XEXP (x,0), 0))
5450 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
5451 && (INTVAL (XEXP (XEXP (x,0), 1))
5452 <= MAX_LD_OFFSET (GET_MODE (x))))
5454 rtx xx = XEXP (XEXP (x,0), 0);
5455 int regno = REGNO (xx);
5456 if (TARGET_ALL_DEBUG)
5458 fprintf (stderr, ("extra_constraint:\n"
5459 "reload_completed: %d\n"
5460 "reload_in_progress: %d\n"),
5461 reload_completed, reload_in_progress);
5462 debug_rtx (x);
5464 if (regno >= FIRST_PSEUDO_REGISTER)
5465 return 1; /* allocate pseudos */
5466 else if (regno == REG_Z || regno == REG_Y)
5467 return 1; /* strictly check */
5468 else if (xx == frame_pointer_rtx
5469 || xx == arg_pointer_rtx)
5470 return 1; /* XXX frame & arg pointer checks */
5472 return 0;
5475 /* Convert condition code CONDITION to the valid AVR condition code. */
5477 RTX_CODE
5478 avr_normalize_condition (RTX_CODE condition)
5480 switch (condition)
5482 case GT:
5483 return GE;
5484 case GTU:
5485 return GEU;
5486 case LE:
5487 return LT;
5488 case LEU:
5489 return LTU;
5490 default:
5491 gcc_unreachable ();
5495 /* This function optimizes conditional jumps. */
5497 static void
5498 avr_reorg (void)
5500 rtx insn, pattern;
5502 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5504 if (! (GET_CODE (insn) == INSN
5505 || GET_CODE (insn) == CALL_INSN
5506 || GET_CODE (insn) == JUMP_INSN)
5507 || !single_set (insn))
5508 continue;
5510 pattern = PATTERN (insn);
5512 if (GET_CODE (pattern) == PARALLEL)
5513 pattern = XVECEXP (pattern, 0, 0);
5514 if (GET_CODE (pattern) == SET
5515 && SET_DEST (pattern) == cc0_rtx
5516 && compare_diff_p (insn))
5518 if (GET_CODE (SET_SRC (pattern)) == COMPARE)
5520 /* Now we work under compare insn. */
5522 pattern = SET_SRC (pattern);
5523 if (true_regnum (XEXP (pattern,0)) >= 0
5524 && true_regnum (XEXP (pattern,1)) >= 0 )
5526 rtx x = XEXP (pattern,0);
5527 rtx next = next_real_insn (insn);
5528 rtx pat = PATTERN (next);
5529 rtx src = SET_SRC (pat);
5530 rtx t = XEXP (src,0);
5531 PUT_CODE (t, swap_condition (GET_CODE (t)));
5532 XEXP (pattern,0) = XEXP (pattern,1);
5533 XEXP (pattern,1) = x;
5534 INSN_CODE (next) = -1;
5536 else if (true_regnum (XEXP (pattern,0)) >= 0
5537 && GET_CODE (XEXP (pattern,1)) == CONST_INT)
5539 rtx x = XEXP (pattern,1);
5540 rtx next = next_real_insn (insn);
5541 rtx pat = PATTERN (next);
5542 rtx src = SET_SRC (pat);
5543 rtx t = XEXP (src,0);
5544 enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
5546 if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
5548 XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
5549 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
5550 INSN_CODE (next) = -1;
5551 INSN_CODE (insn) = -1;
5555 else if (true_regnum (SET_SRC (pattern)) >= 0)
5557 /* This is a tst insn */
5558 rtx next = next_real_insn (insn);
5559 rtx pat = PATTERN (next);
5560 rtx src = SET_SRC (pat);
5561 rtx t = XEXP (src,0);
5563 PUT_CODE (t, swap_condition (GET_CODE (t)));
5564 SET_SRC (pattern) = gen_rtx_NEG (GET_MODE (SET_SRC (pattern)),
5565 SET_SRC (pattern));
5566 INSN_CODE (next) = -1;
5567 INSN_CODE (insn) = -1;
5573 /* Returns register number for function return value.*/
5576 avr_ret_register (void)
5578 return 24;
5581 /* Create an RTX representing the place where a
5582 library function returns a value of mode MODE. */
5585 avr_libcall_value (enum machine_mode mode)
5587 int offs = GET_MODE_SIZE (mode);
5588 if (offs < 2)
5589 offs = 2;
5590 return gen_rtx_REG (mode, RET_REGISTER + 2 - offs);
5593 /* Create an RTX representing the place where a
5594 function returns a value of data type VALTYPE. */
5597 avr_function_value (const_tree type, const_tree func ATTRIBUTE_UNUSED)
5599 unsigned int offs;
5601 if (TYPE_MODE (type) != BLKmode)
5602 return avr_libcall_value (TYPE_MODE (type));
5604 offs = int_size_in_bytes (type);
5605 if (offs < 2)
5606 offs = 2;
5607 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
5608 offs = GET_MODE_SIZE (SImode);
5609 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
5610 offs = GET_MODE_SIZE (DImode);
5612 return gen_rtx_REG (BLKmode, RET_REGISTER + 2 - offs);
5615 /* Places additional restrictions on the register class to
5616 use when it is necessary to copy value X into a register
5617 in class CLASS. */
5619 enum reg_class
5620 preferred_reload_class (rtx x ATTRIBUTE_UNUSED, enum reg_class class)
5622 return class;
5626 test_hard_reg_class (enum reg_class class, rtx x)
5628 int regno = true_regnum (x);
5629 if (regno < 0)
5630 return 0;
5632 if (TEST_HARD_REG_CLASS (class, regno))
5633 return 1;
5635 return 0;
5640 jump_over_one_insn_p (rtx insn, rtx dest)
5642 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
5643 ? XEXP (dest, 0)
5644 : dest);
5645 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
5646 int dest_addr = INSN_ADDRESSES (uid);
5647 return dest_addr - jump_addr == get_attr_length (insn) + 1;
5650 /* Returns 1 if a value of mode MODE can be stored starting with hard
5651 register number REGNO. On the enhanced core, anything larger than
5652 1 byte must start in even numbered register for "movw" to work
5653 (this way we don't have to check for odd registers everywhere). */
5656 avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
5658 /* Disallow QImode in stack pointer regs. */
5659 if ((regno == REG_SP || regno == (REG_SP + 1)) && mode == QImode)
5660 return 0;
5662 /* The only thing that can go into registers r28:r29 is a Pmode. */
5663 if (regno == REG_Y && mode == Pmode)
5664 return 1;
5666 /* Otherwise disallow all regno/mode combinations that span r28:r29. */
5667 if (regno <= (REG_Y + 1) && (regno + GET_MODE_SIZE (mode)) >= (REG_Y + 1))
5668 return 0;
5670 if (mode == QImode)
5671 return 1;
5673 /* Modes larger than QImode occupy consecutive registers. */
5674 if (regno + GET_MODE_SIZE (mode) > FIRST_PSEUDO_REGISTER)
5675 return 0;
5677 /* All modes larger than QImode should start in an even register. */
5678 return !(regno & 1);
5681 /* Returns 1 if X is a valid address for an I/O register of size SIZE
5682 (1 or 2). Used for lds/sts -> in/out optimization. Add 0x20 to SIZE
5683 to check for the lower half of I/O space (for cbi/sbi/sbic/sbis). */
5686 avr_io_address_p (rtx x, int size)
5688 return (optimize > 0 && GET_CODE (x) == CONST_INT
5689 && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size);
5692 const char *
5693 output_reload_inhi (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
5695 int tmp;
5696 if (!len)
5697 len = &tmp;
5699 if (GET_CODE (operands[1]) == CONST_INT)
5701 int val = INTVAL (operands[1]);
5702 if ((val & 0xff) == 0)
5704 *len = 3;
5705 return (AS2 (mov,%A0,__zero_reg__) CR_TAB
5706 AS2 (ldi,%2,hi8(%1)) CR_TAB
5707 AS2 (mov,%B0,%2));
5709 else if ((val & 0xff00) == 0)
5711 *len = 3;
5712 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5713 AS2 (mov,%A0,%2) CR_TAB
5714 AS2 (mov,%B0,__zero_reg__));
5716 else if ((val & 0xff) == ((val & 0xff00) >> 8))
5718 *len = 3;
5719 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5720 AS2 (mov,%A0,%2) CR_TAB
5721 AS2 (mov,%B0,%2));
5724 *len = 4;
5725 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5726 AS2 (mov,%A0,%2) CR_TAB
5727 AS2 (ldi,%2,hi8(%1)) CR_TAB
5728 AS2 (mov,%B0,%2));
5732 const char *
5733 output_reload_insisf (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
5735 rtx src = operands[1];
5736 int cnst = (GET_CODE (src) == CONST_INT);
5738 if (len)
5740 if (cnst)
5741 *len = 4 + ((INTVAL (src) & 0xff) != 0)
5742 + ((INTVAL (src) & 0xff00) != 0)
5743 + ((INTVAL (src) & 0xff0000) != 0)
5744 + ((INTVAL (src) & 0xff000000) != 0);
5745 else
5746 *len = 8;
5748 return "";
5751 if (cnst && ((INTVAL (src) & 0xff) == 0))
5752 output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
5753 else
5755 output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
5756 output_asm_insn (AS2 (mov, %A0, %2), operands);
5758 if (cnst && ((INTVAL (src) & 0xff00) == 0))
5759 output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
5760 else
5762 output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
5763 output_asm_insn (AS2 (mov, %B0, %2), operands);
5765 if (cnst && ((INTVAL (src) & 0xff0000) == 0))
5766 output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
5767 else
5769 output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
5770 output_asm_insn (AS2 (mov, %C0, %2), operands);
5772 if (cnst && ((INTVAL (src) & 0xff000000) == 0))
5773 output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
5774 else
5776 output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
5777 output_asm_insn (AS2 (mov, %D0, %2), operands);
5779 return "";
5782 void
5783 avr_output_bld (rtx operands[], int bit_nr)
5785 static char s[] = "bld %A0,0";
5787 s[5] = 'A' + (bit_nr >> 3);
5788 s[8] = '0' + (bit_nr & 7);
5789 output_asm_insn (s, operands);
5792 void
5793 avr_output_addr_vec_elt (FILE *stream, int value)
5795 switch_to_section (progmem_section);
5796 if (AVR_MEGA)
5797 fprintf (stream, "\t.word pm(.L%d)\n", value);
5798 else
5799 fprintf (stream, "\trjmp .L%d\n", value);
5802 /* Returns 1 if SCRATCH are safe to be allocated as a scratch
5803 registers (for a define_peephole2) in the current function. */
5806 avr_peep2_scratch_safe (rtx scratch)
5808 if ((interrupt_function_p (current_function_decl)
5809 || signal_function_p (current_function_decl))
5810 && leaf_function_p ())
5812 int first_reg = true_regnum (scratch);
5813 int last_reg = first_reg + GET_MODE_SIZE (GET_MODE (scratch)) - 1;
5814 int reg;
5816 for (reg = first_reg; reg <= last_reg; reg++)
5818 if (!df_regs_ever_live_p (reg))
5819 return 0;
5822 return 1;
5825 /* Output a branch that tests a single bit of a register (QI, HI or SImode)
5826 or memory location in the I/O space (QImode only).
5828 Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
5829 Operand 1: register operand to test, or CONST_INT memory address.
5830 Operand 2: bit number (for QImode operand) or mask (HImode, SImode).
5831 Operand 3: label to jump to if the test is true. */
5833 const char *
5834 avr_out_sbxx_branch (rtx insn, rtx operands[])
5836 enum rtx_code comp = GET_CODE (operands[0]);
5837 int long_jump = (get_attr_length (insn) >= 4);
5838 int reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
5840 if (comp == GE)
5841 comp = EQ;
5842 else if (comp == LT)
5843 comp = NE;
5845 if (reverse)
5846 comp = reverse_condition (comp);
5848 if (GET_CODE (operands[1]) == CONST_INT)
5850 if (INTVAL (operands[1]) < 0x40)
5852 if (comp == EQ)
5853 output_asm_insn (AS2 (sbis,%1-0x20,%2), operands);
5854 else
5855 output_asm_insn (AS2 (sbic,%1-0x20,%2), operands);
5857 else
5859 output_asm_insn (AS2 (in,__tmp_reg__,%1-0x20), operands);
5860 if (comp == EQ)
5861 output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands);
5862 else
5863 output_asm_insn (AS2 (sbrc,__tmp_reg__,%2), operands);
5866 else /* GET_CODE (operands[1]) == REG */
5868 if (GET_MODE (operands[1]) == QImode)
5870 if (comp == EQ)
5871 output_asm_insn (AS2 (sbrs,%1,%2), operands);
5872 else
5873 output_asm_insn (AS2 (sbrc,%1,%2), operands);
5875 else /* HImode or SImode */
5877 static char buf[] = "sbrc %A1,0";
5878 int bit_nr = exact_log2 (INTVAL (operands[2])
5879 & GET_MODE_MASK (GET_MODE (operands[1])));
5881 buf[3] = (comp == EQ) ? 's' : 'c';
5882 buf[6] = 'A' + (bit_nr >> 3);
5883 buf[9] = '0' + (bit_nr & 7);
5884 output_asm_insn (buf, operands);
5888 if (long_jump)
5889 return (AS1 (rjmp,.+4) CR_TAB
5890 AS1 (jmp,%3));
5891 if (!reverse)
5892 return AS1 (rjmp,%3);
5893 return "";
5896 /* Worker function for TARGET_ASM_CONSTRUCTOR. */
5898 static void
5899 avr_asm_out_ctor (rtx symbol, int priority)
5901 fputs ("\t.global __do_global_ctors\n", asm_out_file);
5902 default_ctor_section_asm_out_constructor (symbol, priority);
5905 /* Worker function for TARGET_ASM_DESTRUCTOR. */
5907 static void
5908 avr_asm_out_dtor (rtx symbol, int priority)
5910 fputs ("\t.global __do_global_dtors\n", asm_out_file);
5911 default_dtor_section_asm_out_destructor (symbol, priority);
5914 /* Worker function for TARGET_RETURN_IN_MEMORY. */
5916 static bool
5917 avr_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
5919 if (TYPE_MODE (type) == BLKmode)
5921 HOST_WIDE_INT size = int_size_in_bytes (type);
5922 return (size == -1 || size > 8);
5924 else
5925 return false;
5928 #include "gt-avr.h"