b149e7efae829fcb142ce66539f898bf52b81ea0
[gcc.git] / gcc / config / avr / avr.c
1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2 Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3 Contributed by Denis Chertykov (denisc@overta.ru)
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
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
47 /* Maximal allowed offset for an address in the LD command */
48 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
49
50 static int avr_naked_function_p (tree);
51 static int interrupt_function_p (tree);
52 static int signal_function_p (tree);
53 static int avr_regs_to_save (HARD_REG_SET *);
54 static int sequent_regs_live (void);
55 static const char *ptrreg_to_str (int);
56 static const char *cond_string (enum rtx_code);
57 static int avr_num_arg_regs (enum machine_mode, tree);
58 static int out_adj_frame_ptr (FILE *, int);
59 static int out_set_stack_ptr (FILE *, int, int);
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 const struct attribute_spec avr_attribute_table[];
65 static bool avr_assemble_integer (rtx, unsigned int, int);
66 static void avr_file_start (void);
67 static void avr_file_end (void);
68 static void avr_output_function_prologue (FILE *, HOST_WIDE_INT);
69 static void avr_output_function_epilogue (FILE *, HOST_WIDE_INT);
70 static void avr_unique_section (tree, int);
71 static void avr_insert_attributes (tree, tree *);
72 static unsigned int avr_section_type_flags (tree, const char *, int);
73
74 static void avr_reorg (void);
75 static void avr_asm_out_ctor (rtx, int);
76 static void avr_asm_out_dtor (rtx, int);
77 static int default_rtx_costs (rtx, enum rtx_code, enum rtx_code);
78 static bool avr_rtx_costs (rtx, int, int, int *);
79 static int avr_address_cost (rtx);
80
81 /* Allocate registers from r25 to r8 for parameters for function calls. */
82 #define FIRST_CUM_REG 26
83
84 /* Temporary register RTX (gen_rtx (REG,QImode,TMP_REGNO)) */
85 static GTY(()) rtx tmp_reg_rtx;
86
87 /* Zeroed register RTX (gen_rtx (REG,QImode,ZERO_REGNO)) */
88 static GTY(()) rtx zero_reg_rtx;
89
90 /* AVR register names {"r0", "r1", ..., "r31"} */
91 static const char *const avr_regnames[] = REGISTER_NAMES;
92
93 /* This holds the last insn address. */
94 static int last_insn_address = 0;
95
96 /* Commands count in the compiled file */
97 static int commands_in_file;
98
99 /* Commands in the functions prologues in the compiled file */
100 static int commands_in_prologues;
101
102 /* Commands in the functions epilogues in the compiled file */
103 static int commands_in_epilogues;
104
105 /* Prologue/Epilogue size in words */
106 static int prologue_size;
107 static int epilogue_size;
108
109 /* Size of all jump tables in the current function, in words. */
110 static int jump_tables_size;
111
112 /* Initial stack value specified by the `-minit-stack=' option */
113 const char *avr_init_stack = "__stack";
114
115 /* Default MCU name */
116 const char *avr_mcu_name = "avr2";
117
118 /* Preprocessor macros to define depending on MCU type. */
119 const char *avr_base_arch_macro;
120 const char *avr_extra_arch_macro;
121
122 /* More than 8K of program memory: use "call" and "jmp". */
123 int avr_mega_p = 0;
124
125 /* Enhanced core: use "movw", "mul", ... */
126 int avr_enhanced_p = 0;
127
128 /* Assembler only. */
129 int avr_asm_only_p = 0;
130
131 struct base_arch_s {
132 int asm_only;
133 int enhanced;
134 int mega;
135 const char *const macro;
136 };
137
138 static const struct base_arch_s avr_arch_types[] = {
139 { 1, 0, 0, NULL }, /* unknown device specified */
140 { 1, 0, 0, "__AVR_ARCH__=1" },
141 { 0, 0, 0, "__AVR_ARCH__=2" },
142 { 0, 0, 1, "__AVR_ARCH__=3" },
143 { 0, 1, 0, "__AVR_ARCH__=4" },
144 { 0, 1, 1, "__AVR_ARCH__=5" }
145 };
146
147 struct mcu_type_s {
148 const char *const name;
149 int arch; /* index in avr_arch_types[] */
150 /* Must lie outside user's namespace. NULL == no macro. */
151 const char *const macro;
152 };
153
154 /* List of all known AVR MCU types - if updated, it has to be kept
155 in sync in several places (FIXME: is there a better way?):
156 - here
157 - avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
158 - t-avr (MULTILIB_MATCHES)
159 - gas/config/tc-avr.c
160 - avr-libc */
161
162 static const struct mcu_type_s avr_mcu_types[] = {
163 /* Classic, <= 8K. */
164 { "avr2", 2, NULL },
165 { "at90s2313", 2, "__AVR_AT90S2313__" },
166 { "at90s2323", 2, "__AVR_AT90S2323__" },
167 { "at90s2333", 2, "__AVR_AT90S2333__" },
168 { "at90s2343", 2, "__AVR_AT90S2343__" },
169 { "attiny22", 2, "__AVR_ATtiny22__" },
170 { "attiny26", 2, "__AVR_ATtiny26__" },
171 { "at90s4414", 2, "__AVR_AT90S4414__" },
172 { "at90s4433", 2, "__AVR_AT90S4433__" },
173 { "at90s4434", 2, "__AVR_AT90S4434__" },
174 { "at90s8515", 2, "__AVR_AT90S8515__" },
175 { "at90c8534", 2, "__AVR_AT90C8534__" },
176 { "at90s8535", 2, "__AVR_AT90S8535__" },
177 { "at86rf401", 2, "__AVR_AT86RF401__" },
178 /* Classic, > 8K. */
179 { "avr3", 3, NULL },
180 { "atmega103", 3, "__AVR_ATmega103__" },
181 { "atmega603", 3, "__AVR_ATmega603__" },
182 { "at43usb320", 3, "__AVR_AT43USB320__" },
183 { "at43usb355", 3, "__AVR_AT43USB355__" },
184 { "at76c711", 3, "__AVR_AT76C711__" },
185 /* Enhanced, <= 8K. */
186 { "avr4", 4, NULL },
187 { "atmega8", 4, "__AVR_ATmega8__" },
188 { "atmega8515", 4, "__AVR_ATmega8515__" },
189 { "atmega8535", 4, "__AVR_ATmega8535__" },
190 /* Enhanced, > 8K. */
191 { "avr5", 5, NULL },
192 { "atmega16", 5, "__AVR_ATmega16__" },
193 { "atmega161", 5, "__AVR_ATmega161__" },
194 { "atmega162", 5, "__AVR_ATmega162__" },
195 { "atmega163", 5, "__AVR_ATmega163__" },
196 { "atmega169", 5, "__AVR_ATmega169__" },
197 { "atmega32", 5, "__AVR_ATmega32__" },
198 { "atmega323", 5, "__AVR_ATmega323__" },
199 { "atmega64", 5, "__AVR_ATmega64__" },
200 { "atmega128", 5, "__AVR_ATmega128__" },
201 { "at94k", 5, "__AVR_AT94K__" },
202 /* Assembler only. */
203 { "avr1", 1, NULL },
204 { "at90s1200", 1, "__AVR_AT90S1200__" },
205 { "attiny11", 1, "__AVR_ATtiny11__" },
206 { "attiny12", 1, "__AVR_ATtiny12__" },
207 { "attiny15", 1, "__AVR_ATtiny15__" },
208 { "attiny28", 1, "__AVR_ATtiny28__" },
209 { NULL, 0, NULL }
210 };
211
212 int avr_case_values_threshold = 30000;
213 \f
214 /* Initialize the GCC target structure. */
215 #undef TARGET_ASM_ALIGNED_HI_OP
216 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
217 #undef TARGET_ASM_INTEGER
218 #define TARGET_ASM_INTEGER avr_assemble_integer
219 #undef TARGET_ASM_FILE_START
220 #define TARGET_ASM_FILE_START avr_file_start
221 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
222 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
223 #undef TARGET_ASM_FILE_END
224 #define TARGET_ASM_FILE_END avr_file_end
225
226 #undef TARGET_ASM_FUNCTION_PROLOGUE
227 #define TARGET_ASM_FUNCTION_PROLOGUE avr_output_function_prologue
228 #undef TARGET_ASM_FUNCTION_EPILOGUE
229 #define TARGET_ASM_FUNCTION_EPILOGUE avr_output_function_epilogue
230 #undef TARGET_ATTRIBUTE_TABLE
231 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
232 #undef TARGET_ASM_UNIQUE_SECTION
233 #define TARGET_ASM_UNIQUE_SECTION avr_unique_section
234 #undef TARGET_INSERT_ATTRIBUTES
235 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
236 #undef TARGET_SECTION_TYPE_FLAGS
237 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
238 #undef TARGET_RTX_COSTS
239 #define TARGET_RTX_COSTS avr_rtx_costs
240 #undef TARGET_ADDRESS_COST
241 #define TARGET_ADDRESS_COST avr_address_cost
242 #undef TARGET_MACHINE_DEPENDENT_REORG
243 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
244
245 struct gcc_target targetm = TARGET_INITIALIZER;
246 \f
247 void
248 avr_override_options (void)
249 {
250 const struct mcu_type_s *t;
251 const struct base_arch_s *base;
252
253 for (t = avr_mcu_types; t->name; t++)
254 if (strcmp (t->name, avr_mcu_name) == 0)
255 break;
256
257 if (!t->name)
258 {
259 fprintf (stderr, "unknown MCU `%s' specified\nKnown MCU names:\n",
260 avr_mcu_name);
261 for (t = avr_mcu_types; t->name; t++)
262 fprintf (stderr," %s\n", t->name);
263 }
264
265 base = &avr_arch_types[t->arch];
266 avr_asm_only_p = base->asm_only;
267 avr_enhanced_p = base->enhanced;
268 avr_mega_p = base->mega;
269 avr_base_arch_macro = base->macro;
270 avr_extra_arch_macro = t->macro;
271
272 if (optimize && !TARGET_NO_TABLEJUMP)
273 avr_case_values_threshold = (!AVR_MEGA || TARGET_CALL_PROLOGUES) ? 8 : 17;
274
275 tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO);
276 zero_reg_rtx = gen_rtx_REG (QImode, ZERO_REGNO);
277 }
278
279 /* return register class from register number. */
280
281 static const int reg_class_tab[]={
282 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
283 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
284 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
285 GENERAL_REGS, /* r0 - r15 */
286 LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
287 LD_REGS, /* r16 - 23 */
288 ADDW_REGS,ADDW_REGS, /* r24,r25 */
289 POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
290 POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
291 POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
292 STACK_REG,STACK_REG /* SPL,SPH */
293 };
294
295 /* Return register class for register R. */
296
297 enum reg_class
298 avr_regno_reg_class (int r)
299 {
300 if (r <= 33)
301 return reg_class_tab[r];
302 return ALL_REGS;
303 }
304
305
306 /* A C expression which defines the machine-dependent operand
307 constraint letters for register classes. If C is such a
308 letter, the value should be the register class corresponding to
309 it. Otherwise, the value should be `NO_REGS'. The register
310 letter `r', corresponding to class `GENERAL_REGS', will not be
311 passed to this macro; you do not need to handle it. */
312
313 enum reg_class
314 avr_reg_class_from_letter (int c)
315 {
316 switch (c)
317 {
318 case 't' : return R0_REG;
319 case 'b' : return BASE_POINTER_REGS;
320 case 'e' : return POINTER_REGS;
321 case 'w' : return ADDW_REGS;
322 case 'd' : return LD_REGS;
323 case 'l' : return NO_LD_REGS;
324 case 'a' : return SIMPLE_LD_REGS;
325 case 'x' : return POINTER_X_REGS;
326 case 'y' : return POINTER_Y_REGS;
327 case 'z' : return POINTER_Z_REGS;
328 case 'q' : return STACK_REG;
329 default: break;
330 }
331 return NO_REGS;
332 }
333
334 /* Return nonzero if FUNC is a naked function. */
335
336 static int
337 avr_naked_function_p (tree func)
338 {
339 tree a;
340
341 if (TREE_CODE (func) != FUNCTION_DECL)
342 abort ();
343
344 a = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
345 return a != NULL_TREE;
346 }
347
348 /* Return nonzero if FUNC is an interrupt function as specified
349 by the "interrupt" attribute. */
350
351 static int
352 interrupt_function_p (tree func)
353 {
354 tree a;
355
356 if (TREE_CODE (func) != FUNCTION_DECL)
357 return 0;
358
359 a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
360 return a != NULL_TREE;
361 }
362
363 /* Return nonzero if FUNC is a signal function as specified
364 by the "signal" attribute. */
365
366 static int
367 signal_function_p (tree func)
368 {
369 tree a;
370
371 if (TREE_CODE (func) != FUNCTION_DECL)
372 return 0;
373
374 a = lookup_attribute ("signal", DECL_ATTRIBUTES (func));
375 return a != NULL_TREE;
376 }
377
378 /* Return the number of hard registers to push/pop in the prologue/epilogue
379 of the current function, and optionally store these registers in SET. */
380
381 static int
382 avr_regs_to_save (HARD_REG_SET *set)
383 {
384 int reg, count;
385 int int_or_sig_p = (interrupt_function_p (current_function_decl)
386 || signal_function_p (current_function_decl));
387 int leaf_func_p = leaf_function_p ();
388
389 if (set)
390 CLEAR_HARD_REG_SET (*set);
391 count = 0;
392
393 /* No need to save any registers if the function never returns. */
394 if (TREE_THIS_VOLATILE (current_function_decl))
395 return 0;
396
397 for (reg = 0; reg < 32; reg++)
398 {
399 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
400 any global register variables. */
401 if (fixed_regs[reg])
402 continue;
403
404 if ((int_or_sig_p && !leaf_func_p && call_used_regs[reg])
405 || (regs_ever_live[reg]
406 && (int_or_sig_p || !call_used_regs[reg])
407 && !(frame_pointer_needed
408 && (reg == REG_Y || reg == (REG_Y+1)))))
409 {
410 if (set)
411 SET_HARD_REG_BIT (*set, reg);
412 count++;
413 }
414 }
415 return count;
416 }
417
418 /* Compute offset between arg_pointer and frame_pointer. */
419
420 int
421 initial_elimination_offset (int from, int to)
422 {
423 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
424 return 0;
425 else
426 {
427 int offset = frame_pointer_needed ? 2 : 0;
428
429 offset += avr_regs_to_save (NULL);
430 return get_frame_size () + 2 + 1 + offset;
431 }
432 }
433
434 /* Return 1 if the function epilogue is just a single "ret". */
435
436 int
437 avr_simple_epilogue (void)
438 {
439 return (! frame_pointer_needed
440 && get_frame_size () == 0
441 && avr_regs_to_save (NULL) == 0
442 && ! interrupt_function_p (current_function_decl)
443 && ! signal_function_p (current_function_decl)
444 && ! avr_naked_function_p (current_function_decl)
445 && ! MAIN_NAME_P (DECL_NAME (current_function_decl))
446 && ! TREE_THIS_VOLATILE (current_function_decl));
447 }
448
449 /* This function checks sequence of live registers. */
450
451 static int
452 sequent_regs_live (void)
453 {
454 int reg;
455 int live_seq=0;
456 int cur_seq=0;
457
458 for (reg = 0; reg < 18; ++reg)
459 {
460 if (!call_used_regs[reg])
461 {
462 if (regs_ever_live[reg])
463 {
464 ++live_seq;
465 ++cur_seq;
466 }
467 else
468 cur_seq = 0;
469 }
470 }
471
472 if (!frame_pointer_needed)
473 {
474 if (regs_ever_live[REG_Y])
475 {
476 ++live_seq;
477 ++cur_seq;
478 }
479 else
480 cur_seq = 0;
481
482 if (regs_ever_live[REG_Y+1])
483 {
484 ++live_seq;
485 ++cur_seq;
486 }
487 else
488 cur_seq = 0;
489 }
490 else
491 {
492 cur_seq += 2;
493 live_seq += 2;
494 }
495 return (cur_seq == live_seq) ? live_seq : 0;
496 }
497
498
499 /* Output to FILE the asm instructions to adjust the frame pointer by
500 ADJ (r29:r28 -= ADJ;) which can be positive (prologue) or negative
501 (epilogue). Returns the number of instructions generated. */
502
503 static int
504 out_adj_frame_ptr (FILE *file, int adj)
505 {
506 int size = 0;
507
508 if (adj)
509 {
510 if (TARGET_TINY_STACK)
511 {
512 if (adj < -63 || adj > 63)
513 warning ("large frame pointer change (%d) with -mtiny-stack", adj);
514
515 /* The high byte (r29) doesn't change - prefer "subi" (1 cycle)
516 over "sbiw" (2 cycles, same size). */
517
518 fprintf (file, (AS2 (subi, r28, %d) CR_TAB), adj);
519 size++;
520 }
521 else if (adj < -63 || adj > 63)
522 {
523 fprintf (file, (AS2 (subi, r28, lo8(%d)) CR_TAB
524 AS2 (sbci, r29, hi8(%d)) CR_TAB),
525 adj, adj);
526 size += 2;
527 }
528 else if (adj < 0)
529 {
530 fprintf (file, (AS2 (adiw, r28, %d) CR_TAB), -adj);
531 size++;
532 }
533 else
534 {
535 fprintf (file, (AS2 (sbiw, r28, %d) CR_TAB), adj);
536 size++;
537 }
538 }
539 return size;
540 }
541
542
543 /* Output to FILE the asm instructions to copy r29:r28 to SPH:SPL,
544 handling various cases of interrupt enable flag state BEFORE and AFTER
545 (0=disabled, 1=enabled, -1=unknown/unchanged) and target_flags.
546 Returns the number of instructions generated. */
547
548 static int
549 out_set_stack_ptr (FILE *file, int before, int after)
550 {
551 int do_sph, do_cli, do_save, do_sei, lock_sph, size;
552
553 /* The logic here is so that -mno-interrupts actually means
554 "it is safe to write SPH in one instruction, then SPL in the
555 next instruction, without disabling interrupts first".
556 The after != -1 case (interrupt/signal) is not affected. */
557
558 do_sph = !TARGET_TINY_STACK;
559 lock_sph = do_sph && !TARGET_NO_INTERRUPTS;
560 do_cli = (before != 0 && (after == 0 || lock_sph));
561 do_save = (do_cli && before == -1 && after == -1);
562 do_sei = ((do_cli || before != 1) && after == 1);
563 size = 1;
564
565 if (do_save)
566 {
567 fprintf (file, AS2 (in, __tmp_reg__, __SREG__) CR_TAB);
568 size++;
569 }
570
571 if (do_cli)
572 {
573 fprintf (file, "cli" CR_TAB);
574 size++;
575 }
576
577 /* Do SPH first - maybe this will disable interrupts for one instruction
578 someday (a suggestion has been sent to avr@atmel.com for consideration
579 in future devices - that would make -mno-interrupts always safe). */
580 if (do_sph)
581 {
582 fprintf (file, AS2 (out, __SP_H__, r29) CR_TAB);
583 size++;
584 }
585
586 /* Set/restore the I flag now - interrupts will be really enabled only
587 after the next instruction. This is not clearly documented, but
588 believed to be true for all AVR devices. */
589 if (do_save)
590 {
591 fprintf (file, AS2 (out, __SREG__, __tmp_reg__) CR_TAB);
592 size++;
593 }
594 else if (do_sei)
595 {
596 fprintf (file, "sei" CR_TAB);
597 size++;
598 }
599
600 fprintf (file, AS2 (out, __SP_L__, r28) "\n");
601
602 return size;
603 }
604
605
606 /* Output function prologue. */
607
608 static void
609 avr_output_function_prologue (FILE *file, HOST_WIDE_INT size)
610 {
611 int reg;
612 int interrupt_func_p;
613 int signal_func_p;
614 int main_p;
615 int live_seq;
616 int minimize;
617
618 last_insn_address = 0;
619 jump_tables_size = 0;
620 prologue_size = 0;
621 fprintf (file, "/* prologue: frame size=" HOST_WIDE_INT_PRINT_DEC " */\n",
622 size);
623
624 if (avr_naked_function_p (current_function_decl))
625 {
626 fputs ("/* prologue: naked */\n", file);
627 goto out;
628 }
629
630 interrupt_func_p = interrupt_function_p (current_function_decl);
631 signal_func_p = signal_function_p (current_function_decl);
632 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
633 live_seq = sequent_regs_live ();
634 minimize = (TARGET_CALL_PROLOGUES
635 && !interrupt_func_p && !signal_func_p && live_seq);
636
637 if (interrupt_func_p)
638 {
639 fprintf (file,"\tsei\n");
640 ++prologue_size;
641 }
642 if (interrupt_func_p || signal_func_p)
643 {
644 fprintf (file, "\t"
645 AS1 (push,__zero_reg__) CR_TAB
646 AS1 (push,__tmp_reg__) CR_TAB
647 AS2 (in,__tmp_reg__,__SREG__) CR_TAB
648 AS1 (push,__tmp_reg__) CR_TAB
649 AS1 (clr,__zero_reg__) "\n");
650 prologue_size += 5;
651 }
652 if (main_p)
653 {
654 fprintf (file, ("\t"
655 AS1 (ldi,r28) ",lo8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
656 AS1 (ldi,r29) ",hi8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
657 AS2 (out,__SP_H__,r29) CR_TAB
658 AS2 (out,__SP_L__,r28) "\n"),
659 avr_init_stack, size, avr_init_stack, size);
660
661 prologue_size += 4;
662 }
663 else if (minimize && (frame_pointer_needed || live_seq > 6))
664 {
665 fprintf (file, ("\t"
666 AS1 (ldi, r26) ",lo8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
667 AS1 (ldi, r27) ",hi8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB), size, size);
668
669 fprintf (file, (AS2 (ldi, r30, pm_lo8(.L_%s_body)) CR_TAB
670 AS2 (ldi, r31, pm_hi8(.L_%s_body)) CR_TAB)
671 ,current_function_name, current_function_name);
672
673 prologue_size += 4;
674
675 if (AVR_MEGA)
676 {
677 fprintf (file, AS1 (jmp,__prologue_saves__+%d) "\n",
678 (18 - live_seq) * 2);
679 prologue_size += 2;
680 }
681 else
682 {
683 fprintf (file, AS1 (rjmp,__prologue_saves__+%d) "\n",
684 (18 - live_seq) * 2);
685 ++prologue_size;
686 }
687 fprintf (file, ".L_%s_body:\n", current_function_name);
688 }
689 else
690 {
691 HARD_REG_SET set;
692
693 prologue_size += avr_regs_to_save (&set);
694 for (reg = 0; reg < 32; ++reg)
695 {
696 if (TEST_HARD_REG_BIT (set, reg))
697 {
698 fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
699 }
700 }
701 if (frame_pointer_needed)
702 {
703 {
704 fprintf (file, "\t"
705 AS1 (push,r28) CR_TAB
706 AS1 (push,r29) CR_TAB
707 AS2 (in,r28,__SP_L__) CR_TAB
708 AS2 (in,r29,__SP_H__) "\n");
709 prologue_size += 4;
710 if (size)
711 {
712 fputs ("\t", file);
713 prologue_size += out_adj_frame_ptr (file, size);
714
715 if (interrupt_func_p)
716 {
717 prologue_size += out_set_stack_ptr (file, 1, 1);
718 }
719 else if (signal_func_p)
720 {
721 prologue_size += out_set_stack_ptr (file, 0, 0);
722 }
723 else
724 {
725 prologue_size += out_set_stack_ptr (file, -1, -1);
726 }
727 }
728 }
729 }
730 }
731
732 out:
733 fprintf (file, "/* prologue end (size=%d) */\n", prologue_size);
734 }
735
736 /* Output function epilogue. */
737
738 static void
739 avr_output_function_epilogue (FILE *file, HOST_WIDE_INT size)
740 {
741 int reg;
742 int interrupt_func_p;
743 int signal_func_p;
744 int main_p;
745 int function_size;
746 int live_seq;
747 int minimize;
748 rtx last = get_last_nonnote_insn ();
749
750 function_size = jump_tables_size;
751 if (last)
752 {
753 rtx first = get_first_nonnote_insn ();
754 function_size += (INSN_ADDRESSES (INSN_UID (last)) -
755 INSN_ADDRESSES (INSN_UID (first)));
756 function_size += get_attr_length (last);
757 }
758
759 fprintf (file, "/* epilogue: frame size=" HOST_WIDE_INT_PRINT_DEC " */\n", size);
760 epilogue_size = 0;
761
762 if (avr_naked_function_p (current_function_decl))
763 {
764 fputs ("/* epilogue: naked */\n", file);
765 goto out;
766 }
767
768 if (last && GET_CODE (last) == BARRIER)
769 {
770 fputs ("/* epilogue: noreturn */\n", file);
771 goto out;
772 }
773
774 interrupt_func_p = interrupt_function_p (current_function_decl);
775 signal_func_p = signal_function_p (current_function_decl);
776 main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
777 live_seq = sequent_regs_live ();
778 minimize = (TARGET_CALL_PROLOGUES
779 && !interrupt_func_p && !signal_func_p && live_seq);
780
781 if (main_p)
782 {
783 /* Return value from main() is already in the correct registers
784 (r25:r24) as the exit() argument. */
785 if (AVR_MEGA)
786 {
787 fputs ("\t" AS1 (jmp,exit) "\n", file);
788 epilogue_size += 2;
789 }
790 else
791 {
792 fputs ("\t" AS1 (rjmp,exit) "\n", file);
793 ++epilogue_size;
794 }
795 }
796 else if (minimize && (frame_pointer_needed || live_seq > 4))
797 {
798 fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
799 ++epilogue_size;
800 if (frame_pointer_needed)
801 {
802 epilogue_size += out_adj_frame_ptr (file, -size);
803 }
804 else
805 {
806 fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
807 AS2 (in , r29, __SP_H__) CR_TAB));
808 epilogue_size += 2;
809 }
810
811 if (AVR_MEGA)
812 {
813 fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
814 (18 - live_seq) * 2);
815 epilogue_size += 2;
816 }
817 else
818 {
819 fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
820 (18 - live_seq) * 2);
821 ++epilogue_size;
822 }
823 }
824 else
825 {
826 HARD_REG_SET set;
827
828 if (frame_pointer_needed)
829 {
830 if (size)
831 {
832 fputs ("\t", file);
833 epilogue_size += out_adj_frame_ptr (file, -size);
834
835 if (interrupt_func_p || signal_func_p)
836 {
837 epilogue_size += out_set_stack_ptr (file, -1, 0);
838 }
839 else
840 {
841 epilogue_size += out_set_stack_ptr (file, -1, -1);
842 }
843 }
844 fprintf (file, "\t"
845 AS1 (pop,r29) CR_TAB
846 AS1 (pop,r28) "\n");
847 epilogue_size += 2;
848 }
849
850 epilogue_size += avr_regs_to_save (&set);
851 for (reg = 31; reg >= 0; --reg)
852 {
853 if (TEST_HARD_REG_BIT (set, reg))
854 {
855 fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
856 }
857 }
858
859 if (interrupt_func_p || signal_func_p)
860 {
861 fprintf (file, "\t"
862 AS1 (pop,__tmp_reg__) CR_TAB
863 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
864 AS1 (pop,__tmp_reg__) CR_TAB
865 AS1 (pop,__zero_reg__) "\n");
866 epilogue_size += 4;
867 fprintf (file, "\treti\n");
868 }
869 else
870 fprintf (file, "\tret\n");
871 ++epilogue_size;
872 }
873
874 out:
875 fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
876 fprintf (file, "/* function %s size %d (%d) */\n", current_function_name,
877 prologue_size + function_size + epilogue_size, function_size);
878 commands_in_file += prologue_size + function_size + epilogue_size;
879 commands_in_prologues += prologue_size;
880 commands_in_epilogues += epilogue_size;
881 }
882
883
884 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
885 machine for a memory operand of mode MODE. */
886
887 int
888 legitimate_address_p (enum machine_mode mode, rtx x, int strict)
889 {
890 enum reg_class r = NO_REGS;
891
892 if (TARGET_ALL_DEBUG)
893 {
894 fprintf (stderr, "mode: (%s) %s %s %s %s:",
895 GET_MODE_NAME(mode),
896 strict ? "(strict)": "",
897 reload_completed ? "(reload_completed)": "",
898 reload_in_progress ? "(reload_in_progress)": "",
899 reg_renumber ? "(reg_renumber)" : "");
900 if (GET_CODE (x) == PLUS
901 && REG_P (XEXP (x, 0))
902 && GET_CODE (XEXP (x, 1)) == CONST_INT
903 && INTVAL (XEXP (x, 1)) >= 0
904 && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
905 && reg_renumber
906 )
907 fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
908 true_regnum (XEXP (x, 0)));
909 debug_rtx (x);
910 }
911 if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
912 : REG_OK_FOR_BASE_NOSTRICT_P (x)))
913 r = POINTER_REGS;
914 else if (CONSTANT_ADDRESS_P (x))
915 r = ALL_REGS;
916 else if (GET_CODE (x) == PLUS
917 && REG_P (XEXP (x, 0))
918 && GET_CODE (XEXP (x, 1)) == CONST_INT
919 && INTVAL (XEXP (x, 1)) >= 0)
920 {
921 int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
922 if (fit)
923 {
924 if (! strict
925 || REGNO (XEXP (x,0)) == REG_Y
926 || REGNO (XEXP (x,0)) == REG_Z)
927 r = BASE_POINTER_REGS;
928 if (XEXP (x,0) == frame_pointer_rtx
929 || XEXP (x,0) == arg_pointer_rtx)
930 r = BASE_POINTER_REGS;
931 }
932 else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
933 r = POINTER_Y_REGS;
934 }
935 else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
936 && REG_P (XEXP (x, 0))
937 && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
938 : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
939 {
940 r = POINTER_REGS;
941 }
942 if (TARGET_ALL_DEBUG)
943 {
944 fprintf (stderr, " ret = %c\n", r);
945 }
946 return r == NO_REGS ? 0 : (int)r;
947 }
948
949 /* Attempts to replace X with a valid
950 memory address for an operand of mode MODE */
951
952 rtx
953 legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
954 {
955 x = oldx;
956 if (TARGET_ALL_DEBUG)
957 {
958 fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
959 debug_rtx (oldx);
960 }
961
962 if (GET_CODE (oldx) == PLUS
963 && REG_P (XEXP (oldx,0)))
964 {
965 if (REG_P (XEXP (oldx,1)))
966 x = force_reg (GET_MODE (oldx), oldx);
967 else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
968 {
969 int offs = INTVAL (XEXP (oldx,1));
970 if (frame_pointer_rtx != XEXP (oldx,0))
971 if (offs > MAX_LD_OFFSET (mode))
972 {
973 if (TARGET_ALL_DEBUG)
974 fprintf (stderr, "force_reg (big offset)\n");
975 x = force_reg (GET_MODE (oldx), oldx);
976 }
977 }
978 }
979 return x;
980 }
981
982
983 /* Return a pointer register name as a string. */
984
985 static const char *
986 ptrreg_to_str (int regno)
987 {
988 switch (regno)
989 {
990 case REG_X: return "X";
991 case REG_Y: return "Y";
992 case REG_Z: return "Z";
993 default:
994 abort ();
995 }
996 return NULL;
997 }
998
999 /* Return the condition name as a string.
1000 Used in conditional jump constructing */
1001
1002 static const char *
1003 cond_string (enum rtx_code code)
1004 {
1005 switch (code)
1006 {
1007 case NE:
1008 return "ne";
1009 case EQ:
1010 return "eq";
1011 case GE:
1012 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1013 return "pl";
1014 else
1015 return "ge";
1016 case LT:
1017 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1018 return "mi";
1019 else
1020 return "lt";
1021 case GEU:
1022 return "sh";
1023 case LTU:
1024 return "lo";
1025 default:
1026 abort ();
1027 }
1028 }
1029
1030 /* Output ADDR to FILE as address. */
1031
1032 void
1033 print_operand_address (FILE *file, rtx addr)
1034 {
1035 switch (GET_CODE (addr))
1036 {
1037 case REG:
1038 fprintf (file, ptrreg_to_str (REGNO (addr)));
1039 break;
1040
1041 case PRE_DEC:
1042 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1043 break;
1044
1045 case POST_INC:
1046 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1047 break;
1048
1049 default:
1050 if (CONSTANT_ADDRESS_P (addr)
1051 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (addr))
1052 || GET_CODE (addr) == LABEL_REF))
1053 {
1054 fprintf (file, "pm(");
1055 output_addr_const (file,addr);
1056 fprintf (file ,")");
1057 }
1058 else
1059 output_addr_const (file, addr);
1060 }
1061 }
1062
1063
1064 /* Output X as assembler operand to file FILE. */
1065
1066 void
1067 print_operand (FILE *file, rtx x, int code)
1068 {
1069 int abcd = 0;
1070
1071 if (code >= 'A' && code <= 'D')
1072 abcd = code - 'A';
1073
1074 if (code == '~')
1075 {
1076 if (!AVR_MEGA)
1077 fputc ('r', file);
1078 }
1079 else if (REG_P (x))
1080 {
1081 if (x == zero_reg_rtx)
1082 fprintf (file, "__zero_reg__");
1083 else
1084 fprintf (file, reg_names[true_regnum (x) + abcd]);
1085 }
1086 else if (GET_CODE (x) == CONST_INT)
1087 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd);
1088 else if (GET_CODE (x) == MEM)
1089 {
1090 rtx addr = XEXP (x,0);
1091
1092 if (CONSTANT_P (addr) && abcd)
1093 {
1094 fputc ('(', file);
1095 output_address (addr);
1096 fprintf (file, ")+%d", abcd);
1097 }
1098 else if (code == 'o')
1099 {
1100 if (GET_CODE (addr) != PLUS)
1101 fatal_insn ("bad address, not (reg+disp):", addr);
1102
1103 print_operand (file, XEXP (addr, 1), 0);
1104 }
1105 else if (GET_CODE (addr) == PLUS)
1106 {
1107 print_operand_address (file, XEXP (addr,0));
1108 if (REGNO (XEXP (addr, 0)) == REG_X)
1109 fatal_insn ("internal compiler error. Bad address:"
1110 ,addr);
1111 fputc ('+', file);
1112 print_operand (file, XEXP (addr,1), code);
1113 }
1114 else
1115 print_operand_address (file, addr);
1116 }
1117 else if (GET_CODE (x) == CONST_DOUBLE)
1118 {
1119 long val;
1120 REAL_VALUE_TYPE rv;
1121 if (GET_MODE (x) != SFmode)
1122 fatal_insn ("internal compiler error. Unknown mode:", x);
1123 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1124 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1125 fprintf (file, "0x%lx", val);
1126 }
1127 else if (code == 'j')
1128 fputs (cond_string (GET_CODE (x)), file);
1129 else if (code == 'k')
1130 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
1131 else
1132 print_operand_address (file, x);
1133 }
1134
1135 /* Recognize operand OP of mode MODE used in call instructions. */
1136
1137 int
1138 call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1139 {
1140 if (GET_CODE (op) == MEM)
1141 {
1142 rtx inside = XEXP (op, 0);
1143 if (register_operand (inside, Pmode))
1144 return 1;
1145 if (CONSTANT_ADDRESS_P (inside))
1146 return 1;
1147 }
1148 return 0;
1149 }
1150
1151 /* Update the condition code in the INSN. */
1152
1153 void
1154 notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
1155 {
1156 rtx set;
1157
1158 switch (get_attr_cc (insn))
1159 {
1160 case CC_NONE:
1161 /* Insn does not affect CC at all. */
1162 break;
1163
1164 case CC_SET_N:
1165 CC_STATUS_INIT;
1166 break;
1167
1168 case CC_SET_ZN:
1169 set = single_set (insn);
1170 CC_STATUS_INIT;
1171 if (set)
1172 {
1173 cc_status.flags |= CC_NO_OVERFLOW;
1174 cc_status.value1 = SET_DEST (set);
1175 }
1176 break;
1177
1178 case CC_SET_CZN:
1179 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1180 The V flag may or may not be known but that's ok because
1181 alter_cond will change tests to use EQ/NE. */
1182 set = single_set (insn);
1183 CC_STATUS_INIT;
1184 if (set)
1185 {
1186 cc_status.value1 = SET_DEST (set);
1187 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1188 }
1189 break;
1190
1191 case CC_COMPARE:
1192 set = single_set (insn);
1193 CC_STATUS_INIT;
1194 if (set)
1195 cc_status.value1 = SET_SRC (set);
1196 break;
1197
1198 case CC_CLOBBER:
1199 /* Insn doesn't leave CC in a usable state. */
1200 CC_STATUS_INIT;
1201
1202 /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1203 set = single_set (insn);
1204 if (set)
1205 {
1206 rtx src = SET_SRC (set);
1207
1208 if (GET_CODE (src) == ASHIFTRT
1209 && GET_MODE (src) == QImode)
1210 {
1211 rtx x = XEXP (src, 1);
1212
1213 if (GET_CODE (x) == CONST_INT
1214 && INTVAL (x) != 6)
1215 {
1216 cc_status.value1 = SET_DEST (set);
1217 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1218 }
1219 }
1220 }
1221 break;
1222 }
1223 }
1224
1225 /* Return maximum number of consecutive registers of
1226 class CLASS needed to hold a value of mode MODE. */
1227
1228 int
1229 class_max_nregs (enum reg_class class ATTRIBUTE_UNUSED,enum machine_mode mode)
1230 {
1231 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1232 }
1233
1234 /* Choose mode for jump insn:
1235 1 - relative jump in range -63 <= x <= 62 ;
1236 2 - relative jump in range -2046 <= x <= 2045 ;
1237 3 - absolute jump (only for ATmega[16]03). */
1238
1239 int
1240 avr_jump_mode (rtx x, rtx insn)
1241 {
1242 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1243 ? XEXP (x, 0) : x));
1244 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1245 int jump_distance = cur_addr - dest_addr;
1246
1247 if (-63 <= jump_distance && jump_distance <= 62)
1248 return 1;
1249 else if (-2046 <= jump_distance && jump_distance <= 2045)
1250 return 2;
1251 else if (AVR_MEGA)
1252 return 3;
1253
1254 return 2;
1255 }
1256
1257 /* return an AVR condition jump commands.
1258 X is a comparison RTX.
1259 LEN is a number returned by avr_jump_mode function.
1260 if REVERSE nonzero then condition code in X must be reversed. */
1261
1262 const char *
1263 ret_cond_branch (rtx x, int len, int reverse)
1264 {
1265 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1266
1267 switch (cond)
1268 {
1269 case GT:
1270 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1271 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1272 AS1 (brpl,%0)) :
1273 len == 2 ? (AS1 (breq,.+4) CR_TAB
1274 AS1 (brmi,.+2) CR_TAB
1275 AS1 (rjmp,%0)) :
1276 (AS1 (breq,.+6) CR_TAB
1277 AS1 (brmi,.+4) CR_TAB
1278 AS1 (jmp,%0)));
1279
1280 else
1281 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1282 AS1 (brge,%0)) :
1283 len == 2 ? (AS1 (breq,.+4) CR_TAB
1284 AS1 (brlt,.+2) CR_TAB
1285 AS1 (rjmp,%0)) :
1286 (AS1 (breq,.+6) CR_TAB
1287 AS1 (brlt,.+4) CR_TAB
1288 AS1 (jmp,%0)));
1289 case GTU:
1290 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1291 AS1 (brsh,%0)) :
1292 len == 2 ? (AS1 (breq,.+4) CR_TAB
1293 AS1 (brlo,.+2) CR_TAB
1294 AS1 (rjmp,%0)) :
1295 (AS1 (breq,.+6) CR_TAB
1296 AS1 (brlo,.+4) CR_TAB
1297 AS1 (jmp,%0)));
1298 case LE:
1299 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1300 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1301 AS1 (brmi,%0)) :
1302 len == 2 ? (AS1 (breq,.+2) CR_TAB
1303 AS1 (brpl,.+2) CR_TAB
1304 AS1 (rjmp,%0)) :
1305 (AS1 (breq,.+2) CR_TAB
1306 AS1 (brpl,.+4) CR_TAB
1307 AS1 (jmp,%0)));
1308 else
1309 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1310 AS1 (brlt,%0)) :
1311 len == 2 ? (AS1 (breq,.+2) CR_TAB
1312 AS1 (brge,.+2) CR_TAB
1313 AS1 (rjmp,%0)) :
1314 (AS1 (breq,.+2) CR_TAB
1315 AS1 (brge,.+4) CR_TAB
1316 AS1 (jmp,%0)));
1317 case LEU:
1318 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1319 AS1 (brlo,%0)) :
1320 len == 2 ? (AS1 (breq,.+2) CR_TAB
1321 AS1 (brsh,.+2) CR_TAB
1322 AS1 (rjmp,%0)) :
1323 (AS1 (breq,.+2) CR_TAB
1324 AS1 (brsh,.+4) CR_TAB
1325 AS1 (jmp,%0)));
1326 default:
1327 if (reverse)
1328 {
1329 switch (len)
1330 {
1331 case 1:
1332 return AS1 (br%k1,%0);
1333 case 2:
1334 return (AS1 (br%j1,.+2) CR_TAB
1335 AS1 (rjmp,%0));
1336 default:
1337 return (AS1 (br%j1,.+4) CR_TAB
1338 AS1 (jmp,%0));
1339 }
1340 }
1341 else
1342 {
1343 switch (len)
1344 {
1345 case 1:
1346 return AS1 (br%j1,%0);
1347 case 2:
1348 return (AS1 (br%k1,.+2) CR_TAB
1349 AS1 (rjmp,%0));
1350 default:
1351 return (AS1 (br%k1,.+4) CR_TAB
1352 AS1 (jmp,%0));
1353 }
1354 }
1355 }
1356 return "";
1357 }
1358
1359 /* Predicate function for immediate operand which fits to byte (8bit) */
1360
1361 int
1362 byte_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1363 {
1364 return (GET_CODE (op) == CONST_INT
1365 && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1366 }
1367
1368 /* Output all insn addresses and their sizes into the assembly language
1369 output file. This is helpful for debugging whether the length attributes
1370 in the md file are correct.
1371 Output insn cost for next insn. */
1372
1373 void
1374 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
1375 int num_operands ATTRIBUTE_UNUSED)
1376 {
1377 int uid = INSN_UID (insn);
1378
1379 if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1380 {
1381 fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1382 INSN_ADDRESSES (uid),
1383 INSN_ADDRESSES (uid) - last_insn_address,
1384 rtx_cost (PATTERN (insn), INSN));
1385 }
1386 last_insn_address = INSN_ADDRESSES (uid);
1387 }
1388
1389 /* Return 0 if undefined, 1 if always true or always false. */
1390
1391 int
1392 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE operator, rtx x)
1393 {
1394 unsigned int max = (mode == QImode ? 0xff :
1395 mode == HImode ? 0xffff :
1396 mode == SImode ? 0xffffffff : 0);
1397 if (max && operator && GET_CODE (x) == CONST_INT)
1398 {
1399 if (unsigned_condition (operator) != operator)
1400 max >>= 1;
1401
1402 if (max != (INTVAL (x) & max)
1403 && INTVAL (x) != 0xff)
1404 return 1;
1405 }
1406 return 0;
1407 }
1408
1409
1410 /* Returns nonzero if REGNO is the number of a hard
1411 register in which function arguments are sometimes passed. */
1412
1413 int
1414 function_arg_regno_p(int r)
1415 {
1416 return (r >= 8 && r <= 25);
1417 }
1418
1419 /* Initializing the variable cum for the state at the beginning
1420 of the argument list. */
1421
1422 void
1423 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
1424 tree fndecl ATTRIBUTE_UNUSED)
1425 {
1426 cum->nregs = 18;
1427 cum->regno = FIRST_CUM_REG;
1428 if (!libname && fntype)
1429 {
1430 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1431 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1432 != void_type_node));
1433 if (stdarg)
1434 cum->nregs = 0;
1435 }
1436 }
1437
1438 /* Returns the number of registers to allocate for a function argument. */
1439
1440 static int
1441 avr_num_arg_regs (enum machine_mode mode, tree type)
1442 {
1443 int size;
1444
1445 if (mode == BLKmode)
1446 size = int_size_in_bytes (type);
1447 else
1448 size = GET_MODE_SIZE (mode);
1449
1450 /* Align all function arguments to start in even-numbered registers.
1451 Odd-sized arguments leave holes above them. */
1452
1453 return (size + 1) & ~1;
1454 }
1455
1456 /* Controls whether a function argument is passed
1457 in a register, and which register. */
1458
1459 rtx
1460 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1461 int named ATTRIBUTE_UNUSED)
1462 {
1463 int bytes = avr_num_arg_regs (mode, type);
1464
1465 if (cum->nregs && bytes <= cum->nregs)
1466 return gen_rtx (REG, mode, cum->regno - bytes);
1467
1468 return NULL_RTX;
1469 }
1470
1471 /* Update the summarizer variable CUM to advance past an argument
1472 in the argument list. */
1473
1474 void
1475 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1476 int named ATTRIBUTE_UNUSED)
1477 {
1478 int bytes = avr_num_arg_regs (mode, type);
1479
1480 cum->nregs -= bytes;
1481 cum->regno -= bytes;
1482
1483 if (cum->nregs <= 0)
1484 {
1485 cum->nregs = 0;
1486 cum->regno = FIRST_CUM_REG;
1487 }
1488 }
1489
1490 /***********************************************************************
1491 Functions for outputting various mov's for a various modes
1492 ************************************************************************/
1493 const char *
1494 output_movqi (rtx insn, rtx operands[], int *l)
1495 {
1496 int dummy;
1497 rtx dest = operands[0];
1498 rtx src = operands[1];
1499 int *real_l = l;
1500
1501 if (!l)
1502 l = &dummy;
1503
1504 *l = 1;
1505
1506 if (register_operand (dest, QImode))
1507 {
1508 if (register_operand (src, QImode)) /* mov r,r */
1509 {
1510 if (test_hard_reg_class (STACK_REG, dest))
1511 return AS2 (out,%0,%1);
1512 else if (test_hard_reg_class (STACK_REG, src))
1513 return AS2 (in,%0,%1);
1514
1515 return AS2 (mov,%0,%1);
1516 }
1517 else if (CONSTANT_P (src))
1518 {
1519 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1520 return AS2 (ldi,%0,lo8(%1));
1521
1522 if (GET_CODE (src) == CONST_INT)
1523 {
1524 if (src == const0_rtx) /* mov r,L */
1525 return AS1 (clr,%0);
1526 else if (src == const1_rtx)
1527 {
1528 *l = 2;
1529 return (AS1 (clr,%0) CR_TAB
1530 AS1 (inc,%0));
1531 }
1532 else if (src == constm1_rtx)
1533 {
1534 /* Immediate constants -1 to any register */
1535 *l = 2;
1536 return (AS1 (clr,%0) CR_TAB
1537 AS1 (dec,%0));
1538 }
1539 else
1540 {
1541 int bit_nr = exact_log2 (INTVAL (src));
1542
1543 if (bit_nr >= 0)
1544 {
1545 *l = 3;
1546 if (!real_l)
1547 output_asm_insn ((AS1 (clr,%0) CR_TAB
1548 "set"), operands);
1549 if (!real_l)
1550 avr_output_bld (operands, bit_nr);
1551
1552 return "";
1553 }
1554 }
1555 }
1556
1557 /* Last resort, larger than loading from memory. */
1558 *l = 4;
1559 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1560 AS2 (ldi,r31,lo8(%1)) CR_TAB
1561 AS2 (mov,%0,r31) CR_TAB
1562 AS2 (mov,r31,__tmp_reg__));
1563 }
1564 else if (GET_CODE (src) == MEM)
1565 return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1566 }
1567 else if (GET_CODE (dest) == MEM)
1568 {
1569 const char *template;
1570
1571 if (src == const0_rtx)
1572 operands[1] = zero_reg_rtx;
1573
1574 template = out_movqi_mr_r (insn, operands, real_l);
1575
1576 if (!real_l)
1577 output_asm_insn (template, operands);
1578
1579 operands[1] = src;
1580 }
1581 return "";
1582 }
1583
1584
1585 const char *
1586 output_movhi (rtx insn, rtx operands[], int *l)
1587 {
1588 int dummy;
1589 rtx dest = operands[0];
1590 rtx src = operands[1];
1591 int *real_l = l;
1592
1593 if (!l)
1594 l = &dummy;
1595
1596 if (register_operand (dest, HImode))
1597 {
1598 if (register_operand (src, HImode)) /* mov r,r */
1599 {
1600 if (test_hard_reg_class (STACK_REG, dest))
1601 {
1602 if (TARGET_TINY_STACK)
1603 {
1604 *l = 1;
1605 return AS2 (out,__SP_L__,%A1);
1606 }
1607 else if (TARGET_NO_INTERRUPTS)
1608 {
1609 *l = 2;
1610 return (AS2 (out,__SP_H__,%B1) CR_TAB
1611 AS2 (out,__SP_L__,%A1));
1612 }
1613
1614 *l = 5;
1615 return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB
1616 "cli" CR_TAB
1617 AS2 (out,__SP_H__,%B1) CR_TAB
1618 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1619 AS2 (out,__SP_L__,%A1));
1620 }
1621 else if (test_hard_reg_class (STACK_REG, src))
1622 {
1623 *l = 2;
1624 return (AS2 (in,%A0,__SP_L__) CR_TAB
1625 AS2 (in,%B0,__SP_H__));
1626 }
1627
1628 if (AVR_ENHANCED)
1629 {
1630 *l = 1;
1631 return (AS2 (movw,%0,%1));
1632 }
1633
1634 if (true_regnum (dest) > true_regnum (src))
1635 {
1636 *l = 2;
1637 return (AS2 (mov,%B0,%B1) CR_TAB
1638 AS2 (mov,%A0,%A1));
1639 }
1640 else
1641 {
1642 *l = 2;
1643 return (AS2 (mov,%A0,%A1) CR_TAB
1644 AS2 (mov,%B0,%B1));
1645 }
1646 }
1647 else if (CONSTANT_P (src))
1648 {
1649 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1650 {
1651 *l = 2;
1652 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1653 AS2 (ldi,%B0,hi8(%1)));
1654 }
1655
1656 if (GET_CODE (src) == CONST_INT)
1657 {
1658 if (src == const0_rtx) /* mov r,L */
1659 {
1660 *l = 2;
1661 return (AS1 (clr,%A0) CR_TAB
1662 AS1 (clr,%B0));
1663 }
1664 else if (src == const1_rtx)
1665 {
1666 *l = 3;
1667 return (AS1 (clr,%A0) CR_TAB
1668 AS1 (clr,%B0) CR_TAB
1669 AS1 (inc,%A0));
1670 }
1671 else if (src == constm1_rtx)
1672 {
1673 /* Immediate constants -1 to any register */
1674 *l = 3;
1675 return (AS1 (clr,%0) CR_TAB
1676 AS1 (dec,%A0) CR_TAB
1677 AS2 (mov,%B0,%A0));
1678 }
1679 else
1680 {
1681 int bit_nr = exact_log2 (INTVAL (src));
1682
1683 if (bit_nr >= 0)
1684 {
1685 *l = 4;
1686 if (!real_l)
1687 output_asm_insn ((AS1 (clr,%A0) CR_TAB
1688 AS1 (clr,%B0) CR_TAB
1689 "set"), operands);
1690 if (!real_l)
1691 avr_output_bld (operands, bit_nr);
1692
1693 return "";
1694 }
1695 }
1696
1697 if ((INTVAL (src) & 0xff) == 0)
1698 {
1699 *l = 5;
1700 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1701 AS1 (clr,%A0) CR_TAB
1702 AS2 (ldi,r31,hi8(%1)) CR_TAB
1703 AS2 (mov,%B0,r31) CR_TAB
1704 AS2 (mov,r31,__tmp_reg__));
1705 }
1706 else if ((INTVAL (src) & 0xff00) == 0)
1707 {
1708 *l = 5;
1709 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1710 AS2 (ldi,r31,lo8(%1)) CR_TAB
1711 AS2 (mov,%A0,r31) CR_TAB
1712 AS1 (clr,%B0) CR_TAB
1713 AS2 (mov,r31,__tmp_reg__));
1714 }
1715 }
1716
1717 /* Last resort, equal to loading from memory. */
1718 *l = 6;
1719 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1720 AS2 (ldi,r31,lo8(%1)) CR_TAB
1721 AS2 (mov,%A0,r31) CR_TAB
1722 AS2 (ldi,r31,hi8(%1)) CR_TAB
1723 AS2 (mov,%B0,r31) CR_TAB
1724 AS2 (mov,r31,__tmp_reg__));
1725 }
1726 else if (GET_CODE (src) == MEM)
1727 return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1728 }
1729 else if (GET_CODE (dest) == MEM)
1730 {
1731 const char *template;
1732
1733 if (src == const0_rtx)
1734 operands[1] = zero_reg_rtx;
1735
1736 template = out_movhi_mr_r (insn, operands, real_l);
1737
1738 if (!real_l)
1739 output_asm_insn (template, operands);
1740
1741 operands[1] = src;
1742 return "";
1743 }
1744 fatal_insn ("invalid insn:", insn);
1745 return "";
1746 }
1747
1748 const char *
1749 out_movqi_r_mr (rtx insn, rtx op[], int *l)
1750 {
1751 rtx dest = op[0];
1752 rtx src = op[1];
1753 rtx x = XEXP (src, 0);
1754 int dummy;
1755
1756 if (!l)
1757 l = &dummy;
1758
1759 if (CONSTANT_ADDRESS_P (x))
1760 {
1761 if (avr_io_address_p (x, 1))
1762 {
1763 *l = 1;
1764 return AS2 (in,%0,%1-0x20);
1765 }
1766 *l = 2;
1767 return AS2 (lds,%0,%1);
1768 }
1769 /* memory access by reg+disp */
1770 else if (GET_CODE (x) == PLUS
1771 && REG_P (XEXP (x,0))
1772 && GET_CODE (XEXP (x,1)) == CONST_INT)
1773 {
1774 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1775 {
1776 int disp = INTVAL (XEXP (x,1));
1777 if (REGNO (XEXP (x,0)) != REG_Y)
1778 fatal_insn ("incorrect insn:",insn);
1779
1780 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1781 return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
1782 AS2 (ldd,%0,Y+63) CR_TAB
1783 AS2 (sbiw,r28,%o1-63));
1784
1785 return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1786 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1787 AS2 (ld,%0,Y) CR_TAB
1788 AS2 (subi,r28,lo8(%o1)) CR_TAB
1789 AS2 (sbci,r29,hi8(%o1)));
1790 }
1791 else if (REGNO (XEXP (x,0)) == REG_X)
1792 {
1793 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1794 it but I have this situation with extremal optimizing options. */
1795 if (reg_overlap_mentioned_p (dest, XEXP (x,0))
1796 || reg_unused_after (insn, XEXP (x,0)))
1797 return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
1798 AS2 (ld,%0,X));
1799
1800 return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
1801 AS2 (ld,%0,X) CR_TAB
1802 AS2 (sbiw,r26,%o1));
1803 }
1804 *l = 1;
1805 return AS2 (ldd,%0,%1);
1806 }
1807 *l = 1;
1808 return AS2 (ld,%0,%1);
1809 }
1810
1811 const char *
1812 out_movhi_r_mr (rtx insn, rtx op[], int *l)
1813 {
1814 rtx dest = op[0];
1815 rtx src = op[1];
1816 rtx base = XEXP (src, 0);
1817 int reg_dest = true_regnum (dest);
1818 int reg_base = true_regnum (base);
1819 int tmp;
1820
1821 if (!l)
1822 l = &tmp;
1823
1824 if (reg_base > 0)
1825 {
1826 if (reg_dest == reg_base) /* R = (R) */
1827 {
1828 *l = 3;
1829 return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1830 AS2 (ld,%B0,%1) CR_TAB
1831 AS2 (mov,%A0,__tmp_reg__));
1832 }
1833 else if (reg_base == REG_X) /* (R26) */
1834 {
1835 if (reg_unused_after (insn, base))
1836 {
1837 *l = 2;
1838 return (AS2 (ld,%A0,X+) CR_TAB
1839 AS2 (ld,%B0,X));
1840 }
1841 *l = 3;
1842 return (AS2 (ld,%A0,X+) CR_TAB
1843 AS2 (ld,%B0,X) CR_TAB
1844 AS2 (sbiw,r26,1));
1845 }
1846 else /* (R) */
1847 {
1848 *l = 2;
1849 return (AS2 (ld,%A0,%1) CR_TAB
1850 AS2 (ldd,%B0,%1+1));
1851 }
1852 }
1853 else if (GET_CODE (base) == PLUS) /* (R + i) */
1854 {
1855 int disp = INTVAL (XEXP (base, 1));
1856 int reg_base = true_regnum (XEXP (base, 0));
1857
1858 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
1859 {
1860 if (REGNO (XEXP (base, 0)) != REG_Y)
1861 fatal_insn ("incorrect insn:",insn);
1862
1863 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1864 return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
1865 AS2 (ldd,%A0,Y+62) CR_TAB
1866 AS2 (ldd,%B0,Y+63) CR_TAB
1867 AS2 (sbiw,r28,%o1-62));
1868
1869 return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1870 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1871 AS2 (ld,%A0,Y) CR_TAB
1872 AS2 (ldd,%B0,Y+1) CR_TAB
1873 AS2 (subi,r28,lo8(%o1)) CR_TAB
1874 AS2 (sbci,r29,hi8(%o1)));
1875 }
1876 if (reg_base == REG_X)
1877 {
1878 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1879 it but I have this situation with extremal
1880 optimization options. */
1881
1882 *l = 4;
1883 if (reg_base == reg_dest)
1884 return (AS2 (adiw,r26,%o1) CR_TAB
1885 AS2 (ld,__tmp_reg__,X+) CR_TAB
1886 AS2 (ld,%B0,X) CR_TAB
1887 AS2 (mov,%A0,__tmp_reg__));
1888
1889 return (AS2 (adiw,r26,%o1) CR_TAB
1890 AS2 (ld,%A0,X+) CR_TAB
1891 AS2 (ld,%B0,X) CR_TAB
1892 AS2 (sbiw,r26,%o1+1));
1893 }
1894
1895 if (reg_base == reg_dest)
1896 {
1897 *l = 3;
1898 return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
1899 AS2 (ldd,%B0,%B1) CR_TAB
1900 AS2 (mov,%A0,__tmp_reg__));
1901 }
1902
1903 *l = 2;
1904 return (AS2 (ldd,%A0,%A1) CR_TAB
1905 AS2 (ldd,%B0,%B1));
1906 }
1907 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
1908 {
1909 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1910 fatal_insn ("incorrect insn:", insn);
1911
1912 *l = 2;
1913 return (AS2 (ld,%B0,%1) CR_TAB
1914 AS2 (ld,%A0,%1));
1915 }
1916 else if (GET_CODE (base) == POST_INC) /* (R++) */
1917 {
1918 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1919 fatal_insn ("incorrect insn:", insn);
1920
1921 *l = 2;
1922 return (AS2 (ld,%A0,%1) CR_TAB
1923 AS2 (ld,%B0,%1));
1924 }
1925 else if (CONSTANT_ADDRESS_P (base))
1926 {
1927 if (avr_io_address_p (base, 2))
1928 {
1929 *l = 2;
1930 return (AS2 (in,%A0,%A1-0x20) CR_TAB
1931 AS2 (in,%B0,%B1-0x20));
1932 }
1933 *l = 4;
1934 return (AS2 (lds,%A0,%A1) CR_TAB
1935 AS2 (lds,%B0,%B1));
1936 }
1937
1938 fatal_insn ("unknown move insn:",insn);
1939 return "";
1940 }
1941
1942 const char *
1943 out_movsi_r_mr (rtx insn, rtx op[], int *l)
1944 {
1945 rtx dest = op[0];
1946 rtx src = op[1];
1947 rtx base = XEXP (src, 0);
1948 int reg_dest = true_regnum (dest);
1949 int reg_base = true_regnum (base);
1950 int tmp;
1951
1952 if (!l)
1953 l = &tmp;
1954
1955 if (reg_base > 0)
1956 {
1957 if (reg_base == REG_X) /* (R26) */
1958 {
1959 if (reg_dest == REG_X)
1960 /* "ld r26,-X" is undefined */
1961 return *l=7, (AS2 (adiw,r26,3) CR_TAB
1962 AS2 (ld,r29,X) CR_TAB
1963 AS2 (ld,r28,-X) CR_TAB
1964 AS2 (ld,__tmp_reg__,-X) CR_TAB
1965 AS2 (sbiw,r26,1) CR_TAB
1966 AS2 (ld,r26,X) CR_TAB
1967 AS2 (mov,r27,__tmp_reg__));
1968 else if (reg_dest == REG_X - 2)
1969 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
1970 AS2 (ld,%B0,X+) CR_TAB
1971 AS2 (ld,__tmp_reg__,X+) CR_TAB
1972 AS2 (ld,%D0,X) CR_TAB
1973 AS2 (mov,%C0,__tmp_reg__));
1974 else if (reg_unused_after (insn, base))
1975 return *l=4, (AS2 (ld,%A0,X+) CR_TAB
1976 AS2 (ld,%B0,X+) CR_TAB
1977 AS2 (ld,%C0,X+) CR_TAB
1978 AS2 (ld,%D0,X));
1979 else
1980 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
1981 AS2 (ld,%B0,X+) CR_TAB
1982 AS2 (ld,%C0,X+) CR_TAB
1983 AS2 (ld,%D0,X) CR_TAB
1984 AS2 (sbiw,r26,3));
1985 }
1986 else
1987 {
1988 if (reg_dest == reg_base)
1989 return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
1990 AS2 (ldd,%C0,%1+2) CR_TAB
1991 AS2 (ldd,__tmp_reg__,%1+1) CR_TAB
1992 AS2 (ld,%A0,%1) CR_TAB
1993 AS2 (mov,%B0,__tmp_reg__));
1994 else if (reg_base == reg_dest + 2)
1995 return *l=5, (AS2 (ld ,%A0,%1) CR_TAB
1996 AS2 (ldd,%B0,%1+1) CR_TAB
1997 AS2 (ldd,__tmp_reg__,%1+2) CR_TAB
1998 AS2 (ldd,%D0,%1+3) CR_TAB
1999 AS2 (mov,%C0,__tmp_reg__));
2000 else
2001 return *l=4, (AS2 (ld ,%A0,%1) CR_TAB
2002 AS2 (ldd,%B0,%1+1) CR_TAB
2003 AS2 (ldd,%C0,%1+2) CR_TAB
2004 AS2 (ldd,%D0,%1+3));
2005 }
2006 }
2007 else if (GET_CODE (base) == PLUS) /* (R + i) */
2008 {
2009 int disp = INTVAL (XEXP (base, 1));
2010
2011 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2012 {
2013 if (REGNO (XEXP (base, 0)) != REG_Y)
2014 fatal_insn ("incorrect insn:",insn);
2015
2016 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2017 return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2018 AS2 (ldd,%A0,Y+60) CR_TAB
2019 AS2 (ldd,%B0,Y+61) CR_TAB
2020 AS2 (ldd,%C0,Y+62) CR_TAB
2021 AS2 (ldd,%D0,Y+63) CR_TAB
2022 AS2 (sbiw,r28,%o1-60));
2023
2024 return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2025 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2026 AS2 (ld,%A0,Y) CR_TAB
2027 AS2 (ldd,%B0,Y+1) CR_TAB
2028 AS2 (ldd,%C0,Y+2) CR_TAB
2029 AS2 (ldd,%D0,Y+3) CR_TAB
2030 AS2 (subi,r28,lo8(%o1)) CR_TAB
2031 AS2 (sbci,r29,hi8(%o1)));
2032 }
2033
2034 reg_base = true_regnum (XEXP (base, 0));
2035 if (reg_base == REG_X)
2036 {
2037 /* R = (X + d) */
2038 if (reg_dest == REG_X)
2039 {
2040 *l = 7;
2041 /* "ld r26,-X" is undefined */
2042 return (AS2 (adiw,r26,%o1+3) CR_TAB
2043 AS2 (ld,r29,X) CR_TAB
2044 AS2 (ld,r28,-X) CR_TAB
2045 AS2 (ld,__tmp_reg__,-X) CR_TAB
2046 AS2 (sbiw,r26,1) CR_TAB
2047 AS2 (ld,r26,X) CR_TAB
2048 AS2 (mov,r27,__tmp_reg__));
2049 }
2050 *l = 6;
2051 if (reg_dest == REG_X - 2)
2052 return (AS2 (adiw,r26,%o1) CR_TAB
2053 AS2 (ld,r24,X+) CR_TAB
2054 AS2 (ld,r25,X+) CR_TAB
2055 AS2 (ld,__tmp_reg__,X+) CR_TAB
2056 AS2 (ld,r27,X) CR_TAB
2057 AS2 (mov,r26,__tmp_reg__));
2058
2059 return (AS2 (adiw,r26,%o1) CR_TAB
2060 AS2 (ld,%A0,X+) CR_TAB
2061 AS2 (ld,%B0,X+) CR_TAB
2062 AS2 (ld,%C0,X+) CR_TAB
2063 AS2 (ld,%D0,X) CR_TAB
2064 AS2 (sbiw,r26,%o1+3));
2065 }
2066 if (reg_dest == reg_base)
2067 return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2068 AS2 (ldd,%C0,%C1) CR_TAB
2069 AS2 (ldd,__tmp_reg__,%B1) CR_TAB
2070 AS2 (ldd,%A0,%A1) CR_TAB
2071 AS2 (mov,%B0,__tmp_reg__));
2072 else if (reg_dest == reg_base - 2)
2073 return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2074 AS2 (ldd,%B0,%B1) CR_TAB
2075 AS2 (ldd,__tmp_reg__,%C1) CR_TAB
2076 AS2 (ldd,%D0,%D1) CR_TAB
2077 AS2 (mov,%C0,__tmp_reg__));
2078 return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2079 AS2 (ldd,%B0,%B1) CR_TAB
2080 AS2 (ldd,%C0,%C1) CR_TAB
2081 AS2 (ldd,%D0,%D1));
2082 }
2083 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2084 return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2085 AS2 (ld,%C0,%1) CR_TAB
2086 AS2 (ld,%B0,%1) CR_TAB
2087 AS2 (ld,%A0,%1));
2088 else if (GET_CODE (base) == POST_INC) /* (R++) */
2089 return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2090 AS2 (ld,%B0,%1) CR_TAB
2091 AS2 (ld,%C0,%1) CR_TAB
2092 AS2 (ld,%D0,%1));
2093 else if (CONSTANT_ADDRESS_P (base))
2094 return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2095 AS2 (lds,%B0,%B1) CR_TAB
2096 AS2 (lds,%C0,%C1) CR_TAB
2097 AS2 (lds,%D0,%D1));
2098
2099 fatal_insn ("unknown move insn:",insn);
2100 return "";
2101 }
2102
2103 const char *
2104 out_movsi_mr_r (rtx insn, rtx op[], int *l)
2105 {
2106 rtx dest = op[0];
2107 rtx src = op[1];
2108 rtx base = XEXP (dest, 0);
2109 int reg_base = true_regnum (base);
2110 int reg_src = true_regnum (src);
2111 int tmp;
2112
2113 if (!l)
2114 l = &tmp;
2115
2116 if (CONSTANT_ADDRESS_P (base))
2117 return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2118 AS2 (sts,%B0,%B1) CR_TAB
2119 AS2 (sts,%C0,%C1) CR_TAB
2120 AS2 (sts,%D0,%D1));
2121 if (reg_base > 0) /* (r) */
2122 {
2123 if (reg_base == REG_X) /* (R26) */
2124 {
2125 if (reg_src == REG_X)
2126 {
2127 /* "st X+,r26" is undefined */
2128 if (reg_unused_after (insn, base))
2129 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2130 AS2 (st,X,r26) CR_TAB
2131 AS2 (adiw,r26,1) CR_TAB
2132 AS2 (st,X+,__tmp_reg__) CR_TAB
2133 AS2 (st,X+,r28) CR_TAB
2134 AS2 (st,X,r29));
2135 else
2136 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2137 AS2 (st,X,r26) CR_TAB
2138 AS2 (adiw,r26,1) CR_TAB
2139 AS2 (st,X+,__tmp_reg__) CR_TAB
2140 AS2 (st,X+,r28) CR_TAB
2141 AS2 (st,X,r29) CR_TAB
2142 AS2 (sbiw,r26,3));
2143 }
2144 else if (reg_base == reg_src + 2)
2145 {
2146 if (reg_unused_after (insn, base))
2147 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2148 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2149 AS2 (st,%0+,%A1) CR_TAB
2150 AS2 (st,%0+,%B1) CR_TAB
2151 AS2 (st,%0+,__zero_reg__) CR_TAB
2152 AS2 (st,%0,__tmp_reg__) CR_TAB
2153 AS1 (clr,__zero_reg__));
2154 else
2155 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2156 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2157 AS2 (st,%0+,%A1) CR_TAB
2158 AS2 (st,%0+,%B1) CR_TAB
2159 AS2 (st,%0+,__zero_reg__) CR_TAB
2160 AS2 (st,%0,__tmp_reg__) CR_TAB
2161 AS1 (clr,__zero_reg__) CR_TAB
2162 AS2 (sbiw,r26,3));
2163 }
2164 return *l=5, (AS2 (st,%0+,%A1) CR_TAB
2165 AS2 (st,%0+,%B1) CR_TAB
2166 AS2 (st,%0+,%C1) CR_TAB
2167 AS2 (st,%0,%D1) CR_TAB
2168 AS2 (sbiw,r26,3));
2169 }
2170 else
2171 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2172 AS2 (std,%0+1,%B1) CR_TAB
2173 AS2 (std,%0+2,%C1) CR_TAB
2174 AS2 (std,%0+3,%D1));
2175 }
2176 else if (GET_CODE (base) == PLUS) /* (R + i) */
2177 {
2178 int disp = INTVAL (XEXP (base, 1));
2179 reg_base = REGNO (XEXP (base, 0));
2180 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2181 {
2182 if (reg_base != REG_Y)
2183 fatal_insn ("incorrect insn:",insn);
2184
2185 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2186 return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2187 AS2 (std,Y+60,%A1) CR_TAB
2188 AS2 (std,Y+61,%B1) CR_TAB
2189 AS2 (std,Y+62,%C1) CR_TAB
2190 AS2 (std,Y+63,%D1) CR_TAB
2191 AS2 (sbiw,r28,%o0-60));
2192
2193 return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2194 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2195 AS2 (st,Y,%A1) CR_TAB
2196 AS2 (std,Y+1,%B1) CR_TAB
2197 AS2 (std,Y+2,%C1) CR_TAB
2198 AS2 (std,Y+3,%D1) CR_TAB
2199 AS2 (subi,r28,lo8(%o0)) CR_TAB
2200 AS2 (sbci,r29,hi8(%o0)));
2201 }
2202 if (reg_base == REG_X)
2203 {
2204 /* (X + d) = R */
2205 if (reg_src == REG_X)
2206 {
2207 *l = 9;
2208 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2209 AS2 (mov,__zero_reg__,r27) CR_TAB
2210 AS2 (adiw,r26,%o0) CR_TAB
2211 AS2 (st,X+,__tmp_reg__) CR_TAB
2212 AS2 (st,X+,__zero_reg__) CR_TAB
2213 AS2 (st,X+,r28) CR_TAB
2214 AS2 (st,X,r29) CR_TAB
2215 AS1 (clr,__zero_reg__) CR_TAB
2216 AS2 (sbiw,r26,%o0+3));
2217 }
2218 else if (reg_src == REG_X - 2)
2219 {
2220 *l = 9;
2221 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2222 AS2 (mov,__zero_reg__,r27) CR_TAB
2223 AS2 (adiw,r26,%o0) CR_TAB
2224 AS2 (st,X+,r24) CR_TAB
2225 AS2 (st,X+,r25) CR_TAB
2226 AS2 (st,X+,__tmp_reg__) CR_TAB
2227 AS2 (st,X,__zero_reg__) CR_TAB
2228 AS1 (clr,__zero_reg__) CR_TAB
2229 AS2 (sbiw,r26,%o0+3));
2230 }
2231 *l = 6;
2232 return (AS2 (adiw,r26,%o0) CR_TAB
2233 AS2 (st,X+,%A1) CR_TAB
2234 AS2 (st,X+,%B1) CR_TAB
2235 AS2 (st,X+,%C1) CR_TAB
2236 AS2 (st,X,%D1) CR_TAB
2237 AS2 (sbiw,r26,%o0+3));
2238 }
2239 return *l=4, (AS2 (std,%A0,%A1) CR_TAB
2240 AS2 (std,%B0,%B1) CR_TAB
2241 AS2 (std,%C0,%C1) CR_TAB
2242 AS2 (std,%D0,%D1));
2243 }
2244 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2245 return *l=4, (AS2 (st,%0,%D1) CR_TAB
2246 AS2 (st,%0,%C1) CR_TAB
2247 AS2 (st,%0,%B1) CR_TAB
2248 AS2 (st,%0,%A1));
2249 else if (GET_CODE (base) == POST_INC) /* (R++) */
2250 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2251 AS2 (st,%0,%B1) CR_TAB
2252 AS2 (st,%0,%C1) CR_TAB
2253 AS2 (st,%0,%D1));
2254 fatal_insn ("unknown move insn:",insn);
2255 return "";
2256 }
2257
2258 const char *
2259 output_movsisf(rtx insn, rtx operands[], int *l)
2260 {
2261 int dummy;
2262 rtx dest = operands[0];
2263 rtx src = operands[1];
2264 int *real_l = l;
2265
2266 if (!l)
2267 l = &dummy;
2268
2269 if (register_operand (dest, VOIDmode))
2270 {
2271 if (register_operand (src, VOIDmode)) /* mov r,r */
2272 {
2273 if (true_regnum (dest) > true_regnum (src))
2274 {
2275 if (AVR_ENHANCED)
2276 {
2277 *l = 2;
2278 return (AS2 (movw,%C0,%C1) CR_TAB
2279 AS2 (movw,%A0,%A1));
2280 }
2281 *l = 4;
2282 return (AS2 (mov,%D0,%D1) CR_TAB
2283 AS2 (mov,%C0,%C1) CR_TAB
2284 AS2 (mov,%B0,%B1) CR_TAB
2285 AS2 (mov,%A0,%A1));
2286 }
2287 else
2288 {
2289 if (AVR_ENHANCED)
2290 {
2291 *l = 2;
2292 return (AS2 (movw,%A0,%A1) CR_TAB
2293 AS2 (movw,%C0,%C1));
2294 }
2295 *l = 4;
2296 return (AS2 (mov,%A0,%A1) CR_TAB
2297 AS2 (mov,%B0,%B1) CR_TAB
2298 AS2 (mov,%C0,%C1) CR_TAB
2299 AS2 (mov,%D0,%D1));
2300 }
2301 }
2302 else if (CONSTANT_P (src))
2303 {
2304 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2305 {
2306 *l = 4;
2307 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
2308 AS2 (ldi,%B0,hi8(%1)) CR_TAB
2309 AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2310 AS2 (ldi,%D0,hhi8(%1)));
2311 }
2312
2313 if (GET_CODE (src) == CONST_INT)
2314 {
2315 const char *const clr_op0 =
2316 AVR_ENHANCED ? (AS1 (clr,%A0) CR_TAB
2317 AS1 (clr,%B0) CR_TAB
2318 AS2 (movw,%C0,%A0))
2319 : (AS1 (clr,%A0) CR_TAB
2320 AS1 (clr,%B0) CR_TAB
2321 AS1 (clr,%C0) CR_TAB
2322 AS1 (clr,%D0));
2323
2324 if (src == const0_rtx) /* mov r,L */
2325 {
2326 *l = AVR_ENHANCED ? 3 : 4;
2327 return clr_op0;
2328 }
2329 else if (src == const1_rtx)
2330 {
2331 if (!real_l)
2332 output_asm_insn (clr_op0, operands);
2333 *l = AVR_ENHANCED ? 4 : 5;
2334 return AS1 (inc,%A0);
2335 }
2336 else if (src == constm1_rtx)
2337 {
2338 /* Immediate constants -1 to any register */
2339 if (AVR_ENHANCED)
2340 {
2341 *l = 4;
2342 return (AS1 (clr,%A0) CR_TAB
2343 AS1 (dec,%A0) CR_TAB
2344 AS2 (mov,%B0,%A0) CR_TAB
2345 AS2 (movw,%C0,%A0));
2346 }
2347 *l = 5;
2348 return (AS1 (clr,%A0) CR_TAB
2349 AS1 (dec,%A0) CR_TAB
2350 AS2 (mov,%B0,%A0) CR_TAB
2351 AS2 (mov,%C0,%A0) CR_TAB
2352 AS2 (mov,%D0,%A0));
2353 }
2354 else
2355 {
2356 int bit_nr = exact_log2 (INTVAL (src));
2357
2358 if (bit_nr >= 0)
2359 {
2360 *l = AVR_ENHANCED ? 5 : 6;
2361 if (!real_l)
2362 {
2363 output_asm_insn (clr_op0, operands);
2364 output_asm_insn ("set", operands);
2365 }
2366 if (!real_l)
2367 avr_output_bld (operands, bit_nr);
2368
2369 return "";
2370 }
2371 }
2372 }
2373
2374 /* Last resort, better than loading from memory. */
2375 *l = 10;
2376 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2377 AS2 (ldi,r31,lo8(%1)) CR_TAB
2378 AS2 (mov,%A0,r31) CR_TAB
2379 AS2 (ldi,r31,hi8(%1)) CR_TAB
2380 AS2 (mov,%B0,r31) CR_TAB
2381 AS2 (ldi,r31,hlo8(%1)) CR_TAB
2382 AS2 (mov,%C0,r31) CR_TAB
2383 AS2 (ldi,r31,hhi8(%1)) CR_TAB
2384 AS2 (mov,%D0,r31) CR_TAB
2385 AS2 (mov,r31,__tmp_reg__));
2386 }
2387 else if (GET_CODE (src) == MEM)
2388 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2389 }
2390 else if (GET_CODE (dest) == MEM)
2391 {
2392 const char *template;
2393
2394 if (src == const0_rtx)
2395 operands[1] = zero_reg_rtx;
2396
2397 template = out_movsi_mr_r (insn, operands, real_l);
2398
2399 if (!real_l)
2400 output_asm_insn (template, operands);
2401
2402 operands[1] = src;
2403 return "";
2404 }
2405 fatal_insn ("invalid insn:", insn);
2406 return "";
2407 }
2408
2409 const char *
2410 out_movqi_mr_r (rtx insn, rtx op[], int *l)
2411 {
2412 rtx dest = op[0];
2413 rtx src = op[1];
2414 rtx x = XEXP (dest, 0);
2415 int dummy;
2416
2417 if (!l)
2418 l = &dummy;
2419
2420 if (CONSTANT_ADDRESS_P (x))
2421 {
2422 if (avr_io_address_p (x, 1))
2423 {
2424 *l = 1;
2425 return AS2 (out,%0-0x20,%1);
2426 }
2427 *l = 2;
2428 return AS2 (sts,%0,%1);
2429 }
2430 /* memory access by reg+disp */
2431 else if (GET_CODE (x) == PLUS
2432 && REG_P (XEXP (x,0))
2433 && GET_CODE (XEXP (x,1)) == CONST_INT)
2434 {
2435 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2436 {
2437 int disp = INTVAL (XEXP (x,1));
2438 if (REGNO (XEXP (x,0)) != REG_Y)
2439 fatal_insn ("incorrect insn:",insn);
2440
2441 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2442 return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2443 AS2 (std,Y+63,%1) CR_TAB
2444 AS2 (sbiw,r28,%o0-63));
2445
2446 return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2447 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2448 AS2 (st,Y,%1) CR_TAB
2449 AS2 (subi,r28,lo8(%o0)) CR_TAB
2450 AS2 (sbci,r29,hi8(%o0)));
2451 }
2452 else if (REGNO (XEXP (x,0)) == REG_X)
2453 {
2454 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2455 {
2456 if (reg_unused_after (insn, XEXP (x,0)))
2457 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2458 AS2 (adiw,r26,%o0) CR_TAB
2459 AS2 (st,X,__tmp_reg__));
2460
2461 return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2462 AS2 (adiw,r26,%o0) CR_TAB
2463 AS2 (st,X,__tmp_reg__) CR_TAB
2464 AS2 (sbiw,r26,%o0));
2465 }
2466 else
2467 {
2468 if (reg_unused_after (insn, XEXP (x,0)))
2469 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2470 AS2 (st,X,%1));
2471
2472 return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2473 AS2 (st,X,%1) CR_TAB
2474 AS2 (sbiw,r26,%o0));
2475 }
2476 }
2477 *l = 1;
2478 return AS2 (std,%0,%1);
2479 }
2480 *l = 1;
2481 return AS2 (st,%0,%1);
2482 }
2483
2484 const char *
2485 out_movhi_mr_r (rtx insn, rtx op[], int *l)
2486 {
2487 rtx dest = op[0];
2488 rtx src = op[1];
2489 rtx base = XEXP (dest, 0);
2490 int reg_base = true_regnum (base);
2491 int reg_src = true_regnum (src);
2492 int tmp;
2493 if (!l)
2494 l = &tmp;
2495 if (CONSTANT_ADDRESS_P (base))
2496 {
2497 if (avr_io_address_p (base, 2))
2498 {
2499 *l = 2;
2500 return (AS2 (out,%B0-0x20,%B1) CR_TAB
2501 AS2 (out,%A0-0x20,%A1));
2502 }
2503 return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2504 AS2 (sts,%A0,%A1));
2505 }
2506 if (reg_base > 0)
2507 {
2508 if (reg_base == REG_X)
2509 {
2510 if (reg_src == REG_X)
2511 {
2512 /* "st X+,r26" is undefined */
2513 if (reg_unused_after (insn, src))
2514 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2515 AS2 (st,X,r26) CR_TAB
2516 AS2 (adiw,r26,1) CR_TAB
2517 AS2 (st,X,__tmp_reg__));
2518 else
2519 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2520 AS2 (st,X,r26) CR_TAB
2521 AS2 (adiw,r26,1) CR_TAB
2522 AS2 (st,X,__tmp_reg__) CR_TAB
2523 AS2 (sbiw,r26,1));
2524 }
2525 else
2526 {
2527 if (reg_unused_after (insn, base))
2528 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2529 AS2 (st,X,%B1));
2530 else
2531 return *l=3, (AS2 (st ,X+,%A1) CR_TAB
2532 AS2 (st ,X,%B1) CR_TAB
2533 AS2 (sbiw,r26,1));
2534 }
2535 }
2536 else
2537 return *l=2, (AS2 (st ,%0,%A1) CR_TAB
2538 AS2 (std,%0+1,%B1));
2539 }
2540 else if (GET_CODE (base) == PLUS)
2541 {
2542 int disp = INTVAL (XEXP (base, 1));
2543 reg_base = REGNO (XEXP (base, 0));
2544 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2545 {
2546 if (reg_base != REG_Y)
2547 fatal_insn ("incorrect insn:",insn);
2548
2549 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2550 return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2551 AS2 (std,Y+62,%A1) CR_TAB
2552 AS2 (std,Y+63,%B1) CR_TAB
2553 AS2 (sbiw,r28,%o0-62));
2554
2555 return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2556 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2557 AS2 (st,Y,%A1) CR_TAB
2558 AS2 (std,Y+1,%B1) CR_TAB
2559 AS2 (subi,r28,lo8(%o0)) CR_TAB
2560 AS2 (sbci,r29,hi8(%o0)));
2561 }
2562 if (reg_base == REG_X)
2563 {
2564 /* (X + d) = R */
2565 if (reg_src == REG_X)
2566 {
2567 *l = 7;
2568 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2569 AS2 (mov,__zero_reg__,r27) CR_TAB
2570 AS2 (adiw,r26,%o0) CR_TAB
2571 AS2 (st,X+,__tmp_reg__) CR_TAB
2572 AS2 (st,X,__zero_reg__) CR_TAB
2573 AS1 (clr,__zero_reg__) CR_TAB
2574 AS2 (sbiw,r26,%o0+1));
2575 }
2576 *l = 4;
2577 return (AS2 (adiw,r26,%o0) CR_TAB
2578 AS2 (st,X+,%A1) CR_TAB
2579 AS2 (st,X,%B1) CR_TAB
2580 AS2 (sbiw,r26,%o0+1));
2581 }
2582 return *l=2, (AS2 (std,%A0,%A1) CR_TAB
2583 AS2 (std,%B0,%B1));
2584 }
2585 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2586 return *l=2, (AS2 (st,%0,%B1) CR_TAB
2587 AS2 (st,%0,%A1));
2588 else if (GET_CODE (base) == POST_INC) /* (R++) */
2589 return *l=2, (AS2 (st,%0,%A1) CR_TAB
2590 AS2 (st,%0,%B1));
2591 fatal_insn ("unknown move insn:",insn);
2592 return "";
2593 }
2594
2595 /* Return 1 if frame pointer for current function required. */
2596
2597 int
2598 frame_pointer_required_p (void)
2599 {
2600 return (current_function_calls_alloca
2601 || current_function_args_info.nregs == 0
2602 || get_frame_size () > 0);
2603 }
2604
2605 /* Returns the condition of compare insn INSN, or UNKNOWN. */
2606
2607 static RTX_CODE
2608 compare_condition (rtx insn)
2609 {
2610 rtx next = next_real_insn (insn);
2611 RTX_CODE cond = UNKNOWN;
2612 if (next && GET_CODE (next) == JUMP_INSN)
2613 {
2614 rtx pat = PATTERN (next);
2615 rtx src = SET_SRC (pat);
2616 rtx t = XEXP (src, 0);
2617 cond = GET_CODE (t);
2618 }
2619 return cond;
2620 }
2621
2622 /* Returns nonzero if INSN is a tst insn that only tests the sign. */
2623
2624 static int
2625 compare_sign_p (rtx insn)
2626 {
2627 RTX_CODE cond = compare_condition (insn);
2628 return (cond == GE || cond == LT);
2629 }
2630
2631 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
2632 that needs to be swapped (GT, GTU, LE, LEU). */
2633
2634 int
2635 compare_diff_p (rtx insn)
2636 {
2637 RTX_CODE cond = compare_condition (insn);
2638 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2639 }
2640
2641 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition. */
2642
2643 int
2644 compare_eq_p (rtx insn)
2645 {
2646 RTX_CODE cond = compare_condition (insn);
2647 return (cond == EQ || cond == NE);
2648 }
2649
2650
2651 /* Output test instruction for HImode. */
2652
2653 const char *
2654 out_tsthi (rtx insn, int *l)
2655 {
2656 if (compare_sign_p (insn))
2657 {
2658 if (l) *l = 1;
2659 return AS1 (tst,%B0);
2660 }
2661 if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
2662 && compare_eq_p (insn))
2663 {
2664 /* Faster than sbiw if we can clobber the operand. */
2665 if (l) *l = 1;
2666 return AS2 (or,%A0,%B0);
2667 }
2668 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2669 {
2670 if (l) *l = 1;
2671 return AS2 (sbiw,%0,0);
2672 }
2673 if (l) *l = 2;
2674 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2675 AS2 (cpc,%B0,__zero_reg__));
2676 }
2677
2678
2679 /* Output test instruction for SImode. */
2680
2681 const char *
2682 out_tstsi (rtx insn, int *l)
2683 {
2684 if (compare_sign_p (insn))
2685 {
2686 if (l) *l = 1;
2687 return AS1 (tst,%D0);
2688 }
2689 if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2690 {
2691 if (l) *l = 3;
2692 return (AS2 (sbiw,%A0,0) CR_TAB
2693 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2694 AS2 (cpc,%D0,__zero_reg__));
2695 }
2696 if (l) *l = 4;
2697 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2698 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2699 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2700 AS2 (cpc,%D0,__zero_reg__));
2701 }
2702
2703
2704 /* Generate asm equivalent for various shifts.
2705 Shift count is a CONST_INT, MEM or REG.
2706 This only handles cases that are not already
2707 carefully hand-optimized in ?sh??i3_out. */
2708
2709 void
2710 out_shift_with_cnt (const char *template, rtx insn, rtx operands[],
2711 int *len, int t_len)
2712 {
2713 rtx op[10];
2714 char str[500];
2715 int second_label = 1;
2716 int saved_in_tmp = 0;
2717 int use_zero_reg = 0;
2718
2719 op[0] = operands[0];
2720 op[1] = operands[1];
2721 op[2] = operands[2];
2722 op[3] = operands[3];
2723 str[0] = 0;
2724
2725 if (len)
2726 *len = 1;
2727
2728 if (GET_CODE (operands[2]) == CONST_INT)
2729 {
2730 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2731 int count = INTVAL (operands[2]);
2732 int max_len = 10; /* If larger than this, always use a loop. */
2733
2734 if (count < 8 && !scratch)
2735 use_zero_reg = 1;
2736
2737 if (optimize_size)
2738 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
2739
2740 if (t_len * count <= max_len)
2741 {
2742 /* Output shifts inline with no loop - faster. */
2743 if (len)
2744 *len = t_len * count;
2745 else
2746 {
2747 while (count-- > 0)
2748 output_asm_insn (template, op);
2749 }
2750
2751 return;
2752 }
2753
2754 if (scratch)
2755 {
2756 if (!len)
2757 strcat (str, AS2 (ldi,%3,%2));
2758 }
2759 else if (use_zero_reg)
2760 {
2761 /* Hack to save one word: use __zero_reg__ as loop counter.
2762 Set one bit, then shift in a loop until it is 0 again. */
2763
2764 op[3] = zero_reg_rtx;
2765 if (len)
2766 *len = 2;
2767 else
2768 strcat (str, ("set" CR_TAB
2769 AS2 (bld,%3,%2-1)));
2770 }
2771 else
2772 {
2773 /* No scratch register available, use one from LD_REGS (saved in
2774 __tmp_reg__) that doesn't overlap with registers to shift. */
2775
2776 op[3] = gen_rtx (REG, QImode,
2777 ((true_regnum (operands[0]) - 1) & 15) + 16);
2778 op[4] = tmp_reg_rtx;
2779 saved_in_tmp = 1;
2780
2781 if (len)
2782 *len = 3; /* Includes "mov %3,%4" after the loop. */
2783 else
2784 strcat (str, (AS2 (mov,%4,%3) CR_TAB
2785 AS2 (ldi,%3,%2)));
2786 }
2787
2788 second_label = 0;
2789 }
2790 else if (GET_CODE (operands[2]) == MEM)
2791 {
2792 rtx op_mov[10];
2793
2794 op[3] = op_mov[0] = tmp_reg_rtx;
2795 op_mov[1] = op[2];
2796
2797 if (len)
2798 out_movqi_r_mr (insn, op_mov, len);
2799 else
2800 output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2801 }
2802 else if (register_operand (operands[2], QImode))
2803 {
2804 if (reg_unused_after (insn, operands[2]))
2805 op[3] = op[2];
2806 else
2807 {
2808 op[3] = tmp_reg_rtx;
2809 if (!len)
2810 strcat (str, (AS2 (mov,%3,%2) CR_TAB));
2811 }
2812 }
2813 else
2814 fatal_insn ("bad shift insn:", insn);
2815
2816 if (second_label)
2817 {
2818 if (len)
2819 ++*len;
2820 else
2821 strcat (str, AS1 (rjmp,2f));
2822 }
2823
2824 if (len)
2825 *len += t_len + 2; /* template + dec + brXX */
2826 else
2827 {
2828 strcat (str, "\n1:\t");
2829 strcat (str, template);
2830 strcat (str, second_label ? "\n2:\t" : "\n\t");
2831 strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
2832 strcat (str, CR_TAB);
2833 strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
2834 if (saved_in_tmp)
2835 strcat (str, (CR_TAB AS2 (mov,%3,%4)));
2836 output_asm_insn (str, op);
2837 }
2838 }
2839
2840
2841 /* 8bit shift left ((char)x << i) */
2842
2843 const char *
2844 ashlqi3_out (rtx insn, rtx operands[], int *len)
2845 {
2846 if (GET_CODE (operands[2]) == CONST_INT)
2847 {
2848 int k;
2849
2850 if (!len)
2851 len = &k;
2852
2853 switch (INTVAL (operands[2]))
2854 {
2855 default:
2856 *len = 1;
2857 return AS1 (clr,%0);
2858
2859 case 1:
2860 *len = 1;
2861 return AS1 (lsl,%0);
2862
2863 case 2:
2864 *len = 2;
2865 return (AS1 (lsl,%0) CR_TAB
2866 AS1 (lsl,%0));
2867
2868 case 3:
2869 *len = 3;
2870 return (AS1 (lsl,%0) CR_TAB
2871 AS1 (lsl,%0) CR_TAB
2872 AS1 (lsl,%0));
2873
2874 case 4:
2875 if (test_hard_reg_class (LD_REGS, operands[0]))
2876 {
2877 *len = 2;
2878 return (AS1 (swap,%0) CR_TAB
2879 AS2 (andi,%0,0xf0));
2880 }
2881 *len = 4;
2882 return (AS1 (lsl,%0) CR_TAB
2883 AS1 (lsl,%0) CR_TAB
2884 AS1 (lsl,%0) CR_TAB
2885 AS1 (lsl,%0));
2886
2887 case 5:
2888 if (test_hard_reg_class (LD_REGS, operands[0]))
2889 {
2890 *len = 3;
2891 return (AS1 (swap,%0) CR_TAB
2892 AS1 (lsl,%0) CR_TAB
2893 AS2 (andi,%0,0xe0));
2894 }
2895 *len = 5;
2896 return (AS1 (lsl,%0) CR_TAB
2897 AS1 (lsl,%0) CR_TAB
2898 AS1 (lsl,%0) CR_TAB
2899 AS1 (lsl,%0) CR_TAB
2900 AS1 (lsl,%0));
2901
2902 case 6:
2903 if (test_hard_reg_class (LD_REGS, operands[0]))
2904 {
2905 *len = 4;
2906 return (AS1 (swap,%0) CR_TAB
2907 AS1 (lsl,%0) CR_TAB
2908 AS1 (lsl,%0) CR_TAB
2909 AS2 (andi,%0,0xc0));
2910 }
2911 *len = 6;
2912 return (AS1 (lsl,%0) CR_TAB
2913 AS1 (lsl,%0) CR_TAB
2914 AS1 (lsl,%0) CR_TAB
2915 AS1 (lsl,%0) CR_TAB
2916 AS1 (lsl,%0) CR_TAB
2917 AS1 (lsl,%0));
2918
2919 case 7:
2920 *len = 3;
2921 return (AS1 (ror,%0) CR_TAB
2922 AS1 (clr,%0) CR_TAB
2923 AS1 (ror,%0));
2924 }
2925 }
2926 else if (CONSTANT_P (operands[2]))
2927 fatal_insn ("internal compiler error. Incorrect shift:", insn);
2928
2929 out_shift_with_cnt (AS1 (lsl,%0),
2930 insn, operands, len, 1);
2931 return "";
2932 }
2933
2934
2935 /* 16bit shift left ((short)x << i) */
2936
2937 const char *
2938 ashlhi3_out (rtx insn, rtx operands[], int *len)
2939 {
2940 if (GET_CODE (operands[2]) == CONST_INT)
2941 {
2942 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2943 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
2944 int k;
2945 int *t = len;
2946
2947 if (!len)
2948 len = &k;
2949
2950 switch (INTVAL (operands[2]))
2951 {
2952 case 4:
2953 if (optimize_size && scratch)
2954 break; /* 5 */
2955 if (ldi_ok)
2956 {
2957 *len = 6;
2958 return (AS1 (swap,%A0) CR_TAB
2959 AS1 (swap,%B0) CR_TAB
2960 AS2 (andi,%B0,0xf0) CR_TAB
2961 AS2 (eor,%B0,%A0) CR_TAB
2962 AS2 (andi,%A0,0xf0) CR_TAB
2963 AS2 (eor,%B0,%A0));
2964 }
2965 if (scratch)
2966 {
2967 *len = 7;
2968 return (AS1 (swap,%A0) CR_TAB
2969 AS1 (swap,%B0) CR_TAB
2970 AS2 (ldi,%3,0xf0) CR_TAB
2971 AS2 (and,%B0,%3) CR_TAB
2972 AS2 (eor,%B0,%A0) CR_TAB
2973 AS2 (and,%A0,%3) CR_TAB
2974 AS2 (eor,%B0,%A0));
2975 }
2976 break; /* optimize_size ? 6 : 8 */
2977
2978 case 5:
2979 if (optimize_size)
2980 break; /* scratch ? 5 : 6 */
2981 if (ldi_ok)
2982 {
2983 *len = 8;
2984 return (AS1 (lsl,%A0) CR_TAB
2985 AS1 (rol,%B0) CR_TAB
2986 AS1 (swap,%A0) CR_TAB
2987 AS1 (swap,%B0) CR_TAB
2988 AS2 (andi,%B0,0xf0) CR_TAB
2989 AS2 (eor,%B0,%A0) CR_TAB
2990 AS2 (andi,%A0,0xf0) CR_TAB
2991 AS2 (eor,%B0,%A0));
2992 }
2993 if (scratch)
2994 {
2995 *len = 9;
2996 return (AS1 (lsl,%A0) CR_TAB
2997 AS1 (rol,%B0) CR_TAB
2998 AS1 (swap,%A0) CR_TAB
2999 AS1 (swap,%B0) CR_TAB
3000 AS2 (ldi,%3,0xf0) CR_TAB
3001 AS2 (and,%B0,%3) CR_TAB
3002 AS2 (eor,%B0,%A0) CR_TAB
3003 AS2 (and,%A0,%3) CR_TAB
3004 AS2 (eor,%B0,%A0));
3005 }
3006 break; /* 10 */
3007
3008 case 6:
3009 if (optimize_size)
3010 break; /* scratch ? 5 : 6 */
3011 *len = 9;
3012 return (AS1 (clr,__tmp_reg__) CR_TAB
3013 AS1 (lsr,%B0) CR_TAB
3014 AS1 (ror,%A0) CR_TAB
3015 AS1 (ror,__tmp_reg__) CR_TAB
3016 AS1 (lsr,%B0) CR_TAB
3017 AS1 (ror,%A0) CR_TAB
3018 AS1 (ror,__tmp_reg__) CR_TAB
3019 AS2 (mov,%B0,%A0) CR_TAB
3020 AS2 (mov,%A0,__tmp_reg__));
3021
3022 case 7:
3023 *len = 5;
3024 return (AS1 (lsr,%B0) CR_TAB
3025 AS2 (mov,%B0,%A0) CR_TAB
3026 AS1 (clr,%A0) CR_TAB
3027 AS1 (ror,%B0) CR_TAB
3028 AS1 (ror,%A0));
3029
3030 case 8:
3031 if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
3032 return *len = 1, AS1 (clr,%A0);
3033 else
3034 return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3035 AS1 (clr,%A0));
3036
3037 case 9:
3038 *len = 3;
3039 return (AS2 (mov,%B0,%A0) CR_TAB
3040 AS1 (clr,%A0) CR_TAB
3041 AS1 (lsl,%B0));
3042
3043 case 10:
3044 *len = 4;
3045 return (AS2 (mov,%B0,%A0) CR_TAB
3046 AS1 (clr,%A0) CR_TAB
3047 AS1 (lsl,%B0) CR_TAB
3048 AS1 (lsl,%B0));
3049
3050 case 11:
3051 *len = 5;
3052 return (AS2 (mov,%B0,%A0) CR_TAB
3053 AS1 (clr,%A0) CR_TAB
3054 AS1 (lsl,%B0) CR_TAB
3055 AS1 (lsl,%B0) CR_TAB
3056 AS1 (lsl,%B0));
3057
3058 case 12:
3059 if (ldi_ok)
3060 {
3061 *len = 4;
3062 return (AS2 (mov,%B0,%A0) CR_TAB
3063 AS1 (clr,%A0) CR_TAB
3064 AS1 (swap,%B0) CR_TAB
3065 AS2 (andi,%B0,0xf0));
3066 }
3067 if (scratch)
3068 {
3069 *len = 5;
3070 return (AS2 (mov,%B0,%A0) CR_TAB
3071 AS1 (clr,%A0) CR_TAB
3072 AS1 (swap,%B0) CR_TAB
3073 AS2 (ldi,%3,0xf0) CR_TAB
3074 AS2 (and,%B0,%3));
3075 }
3076 *len = 6;
3077 return (AS2 (mov,%B0,%A0) CR_TAB
3078 AS1 (clr,%A0) CR_TAB
3079 AS1 (lsl,%B0) CR_TAB
3080 AS1 (lsl,%B0) CR_TAB
3081 AS1 (lsl,%B0) CR_TAB
3082 AS1 (lsl,%B0));
3083
3084 case 13:
3085 if (ldi_ok)
3086 {
3087 *len = 5;
3088 return (AS2 (mov,%B0,%A0) CR_TAB
3089 AS1 (clr,%A0) CR_TAB
3090 AS1 (swap,%B0) CR_TAB
3091 AS1 (lsl,%B0) CR_TAB
3092 AS2 (andi,%B0,0xe0));
3093 }
3094 if (AVR_ENHANCED && scratch)
3095 {
3096 *len = 5;
3097 return (AS2 (ldi,%3,0x20) CR_TAB
3098 AS2 (mul,%A0,%3) CR_TAB
3099 AS2 (mov,%B0,r0) CR_TAB
3100 AS1 (clr,%A0) CR_TAB
3101 AS1 (clr,__zero_reg__));
3102 }
3103 if (optimize_size && scratch)
3104 break; /* 5 */
3105 if (scratch)
3106 {
3107 *len = 6;
3108 return (AS2 (mov,%B0,%A0) CR_TAB
3109 AS1 (clr,%A0) CR_TAB
3110 AS1 (swap,%B0) CR_TAB
3111 AS1 (lsl,%B0) CR_TAB
3112 AS2 (ldi,%3,0xe0) CR_TAB
3113 AS2 (and,%B0,%3));
3114 }
3115 if (AVR_ENHANCED)
3116 {
3117 *len = 6;
3118 return ("set" CR_TAB
3119 AS2 (bld,r1,5) CR_TAB
3120 AS2 (mul,%A0,r1) CR_TAB
3121 AS2 (mov,%B0,r0) CR_TAB
3122 AS1 (clr,%A0) CR_TAB
3123 AS1 (clr,__zero_reg__));
3124 }
3125 *len = 7;
3126 return (AS2 (mov,%B0,%A0) CR_TAB
3127 AS1 (clr,%A0) CR_TAB
3128 AS1 (lsl,%B0) CR_TAB
3129 AS1 (lsl,%B0) CR_TAB
3130 AS1 (lsl,%B0) CR_TAB
3131 AS1 (lsl,%B0) CR_TAB
3132 AS1 (lsl,%B0));
3133
3134 case 14:
3135 if (AVR_ENHANCED && ldi_ok)
3136 {
3137 *len = 5;
3138 return (AS2 (ldi,%B0,0x40) CR_TAB
3139 AS2 (mul,%A0,%B0) CR_TAB
3140 AS2 (mov,%B0,r0) CR_TAB
3141 AS1 (clr,%A0) CR_TAB
3142 AS1 (clr,__zero_reg__));
3143 }
3144 if (AVR_ENHANCED && scratch)
3145 {
3146 *len = 5;
3147 return (AS2 (ldi,%3,0x40) CR_TAB
3148 AS2 (mul,%A0,%3) CR_TAB
3149 AS2 (mov,%B0,r0) CR_TAB
3150 AS1 (clr,%A0) CR_TAB
3151 AS1 (clr,__zero_reg__));
3152 }
3153 if (optimize_size && ldi_ok)
3154 {
3155 *len = 5;
3156 return (AS2 (mov,%B0,%A0) CR_TAB
3157 AS2 (ldi,%A0,6) "\n1:\t"
3158 AS1 (lsl,%B0) CR_TAB
3159 AS1 (dec,%A0) CR_TAB
3160 AS1 (brne,1b));
3161 }
3162 if (optimize_size && scratch)
3163 break; /* 5 */
3164 *len = 6;
3165 return (AS1 (clr,%B0) CR_TAB
3166 AS1 (lsr,%A0) CR_TAB
3167 AS1 (ror,%B0) CR_TAB
3168 AS1 (lsr,%A0) CR_TAB
3169 AS1 (ror,%B0) CR_TAB
3170 AS1 (clr,%A0));
3171
3172 case 15:
3173 *len = 4;
3174 return (AS1 (clr,%B0) CR_TAB
3175 AS1 (lsr,%A0) CR_TAB
3176 AS1 (ror,%B0) CR_TAB
3177 AS1 (clr,%A0));
3178 }
3179 len = t;
3180 }
3181 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3182 AS1 (rol,%B0)),
3183 insn, operands, len, 2);
3184 return "";
3185 }
3186
3187
3188 /* 32bit shift left ((long)x << i) */
3189
3190 const char *
3191 ashlsi3_out (rtx insn, rtx operands[], int *len)
3192 {
3193 if (GET_CODE (operands[2]) == CONST_INT)
3194 {
3195 int k;
3196 int *t = len;
3197
3198 if (!len)
3199 len = &k;
3200
3201 switch (INTVAL (operands[2]))
3202 {
3203 case 8:
3204 {
3205 int reg0 = true_regnum (operands[0]);
3206 int reg1 = true_regnum (operands[1]);
3207 *len = 4;
3208 if (reg0 >= reg1)
3209 return (AS2 (mov,%D0,%C1) CR_TAB
3210 AS2 (mov,%C0,%B1) CR_TAB
3211 AS2 (mov,%B0,%A1) CR_TAB
3212 AS1 (clr,%A0));
3213 else if (reg0 + 1 == reg1)
3214 {
3215 *len = 1;
3216 return AS1 (clr,%A0);
3217 }
3218 else
3219 return (AS1 (clr,%A0) CR_TAB
3220 AS2 (mov,%B0,%A1) CR_TAB
3221 AS2 (mov,%C0,%B1) CR_TAB
3222 AS2 (mov,%D0,%C1));
3223 }
3224
3225 case 16:
3226 {
3227 int reg0 = true_regnum (operands[0]);
3228 int reg1 = true_regnum (operands[1]);
3229 *len = 4;
3230 if (AVR_ENHANCED && (reg0 + 2 != reg1))
3231 {
3232 *len = 3;
3233 return (AS2 (movw,%C0,%A1) CR_TAB
3234 AS1 (clr,%B0) CR_TAB
3235 AS1 (clr,%A0));
3236 }
3237 if (reg0 + 1 >= reg1)
3238 return (AS2 (mov,%D0,%B1) CR_TAB
3239 AS2 (mov,%C0,%A1) CR_TAB
3240 AS1 (clr,%B0) CR_TAB
3241 AS1 (clr,%A0));
3242 if (reg0 + 2 == reg1)
3243 {
3244 *len = 2;
3245 return (AS1 (clr,%B0) CR_TAB
3246 AS1 (clr,%A0));
3247 }
3248 else
3249 return (AS2 (mov,%C0,%A1) CR_TAB
3250 AS2 (mov,%D0,%B1) CR_TAB
3251 AS1 (clr,%B0) CR_TAB
3252 AS1 (clr,%A0));
3253 }
3254
3255 case 24:
3256 *len = 4;
3257 if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
3258 return (AS2 (mov,%D0,%A1) CR_TAB
3259 AS1 (clr,%C0) CR_TAB
3260 AS1 (clr,%B0) CR_TAB
3261 AS1 (clr,%A0));
3262 else
3263 {
3264 *len = 3;
3265 return (AS1 (clr,%C0) CR_TAB
3266 AS1 (clr,%B0) CR_TAB
3267 AS1 (clr,%A0));
3268 }
3269
3270 case 31:
3271 *len = 6;
3272 return (AS1 (clr,%D0) CR_TAB
3273 AS1 (lsr,%A0) CR_TAB
3274 AS1 (ror,%D0) CR_TAB
3275 AS1 (clr,%C0) CR_TAB
3276 AS1 (clr,%B0) CR_TAB
3277 AS1 (clr,%A0));
3278 }
3279 len = t;
3280 }
3281 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3282 AS1 (rol,%B0) CR_TAB
3283 AS1 (rol,%C0) CR_TAB
3284 AS1 (rol,%D0)),
3285 insn, operands, len, 4);
3286 return "";
3287 }
3288
3289 /* 8bit arithmetic shift right ((signed char)x >> i) */
3290
3291 const char *
3292 ashrqi3_out (rtx insn, rtx operands[], int *len)
3293 {
3294 if (GET_CODE (operands[2]) == CONST_INT)
3295 {
3296 int k;
3297
3298 if (!len)
3299 len = &k;
3300
3301 switch (INTVAL (operands[2]))
3302 {
3303 case 1:
3304 *len = 1;
3305 return AS1 (asr,%0);
3306
3307 case 2:
3308 *len = 2;
3309 return (AS1 (asr,%0) CR_TAB
3310 AS1 (asr,%0));
3311
3312 case 3:
3313 *len = 3;
3314 return (AS1 (asr,%0) CR_TAB
3315 AS1 (asr,%0) CR_TAB
3316 AS1 (asr,%0));
3317
3318 case 4:
3319 *len = 4;
3320 return (AS1 (asr,%0) CR_TAB
3321 AS1 (asr,%0) CR_TAB
3322 AS1 (asr,%0) CR_TAB
3323 AS1 (asr,%0));
3324
3325 case 5:
3326 *len = 5;
3327 return (AS1 (asr,%0) CR_TAB
3328 AS1 (asr,%0) CR_TAB
3329 AS1 (asr,%0) CR_TAB
3330 AS1 (asr,%0) CR_TAB
3331 AS1 (asr,%0));
3332
3333 case 6:
3334 *len = 4;
3335 return (AS2 (bst,%0,6) CR_TAB
3336 AS1 (lsl,%0) CR_TAB
3337 AS2 (sbc,%0,%0) CR_TAB
3338 AS2 (bld,%0,0));
3339
3340 default:
3341 case 7:
3342 *len = 2;
3343 return (AS1 (lsl,%0) CR_TAB
3344 AS2 (sbc,%0,%0));
3345 }
3346 }
3347 else if (CONSTANT_P (operands[2]))
3348 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3349
3350 out_shift_with_cnt (AS1 (asr,%0),
3351 insn, operands, len, 1);
3352 return "";
3353 }
3354
3355
3356 /* 16bit arithmetic shift right ((signed short)x >> i) */
3357
3358 const char *
3359 ashrhi3_out (rtx insn, rtx operands[], int *len)
3360 {
3361 if (GET_CODE (operands[2]) == CONST_INT)
3362 {
3363 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3364 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3365 int k;
3366 int *t = len;
3367
3368 if (!len)
3369 len = &k;
3370
3371 switch (INTVAL (operands[2]))
3372 {
3373 case 4:
3374 case 5:
3375 /* XXX try to optimize this too? */
3376 break;
3377
3378 case 6:
3379 if (optimize_size)
3380 break; /* scratch ? 5 : 6 */
3381 *len = 8;
3382 return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3383 AS2 (mov,%A0,%B0) CR_TAB
3384 AS1 (lsl,__tmp_reg__) CR_TAB
3385 AS1 (rol,%A0) CR_TAB
3386 AS2 (sbc,%B0,%B0) CR_TAB
3387 AS1 (lsl,__tmp_reg__) CR_TAB
3388 AS1 (rol,%A0) CR_TAB
3389 AS1 (rol,%B0));
3390
3391 case 7:
3392 *len = 4;
3393 return (AS1 (lsl,%A0) CR_TAB
3394 AS2 (mov,%A0,%B0) CR_TAB
3395 AS1 (rol,%A0) CR_TAB
3396 AS2 (sbc,%B0,%B0));
3397
3398 case 8:
3399 {
3400 int reg0 = true_regnum (operands[0]);
3401 int reg1 = true_regnum (operands[1]);
3402
3403 if (reg0 == reg1)
3404 return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3405 AS1 (lsl,%B0) CR_TAB
3406 AS2 (sbc,%B0,%B0));
3407 else if (reg0 == reg1 + 1)
3408 return *len = 3, (AS1 (clr,%B0) CR_TAB
3409 AS2 (sbrc,%A0,7) CR_TAB
3410 AS1 (dec,%B0));
3411
3412 return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3413 AS1 (clr,%B0) CR_TAB
3414 AS2 (sbrc,%A0,7) CR_TAB
3415 AS1 (dec,%B0));
3416 }
3417
3418 case 9:
3419 *len = 4;
3420 return (AS2 (mov,%A0,%B0) CR_TAB
3421 AS1 (lsl,%B0) CR_TAB
3422 AS2 (sbc,%B0,%B0) CR_TAB
3423 AS1 (asr,%A0));
3424
3425 case 10:
3426 *len = 5;
3427 return (AS2 (mov,%A0,%B0) CR_TAB
3428 AS1 (lsl,%B0) CR_TAB
3429 AS2 (sbc,%B0,%B0) CR_TAB
3430 AS1 (asr,%A0) CR_TAB
3431 AS1 (asr,%A0));
3432
3433 case 11:
3434 if (AVR_ENHANCED && ldi_ok)
3435 {
3436 *len = 5;
3437 return (AS2 (ldi,%A0,0x20) CR_TAB
3438 AS2 (muls,%B0,%A0) CR_TAB
3439 AS2 (mov,%A0,r1) CR_TAB
3440 AS2 (sbc,%B0,%B0) CR_TAB
3441 AS1 (clr,__zero_reg__));
3442 }
3443 if (optimize_size && scratch)
3444 break; /* 5 */
3445 *len = 6;
3446 return (AS2 (mov,%A0,%B0) CR_TAB
3447 AS1 (lsl,%B0) CR_TAB
3448 AS2 (sbc,%B0,%B0) CR_TAB
3449 AS1 (asr,%A0) CR_TAB
3450 AS1 (asr,%A0) CR_TAB
3451 AS1 (asr,%A0));
3452
3453 case 12:
3454 if (AVR_ENHANCED && ldi_ok)
3455 {
3456 *len = 5;
3457 return (AS2 (ldi,%A0,0x10) CR_TAB
3458 AS2 (muls,%B0,%A0) CR_TAB
3459 AS2 (mov,%A0,r1) CR_TAB
3460 AS2 (sbc,%B0,%B0) CR_TAB
3461 AS1 (clr,__zero_reg__));
3462 }
3463 if (optimize_size && scratch)
3464 break; /* 5 */
3465 *len = 7;
3466 return (AS2 (mov,%A0,%B0) CR_TAB
3467 AS1 (lsl,%B0) CR_TAB
3468 AS2 (sbc,%B0,%B0) CR_TAB
3469 AS1 (asr,%A0) CR_TAB
3470 AS1 (asr,%A0) CR_TAB
3471 AS1 (asr,%A0) CR_TAB
3472 AS1 (asr,%A0));
3473
3474 case 13:
3475 if (AVR_ENHANCED && ldi_ok)
3476 {
3477 *len = 5;
3478 return (AS2 (ldi,%A0,0x08) CR_TAB
3479 AS2 (muls,%B0,%A0) CR_TAB
3480 AS2 (mov,%A0,r1) CR_TAB
3481 AS2 (sbc,%B0,%B0) CR_TAB
3482 AS1 (clr,__zero_reg__));
3483 }
3484 if (optimize_size)
3485 break; /* scratch ? 5 : 7 */
3486 *len = 8;
3487 return (AS2 (mov,%A0,%B0) CR_TAB
3488 AS1 (lsl,%B0) CR_TAB
3489 AS2 (sbc,%B0,%B0) CR_TAB
3490 AS1 (asr,%A0) CR_TAB
3491 AS1 (asr,%A0) CR_TAB
3492 AS1 (asr,%A0) CR_TAB
3493 AS1 (asr,%A0) CR_TAB
3494 AS1 (asr,%A0));
3495
3496 case 14:
3497 *len = 5;
3498 return (AS1 (lsl,%B0) CR_TAB
3499 AS2 (sbc,%A0,%A0) CR_TAB
3500 AS1 (lsl,%B0) CR_TAB
3501 AS2 (mov,%B0,%A0) CR_TAB
3502 AS1 (rol,%A0));
3503
3504 case 15:
3505 return *len = 3, (AS1 (lsl,%B0) CR_TAB
3506 AS2 (sbc,%A0,%A0) CR_TAB
3507 AS2 (mov,%B0,%A0));
3508 }
3509 len = t;
3510 }
3511 out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3512 AS1 (ror,%A0)),
3513 insn, operands, len, 2);
3514 return "";
3515 }
3516
3517
3518 /* 32bit arithmetic shift right ((signed long)x >> i) */
3519
3520 const char *
3521 ashrsi3_out (rtx insn, rtx operands[], int *len)
3522 {
3523 if (GET_CODE (operands[2]) == CONST_INT)
3524 {
3525 int k;
3526 int *t = len;
3527
3528 if (!len)
3529 len = &k;
3530
3531 switch (INTVAL (operands[2]))
3532 {
3533 case 8:
3534 {
3535 int reg0 = true_regnum (operands[0]);
3536 int reg1 = true_regnum (operands[1]);
3537 *len=6;
3538 if (reg0 <= reg1)
3539 return (AS2 (mov,%A0,%B1) CR_TAB
3540 AS2 (mov,%B0,%C1) CR_TAB
3541 AS2 (mov,%C0,%D1) CR_TAB
3542 AS1 (clr,%D0) CR_TAB
3543 AS2 (sbrc,%C0,7) CR_TAB
3544 AS1 (dec,%D0));
3545 else if (reg0 == reg1 + 1)
3546 {
3547 *len = 3;
3548 return (AS1 (clr,%D0) CR_TAB
3549 AS2 (sbrc,%C0,7) CR_TAB
3550 AS1 (dec,%D0));
3551 }
3552 else
3553 return (AS1 (clr,%D0) CR_TAB
3554 AS2 (sbrc,%D1,7) CR_TAB
3555 AS1 (dec,%D0) CR_TAB
3556 AS2 (mov,%C0,%D1) CR_TAB
3557 AS2 (mov,%B0,%C1) CR_TAB
3558 AS2 (mov,%A0,%B1));
3559 }
3560
3561 case 16:
3562 {
3563 int reg0 = true_regnum (operands[0]);
3564 int reg1 = true_regnum (operands[1]);
3565 *len=6;
3566 if (AVR_ENHANCED && (reg0 != reg1 + 2))
3567 {
3568 *len = 5;
3569 return (AS2 (movw,%A0,%C1) CR_TAB
3570 AS1 (clr,%D0) CR_TAB
3571 AS2 (sbrc,%B0,7) CR_TAB
3572 AS1 (com,%D0) CR_TAB
3573 AS2 (mov,%C0,%D0));
3574 }
3575 if (reg0 <= reg1 + 1)
3576 return (AS2 (mov,%A0,%C1) CR_TAB
3577 AS2 (mov,%B0,%D1) CR_TAB
3578 AS1 (clr,%D0) CR_TAB
3579 AS2 (sbrc,%B0,7) CR_TAB
3580 AS1 (com,%D0) CR_TAB
3581 AS2 (mov,%C0,%D0));
3582 else if (reg0 == reg1 + 2)
3583 return *len = 4, (AS1 (clr,%D0) CR_TAB
3584 AS2 (sbrc,%B0,7) CR_TAB
3585 AS1 (com,%D0) CR_TAB
3586 AS2 (mov,%C0,%D0));
3587 else
3588 return (AS2 (mov,%B0,%D1) CR_TAB
3589 AS2 (mov,%A0,%C1) CR_TAB
3590 AS1 (clr,%D0) CR_TAB
3591 AS2 (sbrc,%B0,7) CR_TAB
3592 AS1 (com,%D0) CR_TAB
3593 AS2 (mov,%C0,%D0));
3594 }
3595
3596 case 24:
3597 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3598 return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3599 AS1 (clr,%D0) CR_TAB
3600 AS2 (sbrc,%A0,7) CR_TAB
3601 AS1 (com,%D0) CR_TAB
3602 AS2 (mov,%B0,%D0) CR_TAB
3603 AS2 (mov,%C0,%D0));
3604 else
3605 return *len = 5, (AS1 (clr,%D0) CR_TAB
3606 AS2 (sbrc,%A0,7) CR_TAB
3607 AS1 (com,%D0) CR_TAB
3608 AS2 (mov,%B0,%D0) CR_TAB
3609 AS2 (mov,%C0,%D0));
3610
3611 case 31:
3612 if (AVR_ENHANCED)
3613 return *len = 4, (AS1 (lsl,%D0) CR_TAB
3614 AS2 (sbc,%A0,%A0) CR_TAB
3615 AS2 (mov,%B0,%A0) CR_TAB
3616 AS2 (movw,%C0,%A0));
3617 else
3618 return *len = 5, (AS1 (lsl,%D0) CR_TAB
3619 AS2 (sbc,%A0,%A0) CR_TAB
3620 AS2 (mov,%B0,%A0) CR_TAB
3621 AS2 (mov,%C0,%A0) CR_TAB
3622 AS2 (mov,%D0,%A0));
3623 }
3624 len = t;
3625 }
3626 out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
3627 AS1 (ror,%C0) CR_TAB
3628 AS1 (ror,%B0) CR_TAB
3629 AS1 (ror,%A0)),
3630 insn, operands, len, 4);
3631 return "";
3632 }
3633
3634 /* 8bit logic shift right ((unsigned char)x >> i) */
3635
3636 const char *
3637 lshrqi3_out (rtx insn, rtx operands[], int *len)
3638 {
3639 if (GET_CODE (operands[2]) == CONST_INT)
3640 {
3641 int k;
3642
3643 if (!len)
3644 len = &k;
3645
3646 switch (INTVAL (operands[2]))
3647 {
3648 default:
3649 *len = 1;
3650 return AS1 (clr,%0);
3651
3652 case 1:
3653 *len = 1;
3654 return AS1 (lsr,%0);
3655
3656 case 2:
3657 *len = 2;
3658 return (AS1 (lsr,%0) CR_TAB
3659 AS1 (lsr,%0));
3660 case 3:
3661 *len = 3;
3662 return (AS1 (lsr,%0) CR_TAB
3663 AS1 (lsr,%0) CR_TAB
3664 AS1 (lsr,%0));
3665
3666 case 4:
3667 if (test_hard_reg_class (LD_REGS, operands[0]))
3668 {
3669 *len=2;
3670 return (AS1 (swap,%0) CR_TAB
3671 AS2 (andi,%0,0x0f));
3672 }
3673 *len = 4;
3674 return (AS1 (lsr,%0) CR_TAB
3675 AS1 (lsr,%0) CR_TAB
3676 AS1 (lsr,%0) CR_TAB
3677 AS1 (lsr,%0));
3678
3679 case 5:
3680 if (test_hard_reg_class (LD_REGS, operands[0]))
3681 {
3682 *len = 3;
3683 return (AS1 (swap,%0) CR_TAB
3684 AS1 (lsr,%0) CR_TAB
3685 AS2 (andi,%0,0x7));
3686 }
3687 *len = 5;
3688 return (AS1 (lsr,%0) CR_TAB
3689 AS1 (lsr,%0) CR_TAB
3690 AS1 (lsr,%0) CR_TAB
3691 AS1 (lsr,%0) CR_TAB
3692 AS1 (lsr,%0));
3693
3694 case 6:
3695 if (test_hard_reg_class (LD_REGS, operands[0]))
3696 {
3697 *len = 4;
3698 return (AS1 (swap,%0) CR_TAB
3699 AS1 (lsr,%0) CR_TAB
3700 AS1 (lsr,%0) CR_TAB
3701 AS2 (andi,%0,0x3));
3702 }
3703 *len = 6;
3704 return (AS1 (lsr,%0) CR_TAB
3705 AS1 (lsr,%0) CR_TAB
3706 AS1 (lsr,%0) CR_TAB
3707 AS1 (lsr,%0) CR_TAB
3708 AS1 (lsr,%0) CR_TAB
3709 AS1 (lsr,%0));
3710
3711 case 7:
3712 *len = 3;
3713 return (AS1 (rol,%0) CR_TAB
3714 AS1 (clr,%0) CR_TAB
3715 AS1 (rol,%0));
3716 }
3717 }
3718 else if (CONSTANT_P (operands[2]))
3719 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3720
3721 out_shift_with_cnt (AS1 (lsr,%0),
3722 insn, operands, len, 1);
3723 return "";
3724 }
3725
3726 /* 16bit logic shift right ((unsigned short)x >> i) */
3727
3728 const char *
3729 lshrhi3_out (rtx insn, rtx operands[], int *len)
3730 {
3731 if (GET_CODE (operands[2]) == CONST_INT)
3732 {
3733 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3734 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3735 int k;
3736 int *t = len;
3737
3738 if (!len)
3739 len = &k;
3740
3741 switch (INTVAL (operands[2]))
3742 {
3743 case 4:
3744 if (optimize_size && scratch)
3745 break; /* 5 */
3746 if (ldi_ok)
3747 {
3748 *len = 6;
3749 return (AS1 (swap,%B0) CR_TAB
3750 AS1 (swap,%A0) CR_TAB
3751 AS2 (andi,%A0,0x0f) CR_TAB
3752 AS2 (eor,%A0,%B0) CR_TAB
3753 AS2 (andi,%B0,0x0f) CR_TAB
3754 AS2 (eor,%A0,%B0));
3755 }
3756 if (scratch)
3757 {
3758 *len = 7;
3759 return (AS1 (swap,%B0) CR_TAB
3760 AS1 (swap,%A0) CR_TAB
3761 AS2 (ldi,%3,0x0f) CR_TAB
3762 AS2 (and,%A0,%3) CR_TAB
3763 AS2 (eor,%A0,%B0) CR_TAB
3764 AS2 (and,%B0,%3) CR_TAB
3765 AS2 (eor,%A0,%B0));
3766 }
3767 break; /* optimize_size ? 6 : 8 */
3768
3769 case 5:
3770 if (optimize_size)
3771 break; /* scratch ? 5 : 6 */
3772 if (ldi_ok)
3773 {
3774 *len = 8;
3775 return (AS1 (lsr,%B0) CR_TAB
3776 AS1 (ror,%A0) CR_TAB
3777 AS1 (swap,%B0) CR_TAB
3778 AS1 (swap,%A0) CR_TAB
3779 AS2 (andi,%A0,0x0f) CR_TAB
3780 AS2 (eor,%A0,%B0) CR_TAB
3781 AS2 (andi,%B0,0x0f) CR_TAB
3782 AS2 (eor,%A0,%B0));
3783 }
3784 if (scratch)
3785 {
3786 *len = 9;
3787 return (AS1 (lsr,%B0) CR_TAB
3788 AS1 (ror,%A0) CR_TAB
3789 AS1 (swap,%B0) CR_TAB
3790 AS1 (swap,%A0) CR_TAB
3791 AS2 (ldi,%3,0x0f) CR_TAB
3792 AS2 (and,%A0,%3) CR_TAB
3793 AS2 (eor,%A0,%B0) CR_TAB
3794 AS2 (and,%B0,%3) CR_TAB
3795 AS2 (eor,%A0,%B0));
3796 }
3797 break; /* 10 */
3798
3799 case 6:
3800 if (optimize_size)
3801 break; /* scratch ? 5 : 6 */
3802 *len = 9;
3803 return (AS1 (clr,__tmp_reg__) CR_TAB
3804 AS1 (lsl,%A0) CR_TAB
3805 AS1 (rol,%B0) CR_TAB
3806 AS1 (rol,__tmp_reg__) CR_TAB
3807 AS1 (lsl,%A0) CR_TAB
3808 AS1 (rol,%B0) CR_TAB
3809 AS1 (rol,__tmp_reg__) CR_TAB
3810 AS2 (mov,%A0,%B0) CR_TAB
3811 AS2 (mov,%B0,__tmp_reg__));
3812
3813 case 7:
3814 *len = 5;
3815 return (AS1 (lsl,%A0) CR_TAB
3816 AS2 (mov,%A0,%B0) CR_TAB
3817 AS1 (rol,%A0) CR_TAB
3818 AS2 (sbc,%B0,%B0) CR_TAB
3819 AS1 (neg,%B0));
3820
3821 case 8:
3822 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
3823 return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
3824 AS1 (clr,%B0));
3825 else
3826 return *len = 1, AS1 (clr,%B0);
3827
3828 case 9:
3829 *len = 3;
3830 return (AS2 (mov,%A0,%B0) CR_TAB
3831 AS1 (clr,%B0) CR_TAB
3832 AS1 (lsr,%A0));
3833
3834 case 10:
3835 *len = 4;
3836 return (AS2 (mov,%A0,%B0) CR_TAB
3837 AS1 (clr,%B0) CR_TAB
3838 AS1 (lsr,%A0) CR_TAB
3839 AS1 (lsr,%A0));
3840
3841 case 11:
3842 *len = 5;
3843 return (AS2 (mov,%A0,%B0) CR_TAB
3844 AS1 (clr,%B0) CR_TAB
3845 AS1 (lsr,%A0) CR_TAB
3846 AS1 (lsr,%A0) CR_TAB
3847 AS1 (lsr,%A0));
3848
3849 case 12:
3850 if (ldi_ok)
3851 {
3852 *len = 4;
3853 return (AS2 (mov,%A0,%B0) CR_TAB
3854 AS1 (clr,%B0) CR_TAB
3855 AS1 (swap,%A0) CR_TAB
3856 AS2 (andi,%A0,0x0f));
3857 }
3858 if (scratch)
3859 {
3860 *len = 5;
3861 return (AS2 (mov,%A0,%B0) CR_TAB
3862 AS1 (clr,%B0) CR_TAB
3863 AS1 (swap,%A0) CR_TAB
3864 AS2 (ldi,%3,0x0f) CR_TAB
3865 AS2 (and,%A0,%3));
3866 }
3867 *len = 6;
3868 return (AS2 (mov,%A0,%B0) CR_TAB
3869 AS1 (clr,%B0) CR_TAB
3870 AS1 (lsr,%A0) CR_TAB
3871 AS1 (lsr,%A0) CR_TAB
3872 AS1 (lsr,%A0) CR_TAB
3873 AS1 (lsr,%A0));
3874
3875 case 13:
3876 if (ldi_ok)
3877 {
3878 *len = 5;
3879 return (AS2 (mov,%A0,%B0) CR_TAB
3880 AS1 (clr,%B0) CR_TAB
3881 AS1 (swap,%A0) CR_TAB
3882 AS1 (lsr,%A0) CR_TAB
3883 AS2 (andi,%A0,0x07));
3884 }
3885 if (AVR_ENHANCED && scratch)
3886 {
3887 *len = 5;
3888 return (AS2 (ldi,%3,0x08) CR_TAB
3889 AS2 (mul,%B0,%3) CR_TAB
3890 AS2 (mov,%A0,r1) CR_TAB
3891 AS1 (clr,%B0) CR_TAB
3892 AS1 (clr,__zero_reg__));
3893 }
3894 if (optimize_size && scratch)
3895 break; /* 5 */
3896 if (scratch)
3897 {
3898 *len = 6;
3899 return (AS2 (mov,%A0,%B0) CR_TAB
3900 AS1 (clr,%B0) CR_TAB
3901 AS1 (swap,%A0) CR_TAB
3902 AS1 (lsr,%A0) CR_TAB
3903 AS2 (ldi,%3,0x07) CR_TAB
3904 AS2 (and,%A0,%3));
3905 }
3906 if (AVR_ENHANCED)
3907 {
3908 *len = 6;
3909 return ("set" CR_TAB
3910 AS2 (bld,r1,3) CR_TAB
3911 AS2 (mul,%B0,r1) CR_TAB
3912 AS2 (mov,%A0,r1) CR_TAB
3913 AS1 (clr,%B0) CR_TAB
3914 AS1 (clr,__zero_reg__));
3915 }
3916 *len = 7;
3917 return (AS2 (mov,%A0,%B0) CR_TAB
3918 AS1 (clr,%B0) CR_TAB
3919 AS1 (lsr,%A0) CR_TAB
3920 AS1 (lsr,%A0) CR_TAB
3921 AS1 (lsr,%A0) CR_TAB
3922 AS1 (lsr,%A0) CR_TAB
3923 AS1 (lsr,%A0));
3924
3925 case 14:
3926 if (AVR_ENHANCED && ldi_ok)
3927 {
3928 *len = 5;
3929 return (AS2 (ldi,%A0,0x04) CR_TAB
3930 AS2 (mul,%B0,%A0) CR_TAB
3931 AS2 (mov,%A0,r1) CR_TAB
3932 AS1 (clr,%B0) CR_TAB
3933 AS1 (clr,__zero_reg__));
3934 }
3935 if (AVR_ENHANCED && scratch)
3936 {
3937 *len = 5;
3938 return (AS2 (ldi,%3,0x04) CR_TAB
3939 AS2 (mul,%B0,%3) CR_TAB
3940 AS2 (mov,%A0,r1) CR_TAB
3941 AS1 (clr,%B0) CR_TAB
3942 AS1 (clr,__zero_reg__));
3943 }
3944 if (optimize_size && ldi_ok)
3945 {
3946 *len = 5;
3947 return (AS2 (mov,%A0,%B0) CR_TAB
3948 AS2 (ldi,%B0,6) "\n1:\t"
3949 AS1 (lsr,%A0) CR_TAB
3950 AS1 (dec,%B0) CR_TAB
3951 AS1 (brne,1b));
3952 }
3953 if (optimize_size && scratch)
3954 break; /* 5 */
3955 *len = 6;
3956 return (AS1 (clr,%A0) CR_TAB
3957 AS1 (lsl,%B0) CR_TAB
3958 AS1 (rol,%A0) CR_TAB
3959 AS1 (lsl,%B0) CR_TAB
3960 AS1 (rol,%A0) CR_TAB
3961 AS1 (clr,%B0));
3962
3963 case 15:
3964 *len = 4;
3965 return (AS1 (clr,%A0) CR_TAB
3966 AS1 (lsl,%B0) CR_TAB
3967 AS1 (rol,%A0) CR_TAB
3968 AS1 (clr,%B0));
3969 }
3970 len = t;
3971 }
3972 out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
3973 AS1 (ror,%A0)),
3974 insn, operands, len, 2);
3975 return "";
3976 }
3977
3978 /* 32bit logic shift right ((unsigned int)x >> i) */
3979
3980 const char *
3981 lshrsi3_out (rtx insn, rtx operands[], int *len)
3982 {
3983 if (GET_CODE (operands[2]) == CONST_INT)
3984 {
3985 int k;
3986 int *t = len;
3987
3988 if (!len)
3989 len = &k;
3990
3991 switch (INTVAL (operands[2]))
3992 {
3993 case 8:
3994 {
3995 int reg0 = true_regnum (operands[0]);
3996 int reg1 = true_regnum (operands[1]);
3997 *len = 4;
3998 if (reg0 <= reg1)
3999 return (AS2 (mov,%A0,%B1) CR_TAB
4000 AS2 (mov,%B0,%C1) CR_TAB
4001 AS2 (mov,%C0,%D1) CR_TAB
4002 AS1 (clr,%D0));
4003 else if (reg0 == reg1 + 1)
4004 return *len = 1, AS1 (clr,%D0);
4005 else
4006 return (AS1 (clr,%D0) CR_TAB
4007 AS2 (mov,%C0,%D1) CR_TAB
4008 AS2 (mov,%B0,%C1) CR_TAB
4009 AS2 (mov,%A0,%B1));
4010 }
4011
4012 case 16:
4013 {
4014 int reg0 = true_regnum (operands[0]);
4015 int reg1 = true_regnum (operands[1]);
4016 *len = 4;
4017 if (AVR_ENHANCED && (reg0 != reg1 + 2))
4018 {
4019 *len = 3;
4020 return (AS2 (movw,%A0,%C1) CR_TAB
4021 AS1 (clr,%C0) CR_TAB
4022 AS1 (clr,%D0));
4023 }
4024 if (reg0 <= reg1 + 1)
4025 return (AS2 (mov,%A0,%C1) CR_TAB
4026 AS2 (mov,%B0,%D1) CR_TAB
4027 AS1 (clr,%C0) CR_TAB
4028 AS1 (clr,%D0));
4029 else if (reg0 == reg1 + 2)
4030 return *len = 2, (AS1 (clr,%C0) CR_TAB
4031 AS1 (clr,%D0));
4032 else
4033 return (AS2 (mov,%B0,%D1) CR_TAB
4034 AS2 (mov,%A0,%C1) CR_TAB
4035 AS1 (clr,%C0) CR_TAB
4036 AS1 (clr,%D0));
4037 }
4038
4039 case 24:
4040 if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
4041 return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4042 AS1 (clr,%B0) CR_TAB
4043 AS1 (clr,%C0) CR_TAB
4044 AS1 (clr,%D0));
4045 else
4046 return *len = 3, (AS1 (clr,%B0) CR_TAB
4047 AS1 (clr,%C0) CR_TAB
4048 AS1 (clr,%D0));
4049
4050 case 31:
4051 *len = 6;
4052 return (AS1 (clr,%A0) CR_TAB
4053 AS2 (sbrc,%D0,7) CR_TAB
4054 AS1 (inc,%A0) CR_TAB
4055 AS1 (clr,%B0) CR_TAB
4056 AS1 (clr,%C0) CR_TAB
4057 AS1 (clr,%D0));
4058 }
4059 len = t;
4060 }
4061 out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4062 AS1 (ror,%C0) CR_TAB
4063 AS1 (ror,%B0) CR_TAB
4064 AS1 (ror,%A0)),
4065 insn, operands, len, 4);
4066 return "";
4067 }
4068
4069 /* Modifies the length assigned to instruction INSN
4070 LEN is the initially computed length of the insn. */
4071
4072 int
4073 adjust_insn_length (rtx insn, int len)
4074 {
4075 rtx patt = PATTERN (insn);
4076 rtx set;
4077
4078 if (GET_CODE (patt) == SET)
4079 {
4080 rtx op[10];
4081 op[1] = SET_SRC (patt);
4082 op[0] = SET_DEST (patt);
4083 if (general_operand (op[1], VOIDmode)
4084 && general_operand (op[0], VOIDmode))
4085 {
4086 switch (GET_MODE (op[0]))
4087 {
4088 case QImode:
4089 output_movqi (insn, op, &len);
4090 break;
4091 case HImode:
4092 output_movhi (insn, op, &len);
4093 break;
4094 case SImode:
4095 case SFmode:
4096 output_movsisf (insn, op, &len);
4097 break;
4098 default:
4099 break;
4100 }
4101 }
4102 else if (op[0] == cc0_rtx && REG_P (op[1]))
4103 {
4104 switch (GET_MODE (op[1]))
4105 {
4106 case HImode: out_tsthi (insn,&len); break;
4107 case SImode: out_tstsi (insn,&len); break;
4108 default: break;
4109 }
4110 }
4111 else if (GET_CODE (op[1]) == AND)
4112 {
4113 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4114 {
4115 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4116 if (GET_MODE (op[1]) == SImode)
4117 len = (((mask & 0xff) != 0xff)
4118 + ((mask & 0xff00) != 0xff00)
4119 + ((mask & 0xff0000L) != 0xff0000L)
4120 + ((mask & 0xff000000L) != 0xff000000L));
4121 else if (GET_MODE (op[1]) == HImode)
4122 len = (((mask & 0xff) != 0xff)
4123 + ((mask & 0xff00) != 0xff00));
4124 }
4125 }
4126 else if (GET_CODE (op[1]) == IOR)
4127 {
4128 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4129 {
4130 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4131 if (GET_MODE (op[1]) == SImode)
4132 len = (((mask & 0xff) != 0)
4133 + ((mask & 0xff00) != 0)
4134 + ((mask & 0xff0000L) != 0)
4135 + ((mask & 0xff000000L) != 0));
4136 else if (GET_MODE (op[1]) == HImode)
4137 len = (((mask & 0xff) != 0)
4138 + ((mask & 0xff00) != 0));
4139 }
4140 }
4141 }
4142 set = single_set (insn);
4143 if (set)
4144 {
4145 rtx op[10];
4146
4147 op[1] = SET_SRC (set);
4148 op[0] = SET_DEST (set);
4149
4150 if (GET_CODE (patt) == PARALLEL
4151 && general_operand (op[1], VOIDmode)
4152 && general_operand (op[0], VOIDmode))
4153 {
4154 if (XVECLEN (patt, 0) == 2)
4155 op[2] = XVECEXP (patt, 0, 1);
4156
4157 switch (GET_MODE (op[0]))
4158 {
4159 case QImode:
4160 len = 2;
4161 break;
4162 case HImode:
4163 output_reload_inhi (insn, op, &len);
4164 break;
4165 case SImode:
4166 case SFmode:
4167 output_reload_insisf (insn, op, &len);
4168 break;
4169 default:
4170 break;
4171 }
4172 }
4173 else if (GET_CODE (op[1]) == ASHIFT
4174 || GET_CODE (op[1]) == ASHIFTRT
4175 || GET_CODE (op[1]) == LSHIFTRT)
4176 {
4177 rtx ops[10];
4178 ops[0] = op[0];
4179 ops[1] = XEXP (op[1],0);
4180 ops[2] = XEXP (op[1],1);
4181 switch (GET_CODE (op[1]))
4182 {
4183 case ASHIFT:
4184 switch (GET_MODE (op[0]))
4185 {
4186 case QImode: ashlqi3_out (insn,ops,&len); break;
4187 case HImode: ashlhi3_out (insn,ops,&len); break;
4188 case SImode: ashlsi3_out (insn,ops,&len); break;
4189 default: break;
4190 }
4191 break;
4192 case ASHIFTRT:
4193 switch (GET_MODE (op[0]))
4194 {
4195 case QImode: ashrqi3_out (insn,ops,&len); break;
4196 case HImode: ashrhi3_out (insn,ops,&len); break;
4197 case SImode: ashrsi3_out (insn,ops,&len); break;
4198 default: break;
4199 }
4200 break;
4201 case LSHIFTRT:
4202 switch (GET_MODE (op[0]))
4203 {
4204 case QImode: lshrqi3_out (insn,ops,&len); break;
4205 case HImode: lshrhi3_out (insn,ops,&len); break;
4206 case SImode: lshrsi3_out (insn,ops,&len); break;
4207 default: break;
4208 }
4209 break;
4210 default:
4211 break;
4212 }
4213 }
4214 }
4215 return len;
4216 }
4217
4218 /* Return nonzero if register REG dead after INSN. */
4219
4220 int
4221 reg_unused_after (rtx insn, rtx reg)
4222 {
4223 return (dead_or_set_p (insn, reg)
4224 || (REG_P(reg) && _reg_unused_after (insn, reg)));
4225 }
4226
4227 /* Return nonzero if REG is not used after INSN.
4228 We assume REG is a reload reg, and therefore does
4229 not live past labels. It may live past calls or jumps though. */
4230
4231 int
4232 _reg_unused_after (rtx insn, rtx reg)
4233 {
4234 enum rtx_code code;
4235 rtx set;
4236
4237 /* If the reg is set by this instruction, then it is safe for our
4238 case. Disregard the case where this is a store to memory, since
4239 we are checking a register used in the store address. */
4240 set = single_set (insn);
4241 if (set && GET_CODE (SET_DEST (set)) != MEM
4242 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4243 return 1;
4244
4245 while ((insn = NEXT_INSN (insn)))
4246 {
4247 code = GET_CODE (insn);
4248
4249 #if 0
4250 /* If this is a label that existed before reload, then the register
4251 if dead here. However, if this is a label added by reorg, then
4252 the register may still be live here. We can't tell the difference,
4253 so we just ignore labels completely. */
4254 if (code == CODE_LABEL)
4255 return 1;
4256 /* else */
4257 #endif
4258
4259 if (code == JUMP_INSN)
4260 return 0;
4261
4262 /* If this is a sequence, we must handle them all at once.
4263 We could have for instance a call that sets the target register,
4264 and an insn in a delay slot that uses the register. In this case,
4265 we must return 0. */
4266 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
4267 {
4268 int i;
4269 int retval = 0;
4270
4271 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
4272 {
4273 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
4274 rtx set = single_set (this_insn);
4275
4276 if (GET_CODE (this_insn) == CALL_INSN)
4277 code = CALL_INSN;
4278 else if (GET_CODE (this_insn) == JUMP_INSN)
4279 {
4280 if (INSN_ANNULLED_BRANCH_P (this_insn))
4281 return 0;
4282 code = JUMP_INSN;
4283 }
4284
4285 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4286 return 0;
4287 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4288 {
4289 if (GET_CODE (SET_DEST (set)) != MEM)
4290 retval = 1;
4291 else
4292 return 0;
4293 }
4294 if (set == 0
4295 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
4296 return 0;
4297 }
4298 if (retval == 1)
4299 return 1;
4300 else if (code == JUMP_INSN)
4301 return 0;
4302 }
4303
4304 if (code == CALL_INSN)
4305 {
4306 rtx tem;
4307 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4308 if (GET_CODE (XEXP (tem, 0)) == USE
4309 && REG_P (XEXP (XEXP (tem, 0), 0))
4310 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
4311 return 0;
4312 if (call_used_regs[REGNO (reg)])
4313 return 1;
4314 }
4315
4316 if (GET_RTX_CLASS (code) == 'i')
4317 {
4318 rtx set = single_set (insn);
4319
4320 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4321 return 0;
4322 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4323 return GET_CODE (SET_DEST (set)) != MEM;
4324 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
4325 return 0;
4326 }
4327 }
4328 return 1;
4329 }
4330
4331 /* Target hook for assembling integer objects. The AVR version needs
4332 special handling for references to certain labels. */
4333
4334 static bool
4335 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
4336 {
4337 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
4338 && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x))
4339 || GET_CODE (x) == LABEL_REF))
4340 {
4341 fputs ("\t.word\tpm(", asm_out_file);
4342 output_addr_const (asm_out_file, x);
4343 fputs (")\n", asm_out_file);
4344 return true;
4345 }
4346 return default_assemble_integer (x, size, aligned_p);
4347 }
4348
4349 /* Sets section name for declaration DECL. */
4350
4351 static void
4352 avr_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
4353 {
4354 int len;
4355 const char *name, *prefix;
4356 char *string;
4357
4358 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
4359 name = (* targetm.strip_name_encoding) (name);
4360
4361 if (TREE_CODE (decl) == FUNCTION_DECL)
4362 {
4363 if (flag_function_sections)
4364 prefix = ".text.";
4365 else
4366 prefix = ".text";
4367 }
4368 else
4369 abort ();
4370
4371 if (flag_function_sections)
4372 {
4373 len = strlen (name) + strlen (prefix);
4374 string = alloca (len + 1);
4375 sprintf (string, "%s%s", prefix, name);
4376 DECL_SECTION_NAME (decl) = build_string (len, string);
4377 }
4378 }
4379
4380
4381 /* The routine used to output NUL terminated strings. We use a special
4382 version of this for most svr4 targets because doing so makes the
4383 generated assembly code more compact (and thus faster to assemble)
4384 as well as more readable, especially for targets like the i386
4385 (where the only alternative is to output character sequences as
4386 comma separated lists of numbers). */
4387
4388 void
4389 gas_output_limited_string(FILE *file, const char *str)
4390 {
4391 const unsigned char *_limited_str = (unsigned char *) str;
4392 unsigned ch;
4393 fprintf (file, "%s\"", STRING_ASM_OP);
4394 for (; (ch = *_limited_str); _limited_str++)
4395 {
4396 int escape;
4397 switch (escape = ESCAPES[ch])
4398 {
4399 case 0:
4400 putc (ch, file);
4401 break;
4402 case 1:
4403 fprintf (file, "\\%03o", ch);
4404 break;
4405 default:
4406 putc ('\\', file);
4407 putc (escape, file);
4408 break;
4409 }
4410 }
4411 fprintf (file, "\"\n");
4412 }
4413
4414 /* The routine used to output sequences of byte values. We use a special
4415 version of this for most svr4 targets because doing so makes the
4416 generated assembly code more compact (and thus faster to assemble)
4417 as well as more readable. Note that if we find subparts of the
4418 character sequence which end with NUL (and which are shorter than
4419 STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
4420
4421 void
4422 gas_output_ascii(FILE *file, const char *str, size_t length)
4423 {
4424 const unsigned char *_ascii_bytes = (const unsigned char *) str;
4425 const unsigned char *limit = _ascii_bytes + length;
4426 unsigned bytes_in_chunk = 0;
4427 for (; _ascii_bytes < limit; _ascii_bytes++)
4428 {
4429 const unsigned char *p;
4430 if (bytes_in_chunk >= 60)
4431 {
4432 fprintf (file, "\"\n");
4433 bytes_in_chunk = 0;
4434 }
4435 for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
4436 continue;
4437 if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
4438 {
4439 if (bytes_in_chunk > 0)
4440 {
4441 fprintf (file, "\"\n");
4442 bytes_in_chunk = 0;
4443 }
4444 gas_output_limited_string (file, (char*)_ascii_bytes);
4445 _ascii_bytes = p;
4446 }
4447 else
4448 {
4449 int escape;
4450 unsigned ch;
4451 if (bytes_in_chunk == 0)
4452 fprintf (file, "\t.ascii\t\"");
4453 switch (escape = ESCAPES[ch = *_ascii_bytes])
4454 {
4455 case 0:
4456 putc (ch, file);
4457 bytes_in_chunk++;
4458 break;
4459 case 1:
4460 fprintf (file, "\\%03o", ch);
4461 bytes_in_chunk += 4;
4462 break;
4463 default:
4464 putc ('\\', file);
4465 putc (escape, file);
4466 bytes_in_chunk += 2;
4467 break;
4468 }
4469 }
4470 }
4471 if (bytes_in_chunk > 0)
4472 fprintf (file, "\"\n");
4473 }
4474
4475 /* Return value is nonzero if pseudos that have been
4476 assigned to registers of class CLASS would likely be spilled
4477 because registers of CLASS are needed for spill registers. */
4478
4479 enum reg_class
4480 class_likely_spilled_p (int c)
4481 {
4482 return (c != ALL_REGS && c != ADDW_REGS);
4483 }
4484
4485 /* Valid attributes:
4486 progmem - put data to program memory;
4487 signal - make a function to be hardware interrupt. After function
4488 prologue interrupts are disabled;
4489 interrupt - make a function to be hardware interrupt. After function
4490 prologue interrupts are enabled;
4491 naked - don't generate function prologue/epilogue and `ret' command.
4492
4493 Only `progmem' attribute valid for type. */
4494
4495 const struct attribute_spec avr_attribute_table[] =
4496 {
4497 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
4498 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute },
4499 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4500 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4501 { "naked", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4502 { NULL, 0, 0, false, false, false, NULL }
4503 };
4504
4505 /* Handle a "progmem" attribute; arguments as in
4506 struct attribute_spec.handler. */
4507 static tree
4508 avr_handle_progmem_attribute (tree *node, tree name,
4509 tree args ATTRIBUTE_UNUSED,
4510 int flags ATTRIBUTE_UNUSED,
4511 bool *no_add_attrs)
4512 {
4513 if (DECL_P (*node))
4514 {
4515 if (TREE_CODE (*node) == TYPE_DECL)
4516 {
4517 /* This is really a decl attribute, not a type attribute,
4518 but try to handle it for GCC 3.0 backwards compatibility. */
4519
4520 tree type = TREE_TYPE (*node);
4521 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
4522 tree newtype = build_type_attribute_variant (type, attr);
4523
4524 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
4525 TREE_TYPE (*node) = newtype;
4526 *no_add_attrs = true;
4527 }
4528 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
4529 {
4530 if (DECL_INITIAL (*node) == NULL_TREE && !DECL_EXTERNAL (*node))
4531 {
4532 warning ("only initialized variables can be placed into "
4533 "program memory area");
4534 *no_add_attrs = true;
4535 }
4536 }
4537 else
4538 {
4539 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
4540 *no_add_attrs = true;
4541 }
4542 }
4543
4544 return NULL_TREE;
4545 }
4546
4547 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
4548 struct attribute_spec.handler. */
4549
4550 static tree
4551 avr_handle_fndecl_attribute (tree *node, tree name,
4552 tree args ATTRIBUTE_UNUSED,
4553 int flags ATTRIBUTE_UNUSED,
4554 bool *no_add_attrs)
4555 {
4556 if (TREE_CODE (*node) != FUNCTION_DECL)
4557 {
4558 warning ("`%s' attribute only applies to functions",
4559 IDENTIFIER_POINTER (name));
4560 *no_add_attrs = true;
4561 }
4562
4563 return NULL_TREE;
4564 }
4565
4566 /* Look for attribute `progmem' in DECL
4567 if found return 1, otherwise 0. */
4568
4569 int
4570 avr_progmem_p (tree decl)
4571 {
4572 tree a;
4573
4574 if (TREE_CODE (decl) != VAR_DECL)
4575 return 0;
4576
4577 if (NULL_TREE
4578 != lookup_attribute ("progmem", DECL_ATTRIBUTES (decl)))
4579 return 1;
4580
4581 a=decl;
4582 do
4583 a = TREE_TYPE(a);
4584 while (TREE_CODE (a) == ARRAY_TYPE);
4585
4586 if (a == error_mark_node)
4587 return 0;
4588
4589 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
4590 return 1;
4591
4592 return 0;
4593 }
4594
4595 /* Add the section attribute if the variable is in progmem. */
4596
4597 static void
4598 avr_insert_attributes (tree node, tree *attributes)
4599 {
4600 if (TREE_CODE (node) == VAR_DECL
4601 && (TREE_STATIC (node) || DECL_EXTERNAL (node))
4602 && avr_progmem_p (node))
4603 {
4604 static const char dsec[] = ".progmem.data";
4605 *attributes = tree_cons (get_identifier ("section"),
4606 build_tree_list (NULL, build_string (strlen (dsec), dsec)),
4607 *attributes);
4608
4609 /* ??? This seems sketchy. Why can't the user declare the
4610 thing const in the first place? */
4611 TREE_READONLY (node) = 1;
4612 }
4613 }
4614
4615 static unsigned int
4616 avr_section_type_flags (tree decl, const char *name, int reloc)
4617 {
4618 unsigned int flags = default_section_type_flags (decl, name, reloc);
4619
4620 if (strncmp (name, ".noinit", 7) == 0)
4621 {
4622 if (decl && TREE_CODE (decl) == VAR_DECL
4623 && DECL_INITIAL (decl) == NULL_TREE)
4624 flags |= SECTION_BSS; /* @nobits */
4625 else
4626 warning ("only uninitialized variables can be placed in the "
4627 ".noinit section");
4628 }
4629
4630 return flags;
4631 }
4632
4633 /* Outputs some appropriate text to go at the start of an assembler
4634 file. */
4635
4636 static void
4637 avr_file_start (void)
4638 {
4639 if (avr_asm_only_p)
4640 error ("MCU `%s' supported for assembler only", avr_mcu_name);
4641
4642 default_file_start ();
4643
4644 fprintf (asm_out_file, "\t.arch %s\n", avr_mcu_name);
4645 fputs ("__SREG__ = 0x3f\n"
4646 "__SP_H__ = 0x3e\n"
4647 "__SP_L__ = 0x3d\n", asm_out_file);
4648
4649 fputs ("__tmp_reg__ = 0\n"
4650 "__zero_reg__ = 1\n", asm_out_file);
4651
4652 /* FIXME: output these only if there is anything in the .data / .bss
4653 sections - some code size could be saved by not linking in the
4654 initialization code from libgcc if one or both sections are empty. */
4655 fputs ("\t.global __do_copy_data\n", asm_out_file);
4656 fputs ("\t.global __do_clear_bss\n", asm_out_file);
4657
4658 commands_in_file = 0;
4659 commands_in_prologues = 0;
4660 commands_in_epilogues = 0;
4661 }
4662
4663 /* Outputs to the stdio stream FILE some
4664 appropriate text to go at the end of an assembler file. */
4665
4666 static void
4667 avr_file_end (void)
4668 {
4669 fputs ("/* File ", asm_out_file);
4670 output_quoted_string (asm_out_file, main_input_filename);
4671 fprintf (asm_out_file,
4672 ": code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
4673 commands_in_file,
4674 commands_in_file,
4675 commands_in_file - commands_in_prologues - commands_in_epilogues,
4676 commands_in_prologues, commands_in_epilogues);
4677 }
4678
4679 /* Choose the order in which to allocate hard registers for
4680 pseudo-registers local to a basic block.
4681
4682 Store the desired register order in the array `reg_alloc_order'.
4683 Element 0 should be the register to allocate first; element 1, the
4684 next register; and so on. */
4685
4686 void
4687 order_regs_for_local_alloc (void)
4688 {
4689 unsigned int i;
4690 static const int order_0[] = {
4691 24,25,
4692 18,19,
4693 20,21,
4694 22,23,
4695 30,31,
4696 26,27,
4697 28,29,
4698 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4699 0,1,
4700 32,33,34,35
4701 };
4702 static const int order_1[] = {
4703 18,19,
4704 20,21,
4705 22,23,
4706 24,25,
4707 30,31,
4708 26,27,
4709 28,29,
4710 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4711 0,1,
4712 32,33,34,35
4713 };
4714 static const int order_2[] = {
4715 25,24,
4716 23,22,
4717 21,20,
4718 19,18,
4719 30,31,
4720 26,27,
4721 28,29,
4722 17,16,
4723 15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4724 1,0,
4725 32,33,34,35
4726 };
4727
4728 const int *order = (TARGET_ORDER_1 ? order_1 :
4729 TARGET_ORDER_2 ? order_2 :
4730 order_0);
4731 for (i=0; i < ARRAY_SIZE (order_0); ++i)
4732 reg_alloc_order[i] = order[i];
4733 }
4734
4735 /* Calculate the cost of X code of the expression in which it is contained,
4736 found in OUTER_CODE */
4737
4738 static int
4739 default_rtx_costs (rtx X, enum rtx_code code, enum rtx_code outer_code)
4740 {
4741 int cost=0;
4742 switch (code)
4743 {
4744 case SYMBOL_REF:
4745 case LABEL_REF:
4746 cost = 2 * GET_MODE_SIZE (GET_MODE (X));
4747 break;
4748 case MEM:
4749 if (outer_code != SET)
4750 cost = 1;
4751 if (GET_CODE (XEXP (X,0)) == SYMBOL_REF)
4752 cost += 2 * GET_MODE_SIZE (GET_MODE (X));
4753 else
4754 cost += GET_MODE_SIZE (GET_MODE (X));
4755 break;
4756 case CONST_INT:
4757 cost = 0;
4758 break;
4759 case SIGN_EXTEND:
4760 if (outer_code == SET)
4761 cost = GET_MODE_SIZE (GET_MODE (X));
4762 else
4763 cost = -GET_MODE_SIZE (GET_MODE (X));
4764 break;
4765 case ZERO_EXTEND:
4766 if (outer_code == SET)
4767 cost = GET_MODE_SIZE (GET_MODE (X));
4768 else
4769 cost = -1;
4770 break;
4771 case PLUS:
4772 case MINUS:
4773 if (outer_code == SET)
4774 {
4775 if (X == stack_pointer_rtx)
4776 cost = -10;
4777 else if (GET_CODE (XEXP (X,1)) == CONST_INT)
4778 cost = (INTVAL (XEXP (X,1)) <= 63 ? 1 :
4779 GET_MODE_SIZE (GET_MODE (X)));
4780 else
4781 cost = GET_MODE_SIZE (GET_MODE (X));
4782 }
4783 break;
4784 case COMPARE:
4785 if (GET_CODE (XEXP (X,1)) == CONST_INT)
4786 cost = GET_MODE_SIZE (GET_MODE (XEXP (X,0)));
4787 break;
4788 default:
4789 break;
4790 }
4791 return cost;
4792 }
4793
4794 static bool
4795 avr_rtx_costs (rtx x, int code, int outer_code, int *total)
4796 {
4797 int cst;
4798
4799 switch (code)
4800 {
4801 case CONST_INT:
4802 if (outer_code == PLUS
4803 || outer_code == IOR
4804 || outer_code == AND
4805 || outer_code == MINUS
4806 || outer_code == SET
4807 || INTVAL (x) == 0)
4808 {
4809 *total = 2;
4810 return true;
4811 }
4812 if (outer_code == COMPARE
4813 && INTVAL (x) >= 0
4814 && INTVAL (x) <= 255)
4815 {
4816 *total = 2;
4817 return true;
4818 }
4819 /* FALLTHRU */
4820
4821 case CONST:
4822 case LABEL_REF:
4823 case SYMBOL_REF:
4824 case CONST_DOUBLE:
4825 *total = 4;
4826 return true;
4827
4828 default:
4829 cst = default_rtx_costs (x, code, outer_code);
4830 if (cst > 0)
4831 {
4832 *total = cst;
4833 return true;
4834 }
4835 else if (cst < 0)
4836 *total += -cst;
4837 return false;
4838 }
4839 }
4840
4841 /* Calculate the cost of a memory address. */
4842
4843 static int
4844 avr_address_cost (rtx x)
4845 {
4846 if (GET_CODE (x) == PLUS
4847 && GET_CODE (XEXP (x,1)) == CONST_INT
4848 && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
4849 && INTVAL (XEXP (x,1)) >= 61)
4850 return 18;
4851 if (CONSTANT_ADDRESS_P (x))
4852 {
4853 if (avr_io_address_p (x, 1))
4854 return 2;
4855 return 4;
4856 }
4857 return 4;
4858 }
4859
4860 /* EXTRA_CONSTRAINT helper */
4861
4862 int
4863 extra_constraint (rtx x, int c)
4864 {
4865 if (c == 'Q'
4866 && GET_CODE (x) == MEM
4867 && GET_CODE (XEXP (x,0)) == PLUS)
4868 {
4869 if (TARGET_ALL_DEBUG)
4870 {
4871 fprintf (stderr, ("extra_constraint:\n"
4872 "reload_completed: %d\n"
4873 "reload_in_progress: %d\n"),
4874 reload_completed, reload_in_progress);
4875 debug_rtx (x);
4876 }
4877 if (GET_CODE (x) == MEM
4878 && GET_CODE (XEXP (x,0)) == PLUS
4879 && REG_P (XEXP (XEXP (x,0), 0))
4880 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
4881 && (INTVAL (XEXP (XEXP (x,0), 1))
4882 <= MAX_LD_OFFSET (GET_MODE (x))))
4883 {
4884 rtx xx = XEXP (XEXP (x,0), 0);
4885 int regno = REGNO (xx);
4886 if (TARGET_ALL_DEBUG)
4887 {
4888 fprintf (stderr, ("extra_constraint:\n"
4889 "reload_completed: %d\n"
4890 "reload_in_progress: %d\n"),
4891 reload_completed, reload_in_progress);
4892 debug_rtx (x);
4893 }
4894 if (regno >= FIRST_PSEUDO_REGISTER)
4895 return 1; /* allocate pseudos */
4896 else if (regno == REG_Z || regno == REG_Y)
4897 return 1; /* strictly check */
4898 else if (xx == frame_pointer_rtx
4899 || xx == arg_pointer_rtx)
4900 return 1; /* XXX frame & arg pointer checks */
4901 }
4902 }
4903 return 0;
4904 }
4905
4906 /* Convert condition code CONDITION to the valid AVR condition code. */
4907
4908 RTX_CODE
4909 avr_normalize_condition (RTX_CODE condition)
4910 {
4911 switch (condition)
4912 {
4913 case GT:
4914 return GE;
4915 case GTU:
4916 return GEU;
4917 case LE:
4918 return LT;
4919 case LEU:
4920 return LTU;
4921 default:
4922 abort ();
4923 }
4924 }
4925
4926 /* This function optimizes conditional jumps. */
4927
4928 static void
4929 avr_reorg (void)
4930 {
4931 rtx insn, pattern;
4932
4933 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4934 {
4935 if (! (GET_CODE (insn) == INSN
4936 || GET_CODE (insn) == CALL_INSN
4937 || GET_CODE (insn) == JUMP_INSN)
4938 || !single_set (insn))
4939 continue;
4940
4941 pattern = PATTERN (insn);
4942
4943 if (GET_CODE (pattern) == PARALLEL)
4944 pattern = XVECEXP (pattern, 0, 0);
4945 if (GET_CODE (pattern) == SET
4946 && SET_DEST (pattern) == cc0_rtx
4947 && compare_diff_p (insn))
4948 {
4949 if (GET_CODE (SET_SRC (pattern)) == COMPARE)
4950 {
4951 /* Now we work under compare insn. */
4952
4953 pattern = SET_SRC (pattern);
4954 if (true_regnum (XEXP (pattern,0)) >= 0
4955 && true_regnum (XEXP (pattern,1)) >= 0 )
4956 {
4957 rtx x = XEXP (pattern,0);
4958 rtx next = next_real_insn (insn);
4959 rtx pat = PATTERN (next);
4960 rtx src = SET_SRC (pat);
4961 rtx t = XEXP (src,0);
4962 PUT_CODE (t, swap_condition (GET_CODE (t)));
4963 XEXP (pattern,0) = XEXP (pattern,1);
4964 XEXP (pattern,1) = x;
4965 INSN_CODE (next) = -1;
4966 }
4967 else if (true_regnum (XEXP (pattern,0)) >= 0
4968 && GET_CODE (XEXP (pattern,1)) == CONST_INT)
4969 {
4970 rtx x = XEXP (pattern,1);
4971 rtx next = next_real_insn (insn);
4972 rtx pat = PATTERN (next);
4973 rtx src = SET_SRC (pat);
4974 rtx t = XEXP (src,0);
4975 enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
4976
4977 if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
4978 {
4979 XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
4980 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
4981 INSN_CODE (next) = -1;
4982 INSN_CODE (insn) = -1;
4983 }
4984 }
4985 }
4986 else if (true_regnum (SET_SRC (pattern)) >= 0)
4987 {
4988 /* This is a tst insn */
4989 rtx next = next_real_insn (insn);
4990 rtx pat = PATTERN (next);
4991 rtx src = SET_SRC (pat);
4992 rtx t = XEXP (src,0);
4993
4994 PUT_CODE (t, swap_condition (GET_CODE (t)));
4995 SET_SRC (pattern) = gen_rtx (NEG,
4996 GET_MODE (SET_SRC (pattern)),
4997 SET_SRC (pattern));
4998 INSN_CODE (next) = -1;
4999 INSN_CODE (insn) = -1;
5000 }
5001 }
5002 }
5003 }
5004
5005 /* Returns register number for function return value.*/
5006
5007 int
5008 avr_ret_register (void)
5009 {
5010 return 24;
5011 }
5012
5013 /* Ceate an RTX representing the place where a
5014 library function returns a value of mode MODE. */
5015
5016 rtx
5017 avr_libcall_value (enum machine_mode mode)
5018 {
5019 int offs = GET_MODE_SIZE (mode);
5020 if (offs < 2)
5021 offs = 2;
5022 return gen_rtx (REG, mode, RET_REGISTER + 2 - offs);
5023 }
5024
5025 /* Create an RTX representing the place where a
5026 function returns a value of data type VALTYPE. */
5027
5028 rtx
5029 avr_function_value (tree type, tree func ATTRIBUTE_UNUSED)
5030 {
5031 unsigned int offs;
5032
5033 if (TYPE_MODE (type) != BLKmode)
5034 return avr_libcall_value (TYPE_MODE (type));
5035
5036 offs = int_size_in_bytes (type);
5037 if (offs < 2)
5038 offs = 2;
5039 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
5040 offs = GET_MODE_SIZE (SImode);
5041 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
5042 offs = GET_MODE_SIZE (DImode);
5043
5044 return gen_rtx (REG, BLKmode, RET_REGISTER + 2 - offs);
5045 }
5046
5047 /* Returns nonzero if the number MASK has only one bit set. */
5048
5049 int
5050 mask_one_bit_p (HOST_WIDE_INT mask)
5051 {
5052 int i;
5053 unsigned HOST_WIDE_INT n=mask;
5054 for (i = 0; i < 32; ++i)
5055 {
5056 if (n & 0x80000000L)
5057 {
5058 if (n & 0x7fffffffL)
5059 return 0;
5060 else
5061 return 32-i;
5062 }
5063 n<<=1;
5064 }
5065 return 0;
5066 }
5067
5068
5069 /* Places additional restrictions on the register class to
5070 use when it is necessary to copy value X into a register
5071 in class CLASS. */
5072
5073 enum reg_class
5074 preferred_reload_class (rtx x ATTRIBUTE_UNUSED, enum reg_class class)
5075 {
5076 return class;
5077 }
5078
5079 int
5080 test_hard_reg_class (enum reg_class class, rtx x)
5081 {
5082 int regno = true_regnum (x);
5083 if (regno < 0)
5084 return 0;
5085
5086 if (TEST_HARD_REG_CLASS (class, regno))
5087 return 1;
5088
5089 return 0;
5090 }
5091
5092
5093 int
5094 jump_over_one_insn_p (rtx insn, rtx dest)
5095 {
5096 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
5097 ? XEXP (dest, 0)
5098 : dest);
5099 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
5100 int dest_addr = INSN_ADDRESSES (uid);
5101 return dest_addr - jump_addr == get_attr_length (insn) + 1;
5102 }
5103
5104 /* Returns 1 if a value of mode MODE can be stored starting with hard
5105 register number REGNO. On the enhanced core, anything larger than
5106 1 byte must start in even numbered register for "movw" to work
5107 (this way we don't have to check for odd registers everywhere). */
5108
5109 int
5110 avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
5111 {
5112 /* Bug workaround: recog.c (peep2_find_free_register) and probably
5113 a few other places assume that the frame pointer is a single hard
5114 register, so r29 may be allocated and overwrite the high byte of
5115 the frame pointer. Do not allow any value to start in r29. */
5116 if (regno == REG_Y + 1)
5117 return 0;
5118
5119 if (mode == QImode)
5120 return 1;
5121 /* if (regno < 24 && !AVR_ENHANCED)
5122 return 1;*/
5123 return !(regno & 1);
5124 }
5125
5126 /* Returns 1 if X is a valid address for an I/O register of size SIZE
5127 (1 or 2). Used for lds/sts -> in/out optimization. Add 0x20 to SIZE
5128 to check for the lower half of I/O space (for cbi/sbi/sbic/sbis). */
5129
5130 int
5131 avr_io_address_p (rtx x, int size)
5132 {
5133 return (optimize > 0 && GET_CODE (x) == CONST_INT
5134 && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size);
5135 }
5136
5137 /* Returns nonzero (bit number + 1) if X, or -X, is a constant power of 2. */
5138
5139 int
5140 const_int_pow2_p (rtx x)
5141 {
5142 if (GET_CODE (x) == CONST_INT)
5143 {
5144 HOST_WIDE_INT d = INTVAL (x);
5145 HOST_WIDE_INT abs_d = (d >= 0) ? d : -d;
5146 return exact_log2 (abs_d) + 1;
5147 }
5148 return 0;
5149 }
5150
5151 const char *
5152 output_reload_inhi (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
5153 {
5154 int tmp;
5155 if (!len)
5156 len = &tmp;
5157
5158 if (GET_CODE (operands[1]) == CONST_INT)
5159 {
5160 int val = INTVAL (operands[1]);
5161 if ((val & 0xff) == 0)
5162 {
5163 *len = 3;
5164 return (AS2 (mov,%A0,__zero_reg__) CR_TAB
5165 AS2 (ldi,%2,hi8(%1)) CR_TAB
5166 AS2 (mov,%B0,%2));
5167 }
5168 else if ((val & 0xff00) == 0)
5169 {
5170 *len = 3;
5171 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5172 AS2 (mov,%A0,%2) CR_TAB
5173 AS2 (mov,%B0,__zero_reg__));
5174 }
5175 else if ((val & 0xff) == ((val & 0xff00) >> 8))
5176 {
5177 *len = 3;
5178 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5179 AS2 (mov,%A0,%2) CR_TAB
5180 AS2 (mov,%B0,%2));
5181 }
5182 }
5183 *len = 4;
5184 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5185 AS2 (mov,%A0,%2) CR_TAB
5186 AS2 (ldi,%2,hi8(%1)) CR_TAB
5187 AS2 (mov,%B0,%2));
5188 }
5189
5190
5191 const char *
5192 output_reload_insisf (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
5193 {
5194 rtx src = operands[1];
5195 int cnst = (GET_CODE (src) == CONST_INT);
5196
5197 if (len)
5198 {
5199 if (cnst)
5200 *len = 4 + ((INTVAL (src) & 0xff) != 0)
5201 + ((INTVAL (src) & 0xff00) != 0)
5202 + ((INTVAL (src) & 0xff0000) != 0)
5203 + ((INTVAL (src) & 0xff000000) != 0);
5204 else
5205 *len = 8;
5206
5207 return "";
5208 }
5209
5210 if (cnst && ((INTVAL (src) & 0xff) == 0))
5211 output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
5212 else
5213 {
5214 output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
5215 output_asm_insn (AS2 (mov, %A0, %2), operands);
5216 }
5217 if (cnst && ((INTVAL (src) & 0xff00) == 0))
5218 output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
5219 else
5220 {
5221 output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
5222 output_asm_insn (AS2 (mov, %B0, %2), operands);
5223 }
5224 if (cnst && ((INTVAL (src) & 0xff0000) == 0))
5225 output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
5226 else
5227 {
5228 output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
5229 output_asm_insn (AS2 (mov, %C0, %2), operands);
5230 }
5231 if (cnst && ((INTVAL (src) & 0xff000000) == 0))
5232 output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
5233 else
5234 {
5235 output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
5236 output_asm_insn (AS2 (mov, %D0, %2), operands);
5237 }
5238 return "";
5239 }
5240
5241 void
5242 avr_output_bld (rtx operands[], int bit_nr)
5243 {
5244 static char s[] = "bld %A0,0";
5245
5246 s[5] = 'A' + (bit_nr >> 3);
5247 s[8] = '0' + (bit_nr & 7);
5248 output_asm_insn (s, operands);
5249 }
5250
5251 void
5252 avr_output_addr_vec_elt (FILE *stream, int value)
5253 {
5254 if (AVR_MEGA)
5255 fprintf (stream, "\t.word pm(.L%d)\n", value);
5256 else
5257 fprintf (stream, "\trjmp .L%d\n", value);
5258
5259 jump_tables_size++;
5260 }
5261
5262 /* Returns 1 if SCRATCH are safe to be allocated as a scratch
5263 registers (for a define_peephole2) in the current function. */
5264
5265 int
5266 avr_peep2_scratch_safe (rtx scratch)
5267 {
5268 if ((interrupt_function_p (current_function_decl)
5269 || signal_function_p (current_function_decl))
5270 && leaf_function_p ())
5271 {
5272 int first_reg = true_regnum (scratch);
5273 int last_reg = first_reg + GET_MODE_SIZE (GET_MODE (scratch)) - 1;
5274 int reg;
5275
5276 for (reg = first_reg; reg <= last_reg; reg++)
5277 {
5278 if (!regs_ever_live[reg])
5279 return 0;
5280 }
5281 }
5282 return 1;
5283 }
5284
5285 /* Output a branch that tests a single bit of a register (QI, HI or SImode)
5286 or memory location in the I/O space (QImode only).
5287
5288 Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
5289 Operand 1: register operand to test, or CONST_INT memory address.
5290 Operand 2: bit number (for QImode operand) or mask (HImode, SImode).
5291 Operand 3: label to jump to if the test is true. */
5292
5293 const char *
5294 avr_out_sbxx_branch (rtx insn, rtx operands[])
5295 {
5296 enum rtx_code comp = GET_CODE (operands[0]);
5297 int long_jump = (get_attr_length (insn) >= 4);
5298 int reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
5299
5300 if (comp == GE)
5301 comp = EQ;
5302 else if (comp == LT)
5303 comp = NE;
5304
5305 if (reverse)
5306 comp = reverse_condition (comp);
5307
5308 if (GET_CODE (operands[1]) == CONST_INT)
5309 {
5310 if (INTVAL (operands[1]) < 0x40)
5311 {
5312 if (comp == EQ)
5313 output_asm_insn (AS2 (sbis,%1-0x20,%2), operands);
5314 else
5315 output_asm_insn (AS2 (sbic,%1-0x20,%2), operands);
5316 }
5317 else
5318 {
5319 output_asm_insn (AS2 (in,__tmp_reg__,%1-0x20), operands);
5320 if (comp == EQ)
5321 output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands);
5322 else
5323 output_asm_insn (AS2 (sbrc,__tmp_reg__,%2), operands);
5324 }
5325 }
5326 else /* GET_CODE (operands[1]) == REG */
5327 {
5328 if (GET_MODE (operands[1]) == QImode)
5329 {
5330 if (comp == EQ)
5331 output_asm_insn (AS2 (sbrs,%1,%2), operands);
5332 else
5333 output_asm_insn (AS2 (sbrc,%1,%2), operands);
5334 }
5335 else /* HImode or SImode */
5336 {
5337 static char buf[] = "sbrc %A1,0";
5338 int bit_nr = exact_log2 (INTVAL (operands[2])
5339 & GET_MODE_MASK (GET_MODE (operands[1])));
5340
5341 buf[3] = (comp == EQ) ? 's' : 'c';
5342 buf[6] = 'A' + (bit_nr >> 3);
5343 buf[9] = '0' + (bit_nr & 7);
5344 output_asm_insn (buf, operands);
5345 }
5346 }
5347
5348 if (long_jump)
5349 return (AS1 (rjmp,.+4) CR_TAB
5350 AS1 (jmp,%3));
5351 if (!reverse)
5352 return AS1 (rjmp,%3);
5353 return "";
5354 }
5355
5356 static void
5357 avr_asm_out_ctor (rtx symbol, int priority)
5358 {
5359 fputs ("\t.global __do_global_ctors\n", asm_out_file);
5360 default_ctor_section_asm_out_constructor (symbol, priority);
5361 }
5362
5363 static void
5364 avr_asm_out_dtor (rtx symbol, int priority)
5365 {
5366 fputs ("\t.global __do_global_dtors\n", asm_out_file);
5367 default_dtor_section_asm_out_destructor (symbol, priority);
5368 }
5369
5370 #include "gt-avr.h"