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