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