]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/avr/avr.c
decl.c, [...]: Remove redundant enum from machine_mode.
[thirdparty/gcc.git] / gcc / config / avr / avr.c
1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2 Copyright (C) 1998-2014 Free Software Foundation, Inc.
3 Contributed by Denis Chertykov (chertykov@gmail.com)
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "rtl.h"
26 #include "regs.h"
27 #include "hard-reg-set.h"
28 #include "insn-config.h"
29 #include "conditions.h"
30 #include "insn-attr.h"
31 #include "insn-codes.h"
32 #include "flags.h"
33 #include "reload.h"
34 #include "tree.h"
35 #include "varasm.h"
36 #include "print-tree.h"
37 #include "calls.h"
38 #include "stor-layout.h"
39 #include "stringpool.h"
40 #include "output.h"
41 #include "expr.h"
42 #include "c-family/c-common.h"
43 #include "diagnostic-core.h"
44 #include "obstack.h"
45 #include "hashtab.h"
46 #include "hash-set.h"
47 #include "vec.h"
48 #include "machmode.h"
49 #include "input.h"
50 #include "function.h"
51 #include "recog.h"
52 #include "optabs.h"
53 #include "ggc.h"
54 #include "langhooks.h"
55 #include "tm_p.h"
56 #include "target.h"
57 #include "target-def.h"
58 #include "params.h"
59 #include "dominance.h"
60 #include "cfg.h"
61 #include "cfgrtl.h"
62 #include "cfganal.h"
63 #include "lcm.h"
64 #include "cfgbuild.h"
65 #include "cfgcleanup.h"
66 #include "predict.h"
67 #include "basic-block.h"
68 #include "df.h"
69 #include "builtins.h"
70
71 /* Maximal allowed offset for an address in the LD command */
72 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
73
74 /* Return true if STR starts with PREFIX and false, otherwise. */
75 #define STR_PREFIX_P(STR,PREFIX) (0 == strncmp (STR, PREFIX, strlen (PREFIX)))
76
77 /* The 4 bits starting at SECTION_MACH_DEP are reserved to store the
78 address space where data is to be located.
79 As the only non-generic address spaces are all located in flash,
80 this can be used to test if data shall go into some .progmem* section.
81 This must be the rightmost field of machine dependent section flags. */
82 #define AVR_SECTION_PROGMEM (0xf * SECTION_MACH_DEP)
83
84 /* Similar 4-bit region for SYMBOL_REF_FLAGS. */
85 #define AVR_SYMBOL_FLAG_PROGMEM (0xf * SYMBOL_FLAG_MACH_DEP)
86
87 /* Similar 4-bit region in SYMBOL_REF_FLAGS:
88 Set address-space AS in SYMBOL_REF_FLAGS of SYM */
89 #define AVR_SYMBOL_SET_ADDR_SPACE(SYM,AS) \
90 do { \
91 SYMBOL_REF_FLAGS (sym) &= ~AVR_SYMBOL_FLAG_PROGMEM; \
92 SYMBOL_REF_FLAGS (sym) |= (AS) * SYMBOL_FLAG_MACH_DEP; \
93 } while (0)
94
95 /* Read address-space from SYMBOL_REF_FLAGS of SYM */
96 #define AVR_SYMBOL_GET_ADDR_SPACE(SYM) \
97 ((SYMBOL_REF_FLAGS (sym) & AVR_SYMBOL_FLAG_PROGMEM) \
98 / SYMBOL_FLAG_MACH_DEP)
99
100 #define TINY_ADIW(REG1, REG2, I) \
101 "subi " #REG1 ",lo8(-(" #I "))" CR_TAB \
102 "sbci " #REG2 ",hi8(-(" #I "))"
103
104 #define TINY_SBIW(REG1, REG2, I) \
105 "subi " #REG1 ",lo8((" #I "))" CR_TAB \
106 "sbci " #REG2 ",hi8((" #I "))"
107
108 #define AVR_TMP_REGNO (AVR_TINY ? TMP_REGNO_TINY : TMP_REGNO)
109 #define AVR_ZERO_REGNO (AVR_TINY ? ZERO_REGNO_TINY : ZERO_REGNO)
110
111 /* Known address spaces. The order must be the same as in the respective
112 enum from avr.h (or designated initialized must be used). */
113 const avr_addrspace_t avr_addrspace[ADDR_SPACE_COUNT] =
114 {
115 { ADDR_SPACE_RAM, 0, 2, "", 0, NULL },
116 { ADDR_SPACE_FLASH, 1, 2, "__flash", 0, ".progmem.data" },
117 { ADDR_SPACE_FLASH1, 1, 2, "__flash1", 1, ".progmem1.data" },
118 { ADDR_SPACE_FLASH2, 1, 2, "__flash2", 2, ".progmem2.data" },
119 { ADDR_SPACE_FLASH3, 1, 2, "__flash3", 3, ".progmem3.data" },
120 { ADDR_SPACE_FLASH4, 1, 2, "__flash4", 4, ".progmem4.data" },
121 { ADDR_SPACE_FLASH5, 1, 2, "__flash5", 5, ".progmem5.data" },
122 { ADDR_SPACE_MEMX, 1, 3, "__memx", 0, ".progmemx.data" },
123 };
124
125
126 /* Holding RAM addresses of some SFRs used by the compiler and that
127 are unique over all devices in an architecture like 'avr4'. */
128
129 typedef struct
130 {
131 /* SREG: The processor status */
132 int sreg;
133
134 /* RAMPX, RAMPY, RAMPD and CCP of XMEGA */
135 int ccp;
136 int rampd;
137 int rampx;
138 int rampy;
139
140 /* RAMPZ: The high byte of 24-bit address used with ELPM */
141 int rampz;
142
143 /* SP: The stack pointer and its low and high byte */
144 int sp_l;
145 int sp_h;
146 } avr_addr_t;
147
148 static avr_addr_t avr_addr;
149
150
151 /* Prototypes for local helper functions. */
152
153 static const char* out_movqi_r_mr (rtx_insn *, rtx[], int*);
154 static const char* out_movhi_r_mr (rtx_insn *, rtx[], int*);
155 static const char* out_movsi_r_mr (rtx_insn *, rtx[], int*);
156 static const char* out_movqi_mr_r (rtx_insn *, rtx[], int*);
157 static const char* out_movhi_mr_r (rtx_insn *, rtx[], int*);
158 static const char* out_movsi_mr_r (rtx_insn *, rtx[], int*);
159
160 static int get_sequence_length (rtx_insn *insns);
161 static int sequent_regs_live (void);
162 static const char *ptrreg_to_str (int);
163 static const char *cond_string (enum rtx_code);
164 static int avr_num_arg_regs (machine_mode, const_tree);
165 static int avr_operand_rtx_cost (rtx, machine_mode, enum rtx_code,
166 int, bool);
167 static void output_reload_in_const (rtx*, rtx, int*, bool);
168 static struct machine_function * avr_init_machine_status (void);
169
170
171 /* Prototypes for hook implementors if needed before their implementation. */
172
173 static bool avr_rtx_costs (rtx, int, int, int, int*, bool);
174
175
176 /* Allocate registers from r25 to r8 for parameters for function calls. */
177 #define FIRST_CUM_REG 26
178
179 /* Last call saved register */
180 #define LAST_CALLEE_SAVED_REG (AVR_TINY ? 19 : 17)
181
182 /* Implicit target register of LPM instruction (R0) */
183 extern GTY(()) rtx lpm_reg_rtx;
184 rtx lpm_reg_rtx;
185
186 /* (Implicit) address register of LPM instruction (R31:R30 = Z) */
187 extern GTY(()) rtx lpm_addr_reg_rtx;
188 rtx lpm_addr_reg_rtx;
189
190 /* Temporary register RTX (reg:QI TMP_REGNO) */
191 extern GTY(()) rtx tmp_reg_rtx;
192 rtx tmp_reg_rtx;
193
194 /* Zeroed register RTX (reg:QI ZERO_REGNO) */
195 extern GTY(()) rtx zero_reg_rtx;
196 rtx zero_reg_rtx;
197
198 /* RTXs for all general purpose registers as QImode */
199 extern GTY(()) rtx all_regs_rtx[32];
200 rtx all_regs_rtx[32];
201
202 /* SREG, the processor status */
203 extern GTY(()) rtx sreg_rtx;
204 rtx sreg_rtx;
205
206 /* RAMP* special function registers */
207 extern GTY(()) rtx rampd_rtx;
208 extern GTY(()) rtx rampx_rtx;
209 extern GTY(()) rtx rampy_rtx;
210 extern GTY(()) rtx rampz_rtx;
211 rtx rampd_rtx;
212 rtx rampx_rtx;
213 rtx rampy_rtx;
214 rtx rampz_rtx;
215
216 /* RTX containing the strings "" and "e", respectively */
217 static GTY(()) rtx xstring_empty;
218 static GTY(()) rtx xstring_e;
219
220 /* Current architecture. */
221 const avr_arch_t *avr_current_arch;
222
223 /* Current device. */
224 const avr_mcu_t *avr_current_device;
225
226 /* Section to put switch tables in. */
227 static GTY(()) section *progmem_swtable_section;
228
229 /* Unnamed sections associated to __attribute__((progmem)) aka. PROGMEM
230 or to address space __flash* or __memx. Only used as singletons inside
231 avr_asm_select_section, but it must not be local there because of GTY. */
232 static GTY(()) section *progmem_section[ADDR_SPACE_COUNT];
233
234 /* Condition for insns/expanders from avr-dimode.md. */
235 bool avr_have_dimode = true;
236
237 /* To track if code will use .bss and/or .data. */
238 bool avr_need_clear_bss_p = false;
239 bool avr_need_copy_data_p = false;
240
241 \f
242 /* Transform UP into lowercase and write the result to LO.
243 You must provide enough space for LO. Return LO. */
244
245 static char*
246 avr_tolower (char *lo, const char *up)
247 {
248 char *lo0 = lo;
249
250 for (; *up; up++, lo++)
251 *lo = TOLOWER (*up);
252
253 *lo = '\0';
254
255 return lo0;
256 }
257
258
259 /* Custom function to count number of set bits. */
260
261 static inline int
262 avr_popcount (unsigned int val)
263 {
264 int pop = 0;
265
266 while (val)
267 {
268 val &= val-1;
269 pop++;
270 }
271
272 return pop;
273 }
274
275
276 /* Constraint helper function. XVAL is a CONST_INT or a CONST_DOUBLE.
277 Return true if the least significant N_BYTES bytes of XVAL all have a
278 popcount in POP_MASK and false, otherwise. POP_MASK represents a subset
279 of integers which contains an integer N iff bit N of POP_MASK is set. */
280
281 bool
282 avr_popcount_each_byte (rtx xval, int n_bytes, int pop_mask)
283 {
284 int i;
285
286 machine_mode mode = GET_MODE (xval);
287
288 if (VOIDmode == mode)
289 mode = SImode;
290
291 for (i = 0; i < n_bytes; i++)
292 {
293 rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
294 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
295
296 if (0 == (pop_mask & (1 << avr_popcount (val8))))
297 return false;
298 }
299
300 return true;
301 }
302
303
304 /* Access some RTX as INT_MODE. If X is a CONST_FIXED we can get
305 the bit representation of X by "casting" it to CONST_INT. */
306
307 rtx
308 avr_to_int_mode (rtx x)
309 {
310 machine_mode mode = GET_MODE (x);
311
312 return VOIDmode == mode
313 ? x
314 : simplify_gen_subreg (int_mode_for_mode (mode), x, mode, 0);
315 }
316
317
318 /* Implement `TARGET_OPTION_OVERRIDE'. */
319
320 static void
321 avr_option_override (void)
322 {
323 /* Disable -fdelete-null-pointer-checks option for AVR target.
324 This option compiler assumes that dereferencing of a null pointer
325 would halt the program. For AVR this assumption is not true and
326 programs can safely dereference null pointers. Changes made by this
327 option may not work properly for AVR. So disable this option. */
328
329 flag_delete_null_pointer_checks = 0;
330
331 /* caller-save.c looks for call-clobbered hard registers that are assigned
332 to pseudos that cross calls and tries so save-restore them around calls
333 in order to reduce the number of stack slots needed.
334
335 This might lead to situations where reload is no more able to cope
336 with the challenge of AVR's very few address registers and fails to
337 perform the requested spills. */
338
339 if (avr_strict_X)
340 flag_caller_saves = 0;
341
342 /* Unwind tables currently require a frame pointer for correctness,
343 see toplev.c:process_options(). */
344
345 if ((flag_unwind_tables
346 || flag_non_call_exceptions
347 || flag_asynchronous_unwind_tables)
348 && !ACCUMULATE_OUTGOING_ARGS)
349 {
350 flag_omit_frame_pointer = 0;
351 }
352
353 if (flag_pic == 1)
354 warning (OPT_fpic, "-fpic is not supported");
355 if (flag_pic == 2)
356 warning (OPT_fPIC, "-fPIC is not supported");
357 if (flag_pie == 1)
358 warning (OPT_fpie, "-fpie is not supported");
359 if (flag_pie == 2)
360 warning (OPT_fPIE, "-fPIE is not supported");
361
362 /* Search for mcu arch.
363 ??? We should probably just put the architecture-default device
364 settings in the architecture struct and remove any notion of a current
365 device from gcc. */
366
367 for (avr_current_device = avr_mcu_types; ; avr_current_device++)
368 {
369 if (!avr_current_device->name)
370 fatal_error ("mcu not found");
371 if (!avr_current_device->macro
372 && avr_current_device->arch == avr_arch_index)
373 break;
374 }
375
376 avr_current_arch = &avr_arch_types[avr_arch_index];
377 if (avr_n_flash < 0)
378 avr_n_flash = avr_current_device->n_flash;
379
380 /* RAM addresses of some SFRs common to all devices in respective arch. */
381
382 /* SREG: Status Register containing flags like I (global IRQ) */
383 avr_addr.sreg = 0x3F + avr_current_arch->sfr_offset;
384
385 /* RAMPZ: Address' high part when loading via ELPM */
386 avr_addr.rampz = 0x3B + avr_current_arch->sfr_offset;
387
388 avr_addr.rampy = 0x3A + avr_current_arch->sfr_offset;
389 avr_addr.rampx = 0x39 + avr_current_arch->sfr_offset;
390 avr_addr.rampd = 0x38 + avr_current_arch->sfr_offset;
391 avr_addr.ccp = (AVR_TINY ? 0x3C : 0x34) + avr_current_arch->sfr_offset;
392
393 /* SP: Stack Pointer (SP_H:SP_L) */
394 avr_addr.sp_l = 0x3D + avr_current_arch->sfr_offset;
395 avr_addr.sp_h = avr_addr.sp_l + 1;
396
397 init_machine_status = avr_init_machine_status;
398
399 avr_log_set_avr_log();
400 }
401
402 /* Function to set up the backend function structure. */
403
404 static struct machine_function *
405 avr_init_machine_status (void)
406 {
407 return ggc_cleared_alloc<machine_function> ();
408 }
409
410
411 /* Implement `INIT_EXPANDERS'. */
412 /* The function works like a singleton. */
413
414 void
415 avr_init_expanders (void)
416 {
417 int regno;
418
419 for (regno = 0; regno < 32; regno ++)
420 all_regs_rtx[regno] = gen_rtx_REG (QImode, regno);
421
422 lpm_reg_rtx = all_regs_rtx[LPM_REGNO];
423 tmp_reg_rtx = all_regs_rtx[AVR_TMP_REGNO];
424 zero_reg_rtx = all_regs_rtx[AVR_ZERO_REGNO];
425
426 lpm_addr_reg_rtx = gen_rtx_REG (HImode, REG_Z);
427
428 sreg_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.sreg));
429 rampd_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampd));
430 rampx_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampx));
431 rampy_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampy));
432 rampz_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampz));
433
434 xstring_empty = gen_rtx_CONST_STRING (VOIDmode, "");
435 xstring_e = gen_rtx_CONST_STRING (VOIDmode, "e");
436
437 /* TINY core does not have regs r10-r16, but avr-dimode.md expects them
438 to be present */
439 if (AVR_TINY)
440 avr_have_dimode = false;
441 }
442
443
444 /* Implement `REGNO_REG_CLASS'. */
445 /* Return register class for register R. */
446
447 enum reg_class
448 avr_regno_reg_class (int r)
449 {
450 static const enum reg_class reg_class_tab[] =
451 {
452 R0_REG,
453 /* r1 - r15 */
454 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
455 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
456 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
457 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
458 /* r16 - r23 */
459 SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
460 SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
461 /* r24, r25 */
462 ADDW_REGS, ADDW_REGS,
463 /* X: r26, 27 */
464 POINTER_X_REGS, POINTER_X_REGS,
465 /* Y: r28, r29 */
466 POINTER_Y_REGS, POINTER_Y_REGS,
467 /* Z: r30, r31 */
468 POINTER_Z_REGS, POINTER_Z_REGS,
469 /* SP: SPL, SPH */
470 STACK_REG, STACK_REG
471 };
472
473 if (r <= 33)
474 return reg_class_tab[r];
475
476 return ALL_REGS;
477 }
478
479
480 /* Implement `TARGET_SCALAR_MODE_SUPPORTED_P'. */
481
482 static bool
483 avr_scalar_mode_supported_p (machine_mode mode)
484 {
485 if (ALL_FIXED_POINT_MODE_P (mode))
486 return true;
487
488 if (PSImode == mode)
489 return true;
490
491 return default_scalar_mode_supported_p (mode);
492 }
493
494
495 /* Return TRUE if DECL is a VAR_DECL located in flash and FALSE, otherwise. */
496
497 static bool
498 avr_decl_flash_p (tree decl)
499 {
500 if (TREE_CODE (decl) != VAR_DECL
501 || TREE_TYPE (decl) == error_mark_node)
502 {
503 return false;
504 }
505
506 return !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (decl)));
507 }
508
509
510 /* Return TRUE if DECL is a VAR_DECL located in the 24-bit flash
511 address space and FALSE, otherwise. */
512
513 static bool
514 avr_decl_memx_p (tree decl)
515 {
516 if (TREE_CODE (decl) != VAR_DECL
517 || TREE_TYPE (decl) == error_mark_node)
518 {
519 return false;
520 }
521
522 return (ADDR_SPACE_MEMX == TYPE_ADDR_SPACE (TREE_TYPE (decl)));
523 }
524
525
526 /* Return TRUE if X is a MEM rtx located in flash and FALSE, otherwise. */
527
528 bool
529 avr_mem_flash_p (rtx x)
530 {
531 return (MEM_P (x)
532 && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x)));
533 }
534
535
536 /* Return TRUE if X is a MEM rtx located in the 24-bit flash
537 address space and FALSE, otherwise. */
538
539 bool
540 avr_mem_memx_p (rtx x)
541 {
542 return (MEM_P (x)
543 && ADDR_SPACE_MEMX == MEM_ADDR_SPACE (x));
544 }
545
546
547 /* A helper for the subsequent function attribute used to dig for
548 attribute 'name' in a FUNCTION_DECL or FUNCTION_TYPE */
549
550 static inline int
551 avr_lookup_function_attribute1 (const_tree func, const char *name)
552 {
553 if (FUNCTION_DECL == TREE_CODE (func))
554 {
555 if (NULL_TREE != lookup_attribute (name, DECL_ATTRIBUTES (func)))
556 {
557 return true;
558 }
559
560 func = TREE_TYPE (func);
561 }
562
563 gcc_assert (TREE_CODE (func) == FUNCTION_TYPE
564 || TREE_CODE (func) == METHOD_TYPE);
565
566 return NULL_TREE != lookup_attribute (name, TYPE_ATTRIBUTES (func));
567 }
568
569 /* Return nonzero if FUNC is a naked function. */
570
571 static int
572 avr_naked_function_p (tree func)
573 {
574 return avr_lookup_function_attribute1 (func, "naked");
575 }
576
577 /* Return nonzero if FUNC is an interrupt function as specified
578 by the "interrupt" attribute. */
579
580 static int
581 avr_interrupt_function_p (tree func)
582 {
583 return avr_lookup_function_attribute1 (func, "interrupt");
584 }
585
586 /* Return nonzero if FUNC is a signal function as specified
587 by the "signal" attribute. */
588
589 static int
590 avr_signal_function_p (tree func)
591 {
592 return avr_lookup_function_attribute1 (func, "signal");
593 }
594
595 /* Return nonzero if FUNC is an OS_task function. */
596
597 static int
598 avr_OS_task_function_p (tree func)
599 {
600 return avr_lookup_function_attribute1 (func, "OS_task");
601 }
602
603 /* Return nonzero if FUNC is an OS_main function. */
604
605 static int
606 avr_OS_main_function_p (tree func)
607 {
608 return avr_lookup_function_attribute1 (func, "OS_main");
609 }
610
611
612 /* Implement `TARGET_SET_CURRENT_FUNCTION'. */
613 /* Sanity cheching for above function attributes. */
614
615 static void
616 avr_set_current_function (tree decl)
617 {
618 location_t loc;
619 const char *isr;
620
621 if (decl == NULL_TREE
622 || current_function_decl == NULL_TREE
623 || current_function_decl == error_mark_node
624 || ! cfun->machine
625 || cfun->machine->attributes_checked_p)
626 return;
627
628 loc = DECL_SOURCE_LOCATION (decl);
629
630 cfun->machine->is_naked = avr_naked_function_p (decl);
631 cfun->machine->is_signal = avr_signal_function_p (decl);
632 cfun->machine->is_interrupt = avr_interrupt_function_p (decl);
633 cfun->machine->is_OS_task = avr_OS_task_function_p (decl);
634 cfun->machine->is_OS_main = avr_OS_main_function_p (decl);
635
636 isr = cfun->machine->is_interrupt ? "interrupt" : "signal";
637
638 /* Too much attributes make no sense as they request conflicting features. */
639
640 if (cfun->machine->is_OS_task + cfun->machine->is_OS_main
641 + (cfun->machine->is_signal || cfun->machine->is_interrupt) > 1)
642 error_at (loc, "function attributes %qs, %qs and %qs are mutually"
643 " exclusive", "OS_task", "OS_main", isr);
644
645 /* 'naked' will hide effects of 'OS_task' and 'OS_main'. */
646
647 if (cfun->machine->is_naked
648 && (cfun->machine->is_OS_task || cfun->machine->is_OS_main))
649 warning_at (loc, OPT_Wattributes, "function attributes %qs and %qs have"
650 " no effect on %qs function", "OS_task", "OS_main", "naked");
651
652 if (cfun->machine->is_interrupt || cfun->machine->is_signal)
653 {
654 tree args = TYPE_ARG_TYPES (TREE_TYPE (decl));
655 tree ret = TREE_TYPE (TREE_TYPE (decl));
656 const char *name;
657
658 name = DECL_ASSEMBLER_NAME_SET_P (decl)
659 ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))
660 : IDENTIFIER_POINTER (DECL_NAME (decl));
661
662 /* Skip a leading '*' that might still prefix the assembler name,
663 e.g. in non-LTO runs. */
664
665 name = default_strip_name_encoding (name);
666
667 /* Silently ignore 'signal' if 'interrupt' is present. AVR-LibC startet
668 using this when it switched from SIGNAL and INTERRUPT to ISR. */
669
670 if (cfun->machine->is_interrupt)
671 cfun->machine->is_signal = 0;
672
673 /* Interrupt handlers must be void __vector (void) functions. */
674
675 if (args && TREE_CODE (TREE_VALUE (args)) != VOID_TYPE)
676 error_at (loc, "%qs function cannot have arguments", isr);
677
678 if (TREE_CODE (ret) != VOID_TYPE)
679 error_at (loc, "%qs function cannot return a value", isr);
680
681 /* If the function has the 'signal' or 'interrupt' attribute, ensure
682 that the name of the function is "__vector_NN" so as to catch
683 when the user misspells the vector name. */
684
685 if (!STR_PREFIX_P (name, "__vector"))
686 warning_at (loc, 0, "%qs appears to be a misspelled %s handler",
687 name, isr);
688 }
689
690 /* Don't print the above diagnostics more than once. */
691
692 cfun->machine->attributes_checked_p = 1;
693 }
694
695
696 /* Implement `ACCUMULATE_OUTGOING_ARGS'. */
697
698 int
699 avr_accumulate_outgoing_args (void)
700 {
701 if (!cfun)
702 return TARGET_ACCUMULATE_OUTGOING_ARGS;
703
704 /* FIXME: For setjmp and in avr_builtin_setjmp_frame_value we don't know
705 what offset is correct. In some cases it is relative to
706 virtual_outgoing_args_rtx and in others it is relative to
707 virtual_stack_vars_rtx. For example code see
708 gcc.c-torture/execute/built-in-setjmp.c
709 gcc.c-torture/execute/builtins/sprintf-chk.c */
710
711 return (TARGET_ACCUMULATE_OUTGOING_ARGS
712 && !(cfun->calls_setjmp
713 || cfun->has_nonlocal_label));
714 }
715
716
717 /* Report contribution of accumulated outgoing arguments to stack size. */
718
719 static inline int
720 avr_outgoing_args_size (void)
721 {
722 return ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0;
723 }
724
725
726 /* Implement `STARTING_FRAME_OFFSET'. */
727 /* This is the offset from the frame pointer register to the first stack slot
728 that contains a variable living in the frame. */
729
730 int
731 avr_starting_frame_offset (void)
732 {
733 return 1 + avr_outgoing_args_size ();
734 }
735
736
737 /* Return the number of hard registers to push/pop in the prologue/epilogue
738 of the current function, and optionally store these registers in SET. */
739
740 static int
741 avr_regs_to_save (HARD_REG_SET *set)
742 {
743 int reg, count;
744 int int_or_sig_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
745
746 if (set)
747 CLEAR_HARD_REG_SET (*set);
748 count = 0;
749
750 /* No need to save any registers if the function never returns or
751 has the "OS_task" or "OS_main" attribute. */
752
753 if (TREE_THIS_VOLATILE (current_function_decl)
754 || cfun->machine->is_OS_task
755 || cfun->machine->is_OS_main)
756 return 0;
757
758 for (reg = 0; reg < 32; reg++)
759 {
760 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
761 any global register variables. */
762
763 if (fixed_regs[reg])
764 continue;
765
766 if ((int_or_sig_p && !crtl->is_leaf && call_used_regs[reg])
767 || (df_regs_ever_live_p (reg)
768 && (int_or_sig_p || !call_used_regs[reg])
769 /* Don't record frame pointer registers here. They are treated
770 indivitually in prologue. */
771 && !(frame_pointer_needed
772 && (reg == REG_Y || reg == (REG_Y+1)))))
773 {
774 if (set)
775 SET_HARD_REG_BIT (*set, reg);
776 count++;
777 }
778 }
779 return count;
780 }
781
782
783 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
784
785 static bool
786 avr_allocate_stack_slots_for_args (void)
787 {
788 return !cfun->machine->is_naked;
789 }
790
791
792 /* Return true if register FROM can be eliminated via register TO. */
793
794 static bool
795 avr_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
796 {
797 return ((frame_pointer_needed && to == FRAME_POINTER_REGNUM)
798 || !frame_pointer_needed);
799 }
800
801
802 /* Implement `TARGET_WARN_FUNC_RETURN'. */
803
804 static bool
805 avr_warn_func_return (tree decl)
806 {
807 /* Naked functions are implemented entirely in assembly, including the
808 return sequence, so suppress warnings about this. */
809
810 return !avr_naked_function_p (decl);
811 }
812
813 /* Compute offset between arg_pointer and frame_pointer. */
814
815 int
816 avr_initial_elimination_offset (int from, int to)
817 {
818 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
819 return 0;
820 else
821 {
822 int offset = frame_pointer_needed ? 2 : 0;
823 int avr_pc_size = AVR_HAVE_EIJMP_EICALL ? 3 : 2;
824
825 offset += avr_regs_to_save (NULL);
826 return (get_frame_size () + avr_outgoing_args_size()
827 + avr_pc_size + 1 + offset);
828 }
829 }
830
831
832 /* Helper for the function below. */
833
834 static void
835 avr_adjust_type_node (tree *node, machine_mode mode, int sat_p)
836 {
837 *node = make_node (FIXED_POINT_TYPE);
838 TYPE_SATURATING (*node) = sat_p;
839 TYPE_UNSIGNED (*node) = UNSIGNED_FIXED_POINT_MODE_P (mode);
840 TYPE_IBIT (*node) = GET_MODE_IBIT (mode);
841 TYPE_FBIT (*node) = GET_MODE_FBIT (mode);
842 TYPE_PRECISION (*node) = GET_MODE_BITSIZE (mode);
843 TYPE_ALIGN (*node) = 8;
844 SET_TYPE_MODE (*node, mode);
845
846 layout_type (*node);
847 }
848
849
850 /* Implement `TARGET_BUILD_BUILTIN_VA_LIST'. */
851
852 static tree
853 avr_build_builtin_va_list (void)
854 {
855 /* avr-modes.def adjusts [U]TA to be 64-bit modes with 48 fractional bits.
856 This is more appropriate for the 8-bit machine AVR than 128-bit modes.
857 The ADJUST_IBIT/FBIT are handled in toplev:init_adjust_machine_modes()
858 which is auto-generated by genmodes, but the compiler assigns [U]DAmode
859 to the long long accum modes instead of the desired [U]TAmode.
860
861 Fix this now, right after node setup in tree.c:build_common_tree_nodes().
862 This must run before c-cppbuiltin.c:builtin_define_fixed_point_constants()
863 which built-in defines macros like __ULLACCUM_FBIT__ that are used by
864 libgcc to detect IBIT and FBIT. */
865
866 avr_adjust_type_node (&ta_type_node, TAmode, 0);
867 avr_adjust_type_node (&uta_type_node, UTAmode, 0);
868 avr_adjust_type_node (&sat_ta_type_node, TAmode, 1);
869 avr_adjust_type_node (&sat_uta_type_node, UTAmode, 1);
870
871 unsigned_long_long_accum_type_node = uta_type_node;
872 long_long_accum_type_node = ta_type_node;
873 sat_unsigned_long_long_accum_type_node = sat_uta_type_node;
874 sat_long_long_accum_type_node = sat_ta_type_node;
875
876 /* Dispatch to the default handler. */
877
878 return std_build_builtin_va_list ();
879 }
880
881
882 /* Implement `TARGET_BUILTIN_SETJMP_FRAME_VALUE'. */
883 /* Actual start of frame is virtual_stack_vars_rtx this is offset from
884 frame pointer by +STARTING_FRAME_OFFSET.
885 Using saved frame = virtual_stack_vars_rtx - STARTING_FRAME_OFFSET
886 avoids creating add/sub of offset in nonlocal goto and setjmp. */
887
888 static rtx
889 avr_builtin_setjmp_frame_value (void)
890 {
891 rtx xval = gen_reg_rtx (Pmode);
892 emit_insn (gen_subhi3 (xval, virtual_stack_vars_rtx,
893 gen_int_mode (STARTING_FRAME_OFFSET, Pmode)));
894 return xval;
895 }
896
897
898 /* Return contents of MEM at frame pointer + stack size + 1 (+2 if 3-byte PC).
899 This is return address of function. */
900
901 rtx
902 avr_return_addr_rtx (int count, rtx tem)
903 {
904 rtx r;
905
906 /* Can only return this function's return address. Others not supported. */
907 if (count)
908 return NULL;
909
910 if (AVR_3_BYTE_PC)
911 {
912 r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+2");
913 warning (0, "%<builtin_return_address%> contains only 2 bytes"
914 " of address");
915 }
916 else
917 r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+1");
918
919 r = gen_rtx_PLUS (Pmode, tem, r);
920 r = gen_frame_mem (Pmode, memory_address (Pmode, r));
921 r = gen_rtx_ROTATE (HImode, r, GEN_INT (8));
922 return r;
923 }
924
925 /* Return 1 if the function epilogue is just a single "ret". */
926
927 int
928 avr_simple_epilogue (void)
929 {
930 return (! frame_pointer_needed
931 && get_frame_size () == 0
932 && avr_outgoing_args_size() == 0
933 && avr_regs_to_save (NULL) == 0
934 && ! cfun->machine->is_interrupt
935 && ! cfun->machine->is_signal
936 && ! cfun->machine->is_naked
937 && ! TREE_THIS_VOLATILE (current_function_decl));
938 }
939
940 /* This function checks sequence of live registers. */
941
942 static int
943 sequent_regs_live (void)
944 {
945 int reg;
946 int live_seq = 0;
947 int cur_seq = 0;
948
949 for (reg = 0; reg <= LAST_CALLEE_SAVED_REG; ++reg)
950 {
951 if (fixed_regs[reg])
952 {
953 /* Don't recognize sequences that contain global register
954 variables. */
955
956 if (live_seq != 0)
957 return 0;
958 else
959 continue;
960 }
961
962 if (!call_used_regs[reg])
963 {
964 if (df_regs_ever_live_p (reg))
965 {
966 ++live_seq;
967 ++cur_seq;
968 }
969 else
970 cur_seq = 0;
971 }
972 }
973
974 if (!frame_pointer_needed)
975 {
976 if (df_regs_ever_live_p (REG_Y))
977 {
978 ++live_seq;
979 ++cur_seq;
980 }
981 else
982 cur_seq = 0;
983
984 if (df_regs_ever_live_p (REG_Y+1))
985 {
986 ++live_seq;
987 ++cur_seq;
988 }
989 else
990 cur_seq = 0;
991 }
992 else
993 {
994 cur_seq += 2;
995 live_seq += 2;
996 }
997 return (cur_seq == live_seq) ? live_seq : 0;
998 }
999
1000 /* Obtain the length sequence of insns. */
1001
1002 int
1003 get_sequence_length (rtx_insn *insns)
1004 {
1005 rtx_insn *insn;
1006 int length;
1007
1008 for (insn = insns, length = 0; insn; insn = NEXT_INSN (insn))
1009 length += get_attr_length (insn);
1010
1011 return length;
1012 }
1013
1014
1015 /* Implement `INCOMING_RETURN_ADDR_RTX'. */
1016
1017 rtx
1018 avr_incoming_return_addr_rtx (void)
1019 {
1020 /* The return address is at the top of the stack. Note that the push
1021 was via post-decrement, which means the actual address is off by one. */
1022 return gen_frame_mem (HImode, plus_constant (Pmode, stack_pointer_rtx, 1));
1023 }
1024
1025 /* Helper for expand_prologue. Emit a push of a byte register. */
1026
1027 static void
1028 emit_push_byte (unsigned regno, bool frame_related_p)
1029 {
1030 rtx mem, reg;
1031 rtx_insn *insn;
1032
1033 mem = gen_rtx_POST_DEC (HImode, stack_pointer_rtx);
1034 mem = gen_frame_mem (QImode, mem);
1035 reg = gen_rtx_REG (QImode, regno);
1036
1037 insn = emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
1038 if (frame_related_p)
1039 RTX_FRAME_RELATED_P (insn) = 1;
1040
1041 cfun->machine->stack_usage++;
1042 }
1043
1044
1045 /* Helper for expand_prologue. Emit a push of a SFR via tmp_reg.
1046 SFR is a MEM representing the memory location of the SFR.
1047 If CLR_P then clear the SFR after the push using zero_reg. */
1048
1049 static void
1050 emit_push_sfr (rtx sfr, bool frame_related_p, bool clr_p)
1051 {
1052 rtx_insn *insn;
1053
1054 gcc_assert (MEM_P (sfr));
1055
1056 /* IN __tmp_reg__, IO(SFR) */
1057 insn = emit_move_insn (tmp_reg_rtx, sfr);
1058 if (frame_related_p)
1059 RTX_FRAME_RELATED_P (insn) = 1;
1060
1061 /* PUSH __tmp_reg__ */
1062 emit_push_byte (AVR_TMP_REGNO, frame_related_p);
1063
1064 if (clr_p)
1065 {
1066 /* OUT IO(SFR), __zero_reg__ */
1067 insn = emit_move_insn (sfr, const0_rtx);
1068 if (frame_related_p)
1069 RTX_FRAME_RELATED_P (insn) = 1;
1070 }
1071 }
1072
1073 static void
1074 avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set)
1075 {
1076 rtx_insn *insn;
1077 bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
1078 int live_seq = sequent_regs_live ();
1079
1080 HOST_WIDE_INT size_max
1081 = (HOST_WIDE_INT) GET_MODE_MASK (AVR_HAVE_8BIT_SP ? QImode : Pmode);
1082
1083 bool minimize = (TARGET_CALL_PROLOGUES
1084 && size < size_max
1085 && live_seq
1086 && !isr_p
1087 && !cfun->machine->is_OS_task
1088 && !cfun->machine->is_OS_main
1089 && !AVR_TINY);
1090
1091 if (minimize
1092 && (frame_pointer_needed
1093 || avr_outgoing_args_size() > 8
1094 || (AVR_2_BYTE_PC && live_seq > 6)
1095 || live_seq > 7))
1096 {
1097 rtx pattern;
1098 int first_reg, reg, offset;
1099
1100 emit_move_insn (gen_rtx_REG (HImode, REG_X),
1101 gen_int_mode (size, HImode));
1102
1103 pattern = gen_call_prologue_saves (gen_int_mode (live_seq, HImode),
1104 gen_int_mode (live_seq+size, HImode));
1105 insn = emit_insn (pattern);
1106 RTX_FRAME_RELATED_P (insn) = 1;
1107
1108 /* Describe the effect of the unspec_volatile call to prologue_saves.
1109 Note that this formulation assumes that add_reg_note pushes the
1110 notes to the front. Thus we build them in the reverse order of
1111 how we want dwarf2out to process them. */
1112
1113 /* The function does always set frame_pointer_rtx, but whether that
1114 is going to be permanent in the function is frame_pointer_needed. */
1115
1116 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1117 gen_rtx_SET (VOIDmode, (frame_pointer_needed
1118 ? frame_pointer_rtx
1119 : stack_pointer_rtx),
1120 plus_constant (Pmode, stack_pointer_rtx,
1121 -(size + live_seq))));
1122
1123 /* Note that live_seq always contains r28+r29, but the other
1124 registers to be saved are all below 18. */
1125
1126 first_reg = (LAST_CALLEE_SAVED_REG + 1) - (live_seq - 2);
1127
1128 for (reg = 29, offset = -live_seq + 1;
1129 reg >= first_reg;
1130 reg = (reg == 28 ? LAST_CALLEE_SAVED_REG : reg - 1), ++offset)
1131 {
1132 rtx m, r;
1133
1134 m = gen_rtx_MEM (QImode, plus_constant (Pmode, stack_pointer_rtx,
1135 offset));
1136 r = gen_rtx_REG (QImode, reg);
1137 add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (VOIDmode, m, r));
1138 }
1139
1140 cfun->machine->stack_usage += size + live_seq;
1141 }
1142 else /* !minimize */
1143 {
1144 int reg;
1145
1146 for (reg = 0; reg < 32; ++reg)
1147 if (TEST_HARD_REG_BIT (set, reg))
1148 emit_push_byte (reg, true);
1149
1150 if (frame_pointer_needed
1151 && (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main)))
1152 {
1153 /* Push frame pointer. Always be consistent about the
1154 ordering of pushes -- epilogue_restores expects the
1155 register pair to be pushed low byte first. */
1156
1157 emit_push_byte (REG_Y, true);
1158 emit_push_byte (REG_Y + 1, true);
1159 }
1160
1161 if (frame_pointer_needed
1162 && size == 0)
1163 {
1164 insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1165 RTX_FRAME_RELATED_P (insn) = 1;
1166 }
1167
1168 if (size != 0)
1169 {
1170 /* Creating a frame can be done by direct manipulation of the
1171 stack or via the frame pointer. These two methods are:
1172 fp = sp
1173 fp -= size
1174 sp = fp
1175 or
1176 sp -= size
1177 fp = sp (*)
1178 the optimum method depends on function type, stack and
1179 frame size. To avoid a complex logic, both methods are
1180 tested and shortest is selected.
1181
1182 There is also the case where SIZE != 0 and no frame pointer is
1183 needed; this can occur if ACCUMULATE_OUTGOING_ARGS is on.
1184 In that case, insn (*) is not needed in that case.
1185 We use the X register as scratch. This is save because in X
1186 is call-clobbered.
1187 In an interrupt routine, the case of SIZE != 0 together with
1188 !frame_pointer_needed can only occur if the function is not a
1189 leaf function and thus X has already been saved. */
1190
1191 int irq_state = -1;
1192 HOST_WIDE_INT size_cfa = size, neg_size;
1193 rtx_insn *fp_plus_insns;
1194 rtx fp, my_fp;
1195
1196 gcc_assert (frame_pointer_needed
1197 || !isr_p
1198 || !crtl->is_leaf);
1199
1200 fp = my_fp = (frame_pointer_needed
1201 ? frame_pointer_rtx
1202 : gen_rtx_REG (Pmode, REG_X));
1203
1204 if (AVR_HAVE_8BIT_SP)
1205 {
1206 /* The high byte (r29) does not change:
1207 Prefer SUBI (1 cycle) over SBIW (2 cycles, same size). */
1208
1209 my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
1210 }
1211
1212 /* Cut down size and avoid size = 0 so that we don't run
1213 into ICE like PR52488 in the remainder. */
1214
1215 if (size > size_max)
1216 {
1217 /* Don't error so that insane code from newlib still compiles
1218 and does not break building newlib. As PR51345 is implemented
1219 now, there are multilib variants with -msp8.
1220
1221 If user wants sanity checks he can use -Wstack-usage=
1222 or similar options.
1223
1224 For CFA we emit the original, non-saturated size so that
1225 the generic machinery is aware of the real stack usage and
1226 will print the above diagnostic as expected. */
1227
1228 size = size_max;
1229 }
1230
1231 size = trunc_int_for_mode (size, GET_MODE (my_fp));
1232 neg_size = trunc_int_for_mode (-size, GET_MODE (my_fp));
1233
1234 /************ Method 1: Adjust frame pointer ************/
1235
1236 start_sequence ();
1237
1238 /* Normally, the dwarf2out frame-related-expr interpreter does
1239 not expect to have the CFA change once the frame pointer is
1240 set up. Thus, we avoid marking the move insn below and
1241 instead indicate that the entire operation is complete after
1242 the frame pointer subtraction is done. */
1243
1244 insn = emit_move_insn (fp, stack_pointer_rtx);
1245 if (frame_pointer_needed)
1246 {
1247 RTX_FRAME_RELATED_P (insn) = 1;
1248 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1249 gen_rtx_SET (VOIDmode, fp, stack_pointer_rtx));
1250 }
1251
1252 insn = emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp),
1253 my_fp, neg_size));
1254
1255 if (frame_pointer_needed)
1256 {
1257 RTX_FRAME_RELATED_P (insn) = 1;
1258 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1259 gen_rtx_SET (VOIDmode, fp,
1260 plus_constant (Pmode, fp,
1261 -size_cfa)));
1262 }
1263
1264 /* Copy to stack pointer. Note that since we've already
1265 changed the CFA to the frame pointer this operation
1266 need not be annotated if frame pointer is needed.
1267 Always move through unspec, see PR50063.
1268 For meaning of irq_state see movhi_sp_r insn. */
1269
1270 if (cfun->machine->is_interrupt)
1271 irq_state = 1;
1272
1273 if (TARGET_NO_INTERRUPTS
1274 || cfun->machine->is_signal
1275 || cfun->machine->is_OS_main)
1276 irq_state = 0;
1277
1278 if (AVR_HAVE_8BIT_SP)
1279 irq_state = 2;
1280
1281 insn = emit_insn (gen_movhi_sp_r (stack_pointer_rtx,
1282 fp, GEN_INT (irq_state)));
1283 if (!frame_pointer_needed)
1284 {
1285 RTX_FRAME_RELATED_P (insn) = 1;
1286 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1287 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
1288 plus_constant (Pmode,
1289 stack_pointer_rtx,
1290 -size_cfa)));
1291 }
1292
1293 fp_plus_insns = get_insns ();
1294 end_sequence ();
1295
1296 /************ Method 2: Adjust Stack pointer ************/
1297
1298 /* Stack adjustment by means of RCALL . and/or PUSH __TMP_REG__
1299 can only handle specific offsets. */
1300
1301 if (avr_sp_immediate_operand (gen_int_mode (-size, HImode), HImode))
1302 {
1303 rtx_insn *sp_plus_insns;
1304
1305 start_sequence ();
1306
1307 insn = emit_move_insn (stack_pointer_rtx,
1308 plus_constant (Pmode, stack_pointer_rtx,
1309 -size));
1310 RTX_FRAME_RELATED_P (insn) = 1;
1311 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1312 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
1313 plus_constant (Pmode,
1314 stack_pointer_rtx,
1315 -size_cfa)));
1316 if (frame_pointer_needed)
1317 {
1318 insn = emit_move_insn (fp, stack_pointer_rtx);
1319 RTX_FRAME_RELATED_P (insn) = 1;
1320 }
1321
1322 sp_plus_insns = get_insns ();
1323 end_sequence ();
1324
1325 /************ Use shortest method ************/
1326
1327 emit_insn (get_sequence_length (sp_plus_insns)
1328 < get_sequence_length (fp_plus_insns)
1329 ? sp_plus_insns
1330 : fp_plus_insns);
1331 }
1332 else
1333 {
1334 emit_insn (fp_plus_insns);
1335 }
1336
1337 cfun->machine->stack_usage += size_cfa;
1338 } /* !minimize && size != 0 */
1339 } /* !minimize */
1340 }
1341
1342
1343 /* Output function prologue. */
1344
1345 void
1346 avr_expand_prologue (void)
1347 {
1348 HARD_REG_SET set;
1349 HOST_WIDE_INT size;
1350
1351 size = get_frame_size() + avr_outgoing_args_size();
1352
1353 cfun->machine->stack_usage = 0;
1354
1355 /* Prologue: naked. */
1356 if (cfun->machine->is_naked)
1357 {
1358 return;
1359 }
1360
1361 avr_regs_to_save (&set);
1362
1363 if (cfun->machine->is_interrupt || cfun->machine->is_signal)
1364 {
1365 /* Enable interrupts. */
1366 if (cfun->machine->is_interrupt)
1367 emit_insn (gen_enable_interrupt ());
1368
1369 /* Push zero reg. */
1370 emit_push_byte (AVR_ZERO_REGNO, true);
1371
1372 /* Push tmp reg. */
1373 emit_push_byte (AVR_TMP_REGNO, true);
1374
1375 /* Push SREG. */
1376 /* ??? There's no dwarf2 column reserved for SREG. */
1377 emit_push_sfr (sreg_rtx, false, false /* clr */);
1378
1379 /* Clear zero reg. */
1380 emit_move_insn (zero_reg_rtx, const0_rtx);
1381
1382 /* Prevent any attempt to delete the setting of ZERO_REG! */
1383 emit_use (zero_reg_rtx);
1384
1385 /* Push and clear RAMPD/X/Y/Z if present and low-part register is used.
1386 ??? There are no dwarf2 columns reserved for RAMPD/X/Y/Z. */
1387
1388 if (AVR_HAVE_RAMPD)
1389 emit_push_sfr (rampd_rtx, false /* frame-related */, true /* clr */);
1390
1391 if (AVR_HAVE_RAMPX
1392 && TEST_HARD_REG_BIT (set, REG_X)
1393 && TEST_HARD_REG_BIT (set, REG_X + 1))
1394 {
1395 emit_push_sfr (rampx_rtx, false /* frame-related */, true /* clr */);
1396 }
1397
1398 if (AVR_HAVE_RAMPY
1399 && (frame_pointer_needed
1400 || (TEST_HARD_REG_BIT (set, REG_Y)
1401 && TEST_HARD_REG_BIT (set, REG_Y + 1))))
1402 {
1403 emit_push_sfr (rampy_rtx, false /* frame-related */, true /* clr */);
1404 }
1405
1406 if (AVR_HAVE_RAMPZ
1407 && TEST_HARD_REG_BIT (set, REG_Z)
1408 && TEST_HARD_REG_BIT (set, REG_Z + 1))
1409 {
1410 emit_push_sfr (rampz_rtx, false /* frame-related */, AVR_HAVE_RAMPD);
1411 }
1412 } /* is_interrupt is_signal */
1413
1414 avr_prologue_setup_frame (size, set);
1415
1416 if (flag_stack_usage_info)
1417 current_function_static_stack_size = cfun->machine->stack_usage;
1418 }
1419
1420
1421 /* Implement `TARGET_ASM_FUNCTION_END_PROLOGUE'. */
1422 /* Output summary at end of function prologue. */
1423
1424 static void
1425 avr_asm_function_end_prologue (FILE *file)
1426 {
1427 if (cfun->machine->is_naked)
1428 {
1429 fputs ("/* prologue: naked */\n", file);
1430 }
1431 else
1432 {
1433 if (cfun->machine->is_interrupt)
1434 {
1435 fputs ("/* prologue: Interrupt */\n", file);
1436 }
1437 else if (cfun->machine->is_signal)
1438 {
1439 fputs ("/* prologue: Signal */\n", file);
1440 }
1441 else
1442 fputs ("/* prologue: function */\n", file);
1443 }
1444
1445 if (ACCUMULATE_OUTGOING_ARGS)
1446 fprintf (file, "/* outgoing args size = %d */\n",
1447 avr_outgoing_args_size());
1448
1449 fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n",
1450 get_frame_size());
1451 fprintf (file, "/* stack size = %d */\n",
1452 cfun->machine->stack_usage);
1453 /* Create symbol stack offset here so all functions have it. Add 1 to stack
1454 usage for offset so that SP + .L__stack_offset = return address. */
1455 fprintf (file, ".L__stack_usage = %d\n", cfun->machine->stack_usage);
1456 }
1457
1458
1459 /* Implement `EPILOGUE_USES'. */
1460
1461 int
1462 avr_epilogue_uses (int regno ATTRIBUTE_UNUSED)
1463 {
1464 if (reload_completed
1465 && cfun->machine
1466 && (cfun->machine->is_interrupt || cfun->machine->is_signal))
1467 return 1;
1468 return 0;
1469 }
1470
1471 /* Helper for avr_expand_epilogue. Emit a pop of a byte register. */
1472
1473 static void
1474 emit_pop_byte (unsigned regno)
1475 {
1476 rtx mem, reg;
1477
1478 mem = gen_rtx_PRE_INC (HImode, stack_pointer_rtx);
1479 mem = gen_frame_mem (QImode, mem);
1480 reg = gen_rtx_REG (QImode, regno);
1481
1482 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
1483 }
1484
1485 /* Output RTL epilogue. */
1486
1487 void
1488 avr_expand_epilogue (bool sibcall_p)
1489 {
1490 int reg;
1491 int live_seq;
1492 HARD_REG_SET set;
1493 int minimize;
1494 HOST_WIDE_INT size;
1495 bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
1496
1497 size = get_frame_size() + avr_outgoing_args_size();
1498
1499 /* epilogue: naked */
1500 if (cfun->machine->is_naked)
1501 {
1502 gcc_assert (!sibcall_p);
1503
1504 emit_jump_insn (gen_return ());
1505 return;
1506 }
1507
1508 avr_regs_to_save (&set);
1509 live_seq = sequent_regs_live ();
1510
1511 minimize = (TARGET_CALL_PROLOGUES
1512 && live_seq
1513 && !isr_p
1514 && !cfun->machine->is_OS_task
1515 && !cfun->machine->is_OS_main
1516 && !AVR_TINY);
1517
1518 if (minimize
1519 && (live_seq > 4
1520 || frame_pointer_needed
1521 || size))
1522 {
1523 /* Get rid of frame. */
1524
1525 if (!frame_pointer_needed)
1526 {
1527 emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1528 }
1529
1530 if (size)
1531 {
1532 emit_move_insn (frame_pointer_rtx,
1533 plus_constant (Pmode, frame_pointer_rtx, size));
1534 }
1535
1536 emit_insn (gen_epilogue_restores (gen_int_mode (live_seq, HImode)));
1537 return;
1538 }
1539
1540 if (size)
1541 {
1542 /* Try two methods to adjust stack and select shortest. */
1543
1544 int irq_state = -1;
1545 rtx fp, my_fp;
1546 rtx_insn *fp_plus_insns;
1547 HOST_WIDE_INT size_max;
1548
1549 gcc_assert (frame_pointer_needed
1550 || !isr_p
1551 || !crtl->is_leaf);
1552
1553 fp = my_fp = (frame_pointer_needed
1554 ? frame_pointer_rtx
1555 : gen_rtx_REG (Pmode, REG_X));
1556
1557 if (AVR_HAVE_8BIT_SP)
1558 {
1559 /* The high byte (r29) does not change:
1560 Prefer SUBI (1 cycle) over SBIW (2 cycles). */
1561
1562 my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
1563 }
1564
1565 /* For rationale see comment in prologue generation. */
1566
1567 size_max = (HOST_WIDE_INT) GET_MODE_MASK (GET_MODE (my_fp));
1568 if (size > size_max)
1569 size = size_max;
1570 size = trunc_int_for_mode (size, GET_MODE (my_fp));
1571
1572 /********** Method 1: Adjust fp register **********/
1573
1574 start_sequence ();
1575
1576 if (!frame_pointer_needed)
1577 emit_move_insn (fp, stack_pointer_rtx);
1578
1579 emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp), my_fp, size));
1580
1581 /* Copy to stack pointer. */
1582
1583 if (TARGET_NO_INTERRUPTS)
1584 irq_state = 0;
1585
1586 if (AVR_HAVE_8BIT_SP)
1587 irq_state = 2;
1588
1589 emit_insn (gen_movhi_sp_r (stack_pointer_rtx, fp,
1590 GEN_INT (irq_state)));
1591
1592 fp_plus_insns = get_insns ();
1593 end_sequence ();
1594
1595 /********** Method 2: Adjust Stack pointer **********/
1596
1597 if (avr_sp_immediate_operand (gen_int_mode (size, HImode), HImode))
1598 {
1599 rtx_insn *sp_plus_insns;
1600
1601 start_sequence ();
1602
1603 emit_move_insn (stack_pointer_rtx,
1604 plus_constant (Pmode, stack_pointer_rtx, size));
1605
1606 sp_plus_insns = get_insns ();
1607 end_sequence ();
1608
1609 /************ Use shortest method ************/
1610
1611 emit_insn (get_sequence_length (sp_plus_insns)
1612 < get_sequence_length (fp_plus_insns)
1613 ? sp_plus_insns
1614 : fp_plus_insns);
1615 }
1616 else
1617 emit_insn (fp_plus_insns);
1618 } /* size != 0 */
1619
1620 if (frame_pointer_needed
1621 && !(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
1622 {
1623 /* Restore previous frame_pointer. See avr_expand_prologue for
1624 rationale for not using pophi. */
1625
1626 emit_pop_byte (REG_Y + 1);
1627 emit_pop_byte (REG_Y);
1628 }
1629
1630 /* Restore used registers. */
1631
1632 for (reg = 31; reg >= 0; --reg)
1633 if (TEST_HARD_REG_BIT (set, reg))
1634 emit_pop_byte (reg);
1635
1636 if (isr_p)
1637 {
1638 /* Restore RAMPZ/Y/X/D using tmp_reg as scratch.
1639 The conditions to restore them must be tha same as in prologue. */
1640
1641 if (AVR_HAVE_RAMPZ
1642 && TEST_HARD_REG_BIT (set, REG_Z)
1643 && TEST_HARD_REG_BIT (set, REG_Z + 1))
1644 {
1645 emit_pop_byte (TMP_REGNO);
1646 emit_move_insn (rampz_rtx, tmp_reg_rtx);
1647 }
1648
1649 if (AVR_HAVE_RAMPY
1650 && (frame_pointer_needed
1651 || (TEST_HARD_REG_BIT (set, REG_Y)
1652 && TEST_HARD_REG_BIT (set, REG_Y + 1))))
1653 {
1654 emit_pop_byte (TMP_REGNO);
1655 emit_move_insn (rampy_rtx, tmp_reg_rtx);
1656 }
1657
1658 if (AVR_HAVE_RAMPX
1659 && TEST_HARD_REG_BIT (set, REG_X)
1660 && TEST_HARD_REG_BIT (set, REG_X + 1))
1661 {
1662 emit_pop_byte (TMP_REGNO);
1663 emit_move_insn (rampx_rtx, tmp_reg_rtx);
1664 }
1665
1666 if (AVR_HAVE_RAMPD)
1667 {
1668 emit_pop_byte (TMP_REGNO);
1669 emit_move_insn (rampd_rtx, tmp_reg_rtx);
1670 }
1671
1672 /* Restore SREG using tmp_reg as scratch. */
1673
1674 emit_pop_byte (AVR_TMP_REGNO);
1675 emit_move_insn (sreg_rtx, tmp_reg_rtx);
1676
1677 /* Restore tmp REG. */
1678 emit_pop_byte (AVR_TMP_REGNO);
1679
1680 /* Restore zero REG. */
1681 emit_pop_byte (AVR_ZERO_REGNO);
1682 }
1683
1684 if (!sibcall_p)
1685 emit_jump_insn (gen_return ());
1686 }
1687
1688
1689 /* Implement `TARGET_ASM_FUNCTION_BEGIN_EPILOGUE'. */
1690
1691 static void
1692 avr_asm_function_begin_epilogue (FILE *file)
1693 {
1694 fprintf (file, "/* epilogue start */\n");
1695 }
1696
1697
1698 /* Implement `TARGET_CANNOT_MODITY_JUMPS_P'. */
1699
1700 static bool
1701 avr_cannot_modify_jumps_p (void)
1702 {
1703
1704 /* Naked Functions must not have any instructions after
1705 their epilogue, see PR42240 */
1706
1707 if (reload_completed
1708 && cfun->machine
1709 && cfun->machine->is_naked)
1710 {
1711 return true;
1712 }
1713
1714 return false;
1715 }
1716
1717
1718 /* Implement `TARGET_MODE_DEPENDENT_ADDRESS_P'. */
1719
1720 static bool
1721 avr_mode_dependent_address_p (const_rtx addr ATTRIBUTE_UNUSED, addr_space_t as)
1722 {
1723 /* FIXME: Non-generic addresses are not mode-dependent in themselves.
1724 This hook just serves to hack around PR rtl-optimization/52543 by
1725 claiming that non-generic addresses were mode-dependent so that
1726 lower-subreg.c will skip these addresses. lower-subreg.c sets up fake
1727 RTXes to probe SET and MEM costs and assumes that MEM is always in the
1728 generic address space which is not true. */
1729
1730 return !ADDR_SPACE_GENERIC_P (as);
1731 }
1732
1733
1734 /* Helper function for `avr_legitimate_address_p'. */
1735
1736 static inline bool
1737 avr_reg_ok_for_addr_p (rtx reg, addr_space_t as,
1738 RTX_CODE outer_code, bool strict)
1739 {
1740 return (REG_P (reg)
1741 && (avr_regno_mode_code_ok_for_base_p (REGNO (reg), QImode,
1742 as, outer_code, UNKNOWN)
1743 || (!strict
1744 && REGNO (reg) >= FIRST_PSEUDO_REGISTER)));
1745 }
1746
1747
1748 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
1749 machine for a memory operand of mode MODE. */
1750
1751 static bool
1752 avr_legitimate_address_p (machine_mode mode, rtx x, bool strict)
1753 {
1754 bool ok = CONSTANT_ADDRESS_P (x);
1755
1756 switch (GET_CODE (x))
1757 {
1758 case REG:
1759 ok = avr_reg_ok_for_addr_p (x, ADDR_SPACE_GENERIC,
1760 MEM, strict);
1761
1762 if (strict
1763 && GET_MODE_SIZE (mode) > 4
1764 && REG_X == REGNO (x))
1765 {
1766 ok = false;
1767 }
1768 break;
1769
1770 case POST_INC:
1771 case PRE_DEC:
1772 ok = avr_reg_ok_for_addr_p (XEXP (x, 0), ADDR_SPACE_GENERIC,
1773 GET_CODE (x), strict);
1774 break;
1775
1776 case PLUS:
1777 {
1778 rtx reg = XEXP (x, 0);
1779 rtx op1 = XEXP (x, 1);
1780
1781 if (REG_P (reg)
1782 && CONST_INT_P (op1)
1783 && INTVAL (op1) >= 0)
1784 {
1785 bool fit = IN_RANGE (INTVAL (op1), 0, MAX_LD_OFFSET (mode));
1786
1787 if (fit)
1788 {
1789 ok = (! strict
1790 || avr_reg_ok_for_addr_p (reg, ADDR_SPACE_GENERIC,
1791 PLUS, strict));
1792
1793 if (reg == frame_pointer_rtx
1794 || reg == arg_pointer_rtx)
1795 {
1796 ok = true;
1797 }
1798 }
1799 else if (frame_pointer_needed
1800 && reg == frame_pointer_rtx)
1801 {
1802 ok = true;
1803 }
1804 }
1805 }
1806 break;
1807
1808 default:
1809 break;
1810 }
1811
1812 if (avr_log.legitimate_address_p)
1813 {
1814 avr_edump ("\n%?: ret=%d, mode=%m strict=%d "
1815 "reload_completed=%d reload_in_progress=%d %s:",
1816 ok, mode, strict, reload_completed, reload_in_progress,
1817 reg_renumber ? "(reg_renumber)" : "");
1818
1819 if (GET_CODE (x) == PLUS
1820 && REG_P (XEXP (x, 0))
1821 && CONST_INT_P (XEXP (x, 1))
1822 && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
1823 && reg_renumber)
1824 {
1825 avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
1826 true_regnum (XEXP (x, 0)));
1827 }
1828
1829 avr_edump ("\n%r\n", x);
1830 }
1831
1832 return ok;
1833 }
1834
1835
1836 /* Former implementation of TARGET_LEGITIMIZE_ADDRESS,
1837 now only a helper for avr_addr_space_legitimize_address. */
1838 /* Attempts to replace X with a valid
1839 memory address for an operand of mode MODE */
1840
1841 static rtx
1842 avr_legitimize_address (rtx x, rtx oldx, machine_mode mode)
1843 {
1844 bool big_offset_p = false;
1845
1846 x = oldx;
1847
1848 if (GET_CODE (oldx) == PLUS
1849 && REG_P (XEXP (oldx, 0)))
1850 {
1851 if (REG_P (XEXP (oldx, 1)))
1852 x = force_reg (GET_MODE (oldx), oldx);
1853 else if (CONST_INT_P (XEXP (oldx, 1)))
1854 {
1855 int offs = INTVAL (XEXP (oldx, 1));
1856 if (frame_pointer_rtx != XEXP (oldx, 0)
1857 && offs > MAX_LD_OFFSET (mode))
1858 {
1859 big_offset_p = true;
1860 x = force_reg (GET_MODE (oldx), oldx);
1861 }
1862 }
1863 }
1864
1865 if (avr_log.legitimize_address)
1866 {
1867 avr_edump ("\n%?: mode=%m\n %r\n", mode, oldx);
1868
1869 if (x != oldx)
1870 avr_edump (" %s --> %r\n", big_offset_p ? "(big offset)" : "", x);
1871 }
1872
1873 return x;
1874 }
1875
1876
1877 /* Implement `LEGITIMIZE_RELOAD_ADDRESS'. */
1878 /* This will allow register R26/27 to be used where it is no worse than normal
1879 base pointers R28/29 or R30/31. For example, if base offset is greater
1880 than 63 bytes or for R++ or --R addressing. */
1881
1882 rtx
1883 avr_legitimize_reload_address (rtx *px, machine_mode mode,
1884 int opnum, int type, int addr_type,
1885 int ind_levels ATTRIBUTE_UNUSED,
1886 rtx (*mk_memloc)(rtx,int))
1887 {
1888 rtx x = *px;
1889
1890 if (avr_log.legitimize_reload_address)
1891 avr_edump ("\n%?:%m %r\n", mode, x);
1892
1893 if (1 && (GET_CODE (x) == POST_INC
1894 || GET_CODE (x) == PRE_DEC))
1895 {
1896 push_reload (XEXP (x, 0), XEXP (x, 0), &XEXP (x, 0), &XEXP (x, 0),
1897 POINTER_REGS, GET_MODE (x), GET_MODE (x), 0, 0,
1898 opnum, RELOAD_OTHER);
1899
1900 if (avr_log.legitimize_reload_address)
1901 avr_edump (" RCLASS.1 = %R\n IN = %r\n OUT = %r\n",
1902 POINTER_REGS, XEXP (x, 0), XEXP (x, 0));
1903
1904 return x;
1905 }
1906
1907 if (GET_CODE (x) == PLUS
1908 && REG_P (XEXP (x, 0))
1909 && 0 == reg_equiv_constant (REGNO (XEXP (x, 0)))
1910 && CONST_INT_P (XEXP (x, 1))
1911 && INTVAL (XEXP (x, 1)) >= 1)
1912 {
1913 bool fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
1914
1915 if (fit)
1916 {
1917 if (reg_equiv_address (REGNO (XEXP (x, 0))) != 0)
1918 {
1919 int regno = REGNO (XEXP (x, 0));
1920 rtx mem = mk_memloc (x, regno);
1921
1922 push_reload (XEXP (mem, 0), NULL_RTX, &XEXP (mem, 0), NULL,
1923 POINTER_REGS, Pmode, VOIDmode, 0, 0,
1924 1, (enum reload_type) addr_type);
1925
1926 if (avr_log.legitimize_reload_address)
1927 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
1928 POINTER_REGS, XEXP (mem, 0), NULL_RTX);
1929
1930 push_reload (mem, NULL_RTX, &XEXP (x, 0), NULL,
1931 BASE_POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
1932 opnum, (enum reload_type) type);
1933
1934 if (avr_log.legitimize_reload_address)
1935 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
1936 BASE_POINTER_REGS, mem, NULL_RTX);
1937
1938 return x;
1939 }
1940 }
1941 else if (! (frame_pointer_needed
1942 && XEXP (x, 0) == frame_pointer_rtx))
1943 {
1944 push_reload (x, NULL_RTX, px, NULL,
1945 POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
1946 opnum, (enum reload_type) type);
1947
1948 if (avr_log.legitimize_reload_address)
1949 avr_edump (" RCLASS.3 = %R\n IN = %r\n OUT = %r\n",
1950 POINTER_REGS, x, NULL_RTX);
1951
1952 return x;
1953 }
1954 }
1955
1956 return NULL_RTX;
1957 }
1958
1959
1960 /* Implement `TARGET_SECONDARY_RELOAD' */
1961
1962 static reg_class_t
1963 avr_secondary_reload (bool in_p, rtx x,
1964 reg_class_t reload_class ATTRIBUTE_UNUSED,
1965 machine_mode mode, secondary_reload_info *sri)
1966 {
1967 if (in_p
1968 && MEM_P (x)
1969 && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x))
1970 && ADDR_SPACE_MEMX != MEM_ADDR_SPACE (x))
1971 {
1972 /* For the non-generic 16-bit spaces we need a d-class scratch. */
1973
1974 switch (mode)
1975 {
1976 default:
1977 gcc_unreachable();
1978
1979 case QImode: sri->icode = CODE_FOR_reload_inqi; break;
1980 case QQmode: sri->icode = CODE_FOR_reload_inqq; break;
1981 case UQQmode: sri->icode = CODE_FOR_reload_inuqq; break;
1982
1983 case HImode: sri->icode = CODE_FOR_reload_inhi; break;
1984 case HQmode: sri->icode = CODE_FOR_reload_inhq; break;
1985 case HAmode: sri->icode = CODE_FOR_reload_inha; break;
1986 case UHQmode: sri->icode = CODE_FOR_reload_inuhq; break;
1987 case UHAmode: sri->icode = CODE_FOR_reload_inuha; break;
1988
1989 case PSImode: sri->icode = CODE_FOR_reload_inpsi; break;
1990
1991 case SImode: sri->icode = CODE_FOR_reload_insi; break;
1992 case SFmode: sri->icode = CODE_FOR_reload_insf; break;
1993 case SQmode: sri->icode = CODE_FOR_reload_insq; break;
1994 case SAmode: sri->icode = CODE_FOR_reload_insa; break;
1995 case USQmode: sri->icode = CODE_FOR_reload_inusq; break;
1996 case USAmode: sri->icode = CODE_FOR_reload_inusa; break;
1997 }
1998 }
1999
2000 return NO_REGS;
2001 }
2002
2003
2004 /* Helper function to print assembler resp. track instruction
2005 sequence lengths. Always return "".
2006
2007 If PLEN == NULL:
2008 Output assembler code from template TPL with operands supplied
2009 by OPERANDS. This is just forwarding to output_asm_insn.
2010
2011 If PLEN != NULL:
2012 If N_WORDS >= 0 Add N_WORDS to *PLEN.
2013 If N_WORDS < 0 Set *PLEN to -N_WORDS.
2014 Don't output anything.
2015 */
2016
2017 static const char*
2018 avr_asm_len (const char* tpl, rtx* operands, int* plen, int n_words)
2019 {
2020 if (NULL == plen)
2021 {
2022 output_asm_insn (tpl, operands);
2023 }
2024 else
2025 {
2026 if (n_words < 0)
2027 *plen = -n_words;
2028 else
2029 *plen += n_words;
2030 }
2031
2032 return "";
2033 }
2034
2035
2036 /* Return a pointer register name as a string. */
2037
2038 static const char*
2039 ptrreg_to_str (int regno)
2040 {
2041 switch (regno)
2042 {
2043 case REG_X: return "X";
2044 case REG_Y: return "Y";
2045 case REG_Z: return "Z";
2046 default:
2047 output_operand_lossage ("address operand requires constraint for"
2048 " X, Y, or Z register");
2049 }
2050 return NULL;
2051 }
2052
2053 /* Return the condition name as a string.
2054 Used in conditional jump constructing */
2055
2056 static const char*
2057 cond_string (enum rtx_code code)
2058 {
2059 switch (code)
2060 {
2061 case NE:
2062 return "ne";
2063 case EQ:
2064 return "eq";
2065 case GE:
2066 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2067 return "pl";
2068 else
2069 return "ge";
2070 case LT:
2071 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2072 return "mi";
2073 else
2074 return "lt";
2075 case GEU:
2076 return "sh";
2077 case LTU:
2078 return "lo";
2079 default:
2080 gcc_unreachable ();
2081 }
2082
2083 return "";
2084 }
2085
2086
2087 /* Implement `TARGET_PRINT_OPERAND_ADDRESS'. */
2088 /* Output ADDR to FILE as address. */
2089
2090 static void
2091 avr_print_operand_address (FILE *file, rtx addr)
2092 {
2093 switch (GET_CODE (addr))
2094 {
2095 case REG:
2096 fprintf (file, ptrreg_to_str (REGNO (addr)));
2097 break;
2098
2099 case PRE_DEC:
2100 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
2101 break;
2102
2103 case POST_INC:
2104 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
2105 break;
2106
2107 default:
2108 if (CONSTANT_ADDRESS_P (addr)
2109 && text_segment_operand (addr, VOIDmode))
2110 {
2111 rtx x = addr;
2112 if (GET_CODE (x) == CONST)
2113 x = XEXP (x, 0);
2114 if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x,1)) == CONST_INT)
2115 {
2116 /* Assembler gs() will implant word address. Make offset
2117 a byte offset inside gs() for assembler. This is
2118 needed because the more logical (constant+gs(sym)) is not
2119 accepted by gas. For 128K and smaller devices this is ok.
2120 For large devices it will create a trampoline to offset
2121 from symbol which may not be what the user really wanted. */
2122
2123 fprintf (file, "gs(");
2124 output_addr_const (file, XEXP (x,0));
2125 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC ")",
2126 2 * INTVAL (XEXP (x, 1)));
2127 if (AVR_3_BYTE_PC)
2128 if (warning (0, "pointer offset from symbol maybe incorrect"))
2129 {
2130 output_addr_const (stderr, addr);
2131 fprintf(stderr,"\n");
2132 }
2133 }
2134 else
2135 {
2136 fprintf (file, "gs(");
2137 output_addr_const (file, addr);
2138 fprintf (file, ")");
2139 }
2140 }
2141 else
2142 output_addr_const (file, addr);
2143 }
2144 }
2145
2146
2147 /* Implement `TARGET_PRINT_OPERAND_PUNCT_VALID_P'. */
2148
2149 static bool
2150 avr_print_operand_punct_valid_p (unsigned char code)
2151 {
2152 return code == '~' || code == '!';
2153 }
2154
2155
2156 /* Implement `TARGET_PRINT_OPERAND'. */
2157 /* Output X as assembler operand to file FILE.
2158 For a description of supported %-codes, see top of avr.md. */
2159
2160 static void
2161 avr_print_operand (FILE *file, rtx x, int code)
2162 {
2163 int abcd = 0, ef = 0, ij = 0;
2164
2165 if (code >= 'A' && code <= 'D')
2166 abcd = code - 'A';
2167 else if (code == 'E' || code == 'F')
2168 ef = code - 'E';
2169 else if (code == 'I' || code == 'J')
2170 ij = code - 'I';
2171
2172 if (code == '~')
2173 {
2174 if (!AVR_HAVE_JMP_CALL)
2175 fputc ('r', file);
2176 }
2177 else if (code == '!')
2178 {
2179 if (AVR_HAVE_EIJMP_EICALL)
2180 fputc ('e', file);
2181 }
2182 else if (code == 't'
2183 || code == 'T')
2184 {
2185 static int t_regno = -1;
2186 static int t_nbits = -1;
2187
2188 if (REG_P (x) && t_regno < 0 && code == 'T')
2189 {
2190 t_regno = REGNO (x);
2191 t_nbits = GET_MODE_BITSIZE (GET_MODE (x));
2192 }
2193 else if (CONST_INT_P (x) && t_regno >= 0
2194 && IN_RANGE (INTVAL (x), 0, t_nbits - 1))
2195 {
2196 int bpos = INTVAL (x);
2197
2198 fprintf (file, "%s", reg_names[t_regno + bpos / 8]);
2199 if (code == 'T')
2200 fprintf (file, ",%d", bpos % 8);
2201
2202 t_regno = -1;
2203 }
2204 else
2205 fatal_insn ("operands to %T/%t must be reg + const_int:", x);
2206 }
2207 else if (code == 'E' || code == 'F')
2208 {
2209 rtx op = XEXP(x, 0);
2210 fprintf (file, reg_names[REGNO (op) + ef]);
2211 }
2212 else if (code == 'I' || code == 'J')
2213 {
2214 rtx op = XEXP(XEXP(x, 0), 0);
2215 fprintf (file, reg_names[REGNO (op) + ij]);
2216 }
2217 else if (REG_P (x))
2218 {
2219 if (x == zero_reg_rtx)
2220 fprintf (file, "__zero_reg__");
2221 else if (code == 'r' && REGNO (x) < 32)
2222 fprintf (file, "%d", (int) REGNO (x));
2223 else
2224 fprintf (file, reg_names[REGNO (x) + abcd]);
2225 }
2226 else if (CONST_INT_P (x))
2227 {
2228 HOST_WIDE_INT ival = INTVAL (x);
2229
2230 if ('i' != code)
2231 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival + abcd);
2232 else if (low_io_address_operand (x, VOIDmode)
2233 || high_io_address_operand (x, VOIDmode))
2234 {
2235 if (AVR_HAVE_RAMPZ && ival == avr_addr.rampz)
2236 fprintf (file, "__RAMPZ__");
2237 else if (AVR_HAVE_RAMPY && ival == avr_addr.rampy)
2238 fprintf (file, "__RAMPY__");
2239 else if (AVR_HAVE_RAMPX && ival == avr_addr.rampx)
2240 fprintf (file, "__RAMPX__");
2241 else if (AVR_HAVE_RAMPD && ival == avr_addr.rampd)
2242 fprintf (file, "__RAMPD__");
2243 else if ((AVR_XMEGA || AVR_TINY) && ival == avr_addr.ccp)
2244 fprintf (file, "__CCP__");
2245 else if (ival == avr_addr.sreg) fprintf (file, "__SREG__");
2246 else if (ival == avr_addr.sp_l) fprintf (file, "__SP_L__");
2247 else if (ival == avr_addr.sp_h) fprintf (file, "__SP_H__");
2248 else
2249 {
2250 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
2251 ival - avr_current_arch->sfr_offset);
2252 }
2253 }
2254 else
2255 fatal_insn ("bad address, not an I/O address:", x);
2256 }
2257 else if (MEM_P (x))
2258 {
2259 rtx addr = XEXP (x, 0);
2260
2261 if (code == 'm')
2262 {
2263 if (!CONSTANT_P (addr))
2264 fatal_insn ("bad address, not a constant:", addr);
2265 /* Assembler template with m-code is data - not progmem section */
2266 if (text_segment_operand (addr, VOIDmode))
2267 if (warning (0, "accessing data memory with"
2268 " program memory address"))
2269 {
2270 output_addr_const (stderr, addr);
2271 fprintf(stderr,"\n");
2272 }
2273 output_addr_const (file, addr);
2274 }
2275 else if (code == 'i')
2276 {
2277 avr_print_operand (file, addr, 'i');
2278 }
2279 else if (code == 'o')
2280 {
2281 if (GET_CODE (addr) != PLUS)
2282 fatal_insn ("bad address, not (reg+disp):", addr);
2283
2284 avr_print_operand (file, XEXP (addr, 1), 0);
2285 }
2286 else if (code == 'b')
2287 {
2288 if (GET_CODE (addr) != PLUS)
2289 fatal_insn ("bad address, not (reg+disp):", addr);
2290
2291 avr_print_operand_address (file, XEXP (addr, 0));
2292 }
2293 else if (code == 'p' || code == 'r')
2294 {
2295 if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
2296 fatal_insn ("bad address, not post_inc or pre_dec:", addr);
2297
2298 if (code == 'p')
2299 avr_print_operand_address (file, XEXP (addr, 0)); /* X, Y, Z */
2300 else
2301 avr_print_operand (file, XEXP (addr, 0), 0); /* r26, r28, r30 */
2302 }
2303 else if (GET_CODE (addr) == PLUS)
2304 {
2305 avr_print_operand_address (file, XEXP (addr,0));
2306 if (REGNO (XEXP (addr, 0)) == REG_X)
2307 fatal_insn ("internal compiler error. Bad address:"
2308 ,addr);
2309 fputc ('+', file);
2310 avr_print_operand (file, XEXP (addr,1), code);
2311 }
2312 else
2313 avr_print_operand_address (file, addr);
2314 }
2315 else if (code == 'i')
2316 {
2317 if (GET_CODE (x) == SYMBOL_REF && (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_IO))
2318 avr_print_operand_address
2319 (file, plus_constant (HImode, x, -avr_current_arch->sfr_offset));
2320 else
2321 fatal_insn ("bad address, not an I/O address:", x);
2322 }
2323 else if (code == 'x')
2324 {
2325 /* Constant progmem address - like used in jmp or call */
2326 if (0 == text_segment_operand (x, VOIDmode))
2327 if (warning (0, "accessing program memory"
2328 " with data memory address"))
2329 {
2330 output_addr_const (stderr, x);
2331 fprintf(stderr,"\n");
2332 }
2333 /* Use normal symbol for direct address no linker trampoline needed */
2334 output_addr_const (file, x);
2335 }
2336 else if (CONST_FIXED_P (x))
2337 {
2338 HOST_WIDE_INT ival = INTVAL (avr_to_int_mode (x));
2339 if (code != 0)
2340 output_operand_lossage ("Unsupported code '%c' for fixed-point:",
2341 code);
2342 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival);
2343 }
2344 else if (GET_CODE (x) == CONST_DOUBLE)
2345 {
2346 long val;
2347 REAL_VALUE_TYPE rv;
2348 if (GET_MODE (x) != SFmode)
2349 fatal_insn ("internal compiler error. Unknown mode:", x);
2350 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
2351 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
2352 fprintf (file, "0x%lx", val);
2353 }
2354 else if (GET_CODE (x) == CONST_STRING)
2355 fputs (XSTR (x, 0), file);
2356 else if (code == 'j')
2357 fputs (cond_string (GET_CODE (x)), file);
2358 else if (code == 'k')
2359 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
2360 else
2361 avr_print_operand_address (file, x);
2362 }
2363
2364
2365 /* Worker function for `NOTICE_UPDATE_CC'. */
2366 /* Update the condition code in the INSN. */
2367
2368 void
2369 avr_notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx_insn *insn)
2370 {
2371 rtx set;
2372 enum attr_cc cc = get_attr_cc (insn);
2373
2374 switch (cc)
2375 {
2376 default:
2377 break;
2378
2379 case CC_PLUS:
2380 case CC_LDI:
2381 {
2382 rtx *op = recog_data.operand;
2383 int len_dummy, icc;
2384
2385 /* Extract insn's operands. */
2386 extract_constrain_insn_cached (insn);
2387
2388 switch (cc)
2389 {
2390 default:
2391 gcc_unreachable();
2392
2393 case CC_PLUS:
2394 avr_out_plus (insn, op, &len_dummy, &icc);
2395 cc = (enum attr_cc) icc;
2396 break;
2397
2398 case CC_LDI:
2399
2400 cc = (op[1] == CONST0_RTX (GET_MODE (op[0]))
2401 && reg_overlap_mentioned_p (op[0], zero_reg_rtx))
2402 /* Loading zero-reg with 0 uses CLR and thus clobbers cc0. */
2403 ? CC_CLOBBER
2404 /* Any other "r,rL" combination does not alter cc0. */
2405 : CC_NONE;
2406
2407 break;
2408 } /* inner switch */
2409
2410 break;
2411 }
2412 } /* outer swicth */
2413
2414 switch (cc)
2415 {
2416 default:
2417 /* Special values like CC_OUT_PLUS from above have been
2418 mapped to "standard" CC_* values so we never come here. */
2419
2420 gcc_unreachable();
2421 break;
2422
2423 case CC_NONE:
2424 /* Insn does not affect CC at all. */
2425 break;
2426
2427 case CC_SET_N:
2428 CC_STATUS_INIT;
2429 break;
2430
2431 case CC_SET_ZN:
2432 set = single_set (insn);
2433 CC_STATUS_INIT;
2434 if (set)
2435 {
2436 cc_status.flags |= CC_NO_OVERFLOW;
2437 cc_status.value1 = SET_DEST (set);
2438 }
2439 break;
2440
2441 case CC_SET_VZN:
2442 /* Insn like INC, DEC, NEG that set Z,N,V. We currently don't make use
2443 of this combination, cf. also PR61055. */
2444 CC_STATUS_INIT;
2445 break;
2446
2447 case CC_SET_CZN:
2448 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
2449 The V flag may or may not be known but that's ok because
2450 alter_cond will change tests to use EQ/NE. */
2451 set = single_set (insn);
2452 CC_STATUS_INIT;
2453 if (set)
2454 {
2455 cc_status.value1 = SET_DEST (set);
2456 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
2457 }
2458 break;
2459
2460 case CC_COMPARE:
2461 set = single_set (insn);
2462 CC_STATUS_INIT;
2463 if (set)
2464 cc_status.value1 = SET_SRC (set);
2465 break;
2466
2467 case CC_CLOBBER:
2468 /* Insn doesn't leave CC in a usable state. */
2469 CC_STATUS_INIT;
2470 break;
2471 }
2472 }
2473
2474 /* Choose mode for jump insn:
2475 1 - relative jump in range -63 <= x <= 62 ;
2476 2 - relative jump in range -2046 <= x <= 2045 ;
2477 3 - absolute jump (only for ATmega[16]03). */
2478
2479 int
2480 avr_jump_mode (rtx x, rtx_insn *insn)
2481 {
2482 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_CODE (x) == LABEL_REF
2483 ? XEXP (x, 0) : x));
2484 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
2485 int jump_distance = cur_addr - dest_addr;
2486
2487 if (-63 <= jump_distance && jump_distance <= 62)
2488 return 1;
2489 else if (-2046 <= jump_distance && jump_distance <= 2045)
2490 return 2;
2491 else if (AVR_HAVE_JMP_CALL)
2492 return 3;
2493
2494 return 2;
2495 }
2496
2497 /* Return an AVR condition jump commands.
2498 X is a comparison RTX.
2499 LEN is a number returned by avr_jump_mode function.
2500 If REVERSE nonzero then condition code in X must be reversed. */
2501
2502 const char*
2503 ret_cond_branch (rtx x, int len, int reverse)
2504 {
2505 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
2506
2507 switch (cond)
2508 {
2509 case GT:
2510 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2511 return (len == 1 ? ("breq .+2" CR_TAB
2512 "brpl %0") :
2513 len == 2 ? ("breq .+4" CR_TAB
2514 "brmi .+2" CR_TAB
2515 "rjmp %0") :
2516 ("breq .+6" CR_TAB
2517 "brmi .+4" CR_TAB
2518 "jmp %0"));
2519
2520 else
2521 return (len == 1 ? ("breq .+2" CR_TAB
2522 "brge %0") :
2523 len == 2 ? ("breq .+4" CR_TAB
2524 "brlt .+2" CR_TAB
2525 "rjmp %0") :
2526 ("breq .+6" CR_TAB
2527 "brlt .+4" CR_TAB
2528 "jmp %0"));
2529 case GTU:
2530 return (len == 1 ? ("breq .+2" CR_TAB
2531 "brsh %0") :
2532 len == 2 ? ("breq .+4" CR_TAB
2533 "brlo .+2" CR_TAB
2534 "rjmp %0") :
2535 ("breq .+6" CR_TAB
2536 "brlo .+4" CR_TAB
2537 "jmp %0"));
2538 case LE:
2539 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2540 return (len == 1 ? ("breq %0" CR_TAB
2541 "brmi %0") :
2542 len == 2 ? ("breq .+2" CR_TAB
2543 "brpl .+2" CR_TAB
2544 "rjmp %0") :
2545 ("breq .+2" CR_TAB
2546 "brpl .+4" CR_TAB
2547 "jmp %0"));
2548 else
2549 return (len == 1 ? ("breq %0" CR_TAB
2550 "brlt %0") :
2551 len == 2 ? ("breq .+2" CR_TAB
2552 "brge .+2" CR_TAB
2553 "rjmp %0") :
2554 ("breq .+2" CR_TAB
2555 "brge .+4" CR_TAB
2556 "jmp %0"));
2557 case LEU:
2558 return (len == 1 ? ("breq %0" CR_TAB
2559 "brlo %0") :
2560 len == 2 ? ("breq .+2" CR_TAB
2561 "brsh .+2" CR_TAB
2562 "rjmp %0") :
2563 ("breq .+2" CR_TAB
2564 "brsh .+4" CR_TAB
2565 "jmp %0"));
2566 default:
2567 if (reverse)
2568 {
2569 switch (len)
2570 {
2571 case 1:
2572 return "br%k1 %0";
2573 case 2:
2574 return ("br%j1 .+2" CR_TAB
2575 "rjmp %0");
2576 default:
2577 return ("br%j1 .+4" CR_TAB
2578 "jmp %0");
2579 }
2580 }
2581 else
2582 {
2583 switch (len)
2584 {
2585 case 1:
2586 return "br%j1 %0";
2587 case 2:
2588 return ("br%k1 .+2" CR_TAB
2589 "rjmp %0");
2590 default:
2591 return ("br%k1 .+4" CR_TAB
2592 "jmp %0");
2593 }
2594 }
2595 }
2596 return "";
2597 }
2598
2599
2600 /* Worker function for `FINAL_PRESCAN_INSN'. */
2601 /* Output insn cost for next insn. */
2602
2603 void
2604 avr_final_prescan_insn (rtx_insn *insn, rtx *operand ATTRIBUTE_UNUSED,
2605 int num_operands ATTRIBUTE_UNUSED)
2606 {
2607 if (avr_log.rtx_costs)
2608 {
2609 rtx set = single_set (insn);
2610
2611 if (set)
2612 fprintf (asm_out_file, "/* DEBUG: cost = %d. */\n",
2613 set_src_cost (SET_SRC (set), optimize_insn_for_speed_p ()));
2614 else
2615 fprintf (asm_out_file, "/* DEBUG: pattern-cost = %d. */\n",
2616 rtx_cost (PATTERN (insn), INSN, 0,
2617 optimize_insn_for_speed_p()));
2618 }
2619 }
2620
2621 /* Return 0 if undefined, 1 if always true or always false. */
2622
2623 int
2624 avr_simplify_comparison_p (machine_mode mode, RTX_CODE op, rtx x)
2625 {
2626 unsigned int max = (mode == QImode ? 0xff :
2627 mode == HImode ? 0xffff :
2628 mode == PSImode ? 0xffffff :
2629 mode == SImode ? 0xffffffff : 0);
2630 if (max && op && CONST_INT_P (x))
2631 {
2632 if (unsigned_condition (op) != op)
2633 max >>= 1;
2634
2635 if (max != (INTVAL (x) & max)
2636 && INTVAL (x) != 0xff)
2637 return 1;
2638 }
2639 return 0;
2640 }
2641
2642
2643 /* Worker function for `FUNCTION_ARG_REGNO_P'. */
2644 /* Returns nonzero if REGNO is the number of a hard
2645 register in which function arguments are sometimes passed. */
2646
2647 int
2648 avr_function_arg_regno_p(int r)
2649 {
2650 return (AVR_TINY ? r >= 20 && r <= 25 : r >= 8 && r <= 25);
2651 }
2652
2653
2654 /* Worker function for `INIT_CUMULATIVE_ARGS'. */
2655 /* Initializing the variable cum for the state at the beginning
2656 of the argument list. */
2657
2658 void
2659 avr_init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
2660 tree fndecl ATTRIBUTE_UNUSED)
2661 {
2662 cum->nregs = AVR_TINY ? 6 : 18;
2663 cum->regno = FIRST_CUM_REG;
2664 if (!libname && stdarg_p (fntype))
2665 cum->nregs = 0;
2666
2667 /* Assume the calle may be tail called */
2668
2669 cfun->machine->sibcall_fails = 0;
2670 }
2671
2672 /* Returns the number of registers to allocate for a function argument. */
2673
2674 static int
2675 avr_num_arg_regs (machine_mode mode, const_tree type)
2676 {
2677 int size;
2678
2679 if (mode == BLKmode)
2680 size = int_size_in_bytes (type);
2681 else
2682 size = GET_MODE_SIZE (mode);
2683
2684 /* Align all function arguments to start in even-numbered registers.
2685 Odd-sized arguments leave holes above them. */
2686
2687 return (size + 1) & ~1;
2688 }
2689
2690
2691 /* Implement `TARGET_FUNCTION_ARG'. */
2692 /* Controls whether a function argument is passed
2693 in a register, and which register. */
2694
2695 static rtx
2696 avr_function_arg (cumulative_args_t cum_v, machine_mode mode,
2697 const_tree type, bool named ATTRIBUTE_UNUSED)
2698 {
2699 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2700 int bytes = avr_num_arg_regs (mode, type);
2701
2702 if (cum->nregs && bytes <= cum->nregs)
2703 return gen_rtx_REG (mode, cum->regno - bytes);
2704
2705 return NULL_RTX;
2706 }
2707
2708
2709 /* Implement `TARGET_FUNCTION_ARG_ADVANCE'. */
2710 /* Update the summarizer variable CUM to advance past an argument
2711 in the argument list. */
2712
2713 static void
2714 avr_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
2715 const_tree type, bool named ATTRIBUTE_UNUSED)
2716 {
2717 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2718 int bytes = avr_num_arg_regs (mode, type);
2719
2720 cum->nregs -= bytes;
2721 cum->regno -= bytes;
2722
2723 /* A parameter is being passed in a call-saved register. As the original
2724 contents of these regs has to be restored before leaving the function,
2725 a function must not pass arguments in call-saved regs in order to get
2726 tail-called. */
2727
2728 if (cum->regno >= 8
2729 && cum->nregs >= 0
2730 && !call_used_regs[cum->regno])
2731 {
2732 /* FIXME: We ship info on failing tail-call in struct machine_function.
2733 This uses internals of calls.c:expand_call() and the way args_so_far
2734 is used. targetm.function_ok_for_sibcall() needs to be extended to
2735 pass &args_so_far, too. At present, CUMULATIVE_ARGS is target
2736 dependent so that such an extension is not wanted. */
2737
2738 cfun->machine->sibcall_fails = 1;
2739 }
2740
2741 /* Test if all registers needed by the ABI are actually available. If the
2742 user has fixed a GPR needed to pass an argument, an (implicit) function
2743 call will clobber that fixed register. See PR45099 for an example. */
2744
2745 if (cum->regno >= 8
2746 && cum->nregs >= 0)
2747 {
2748 int regno;
2749
2750 for (regno = cum->regno; regno < cum->regno + bytes; regno++)
2751 if (fixed_regs[regno])
2752 warning (0, "fixed register %s used to pass parameter to function",
2753 reg_names[regno]);
2754 }
2755
2756 if (cum->nregs <= 0)
2757 {
2758 cum->nregs = 0;
2759 cum->regno = FIRST_CUM_REG;
2760 }
2761 }
2762
2763 /* Implement `TARGET_FUNCTION_OK_FOR_SIBCALL' */
2764 /* Decide whether we can make a sibling call to a function. DECL is the
2765 declaration of the function being targeted by the call and EXP is the
2766 CALL_EXPR representing the call. */
2767
2768 static bool
2769 avr_function_ok_for_sibcall (tree decl_callee, tree exp_callee)
2770 {
2771 tree fntype_callee;
2772
2773 /* Tail-calling must fail if callee-saved regs are used to pass
2774 function args. We must not tail-call when `epilogue_restores'
2775 is used. Unfortunately, we cannot tell at this point if that
2776 actually will happen or not, and we cannot step back from
2777 tail-calling. Thus, we inhibit tail-calling with -mcall-prologues. */
2778
2779 if (cfun->machine->sibcall_fails
2780 || TARGET_CALL_PROLOGUES)
2781 {
2782 return false;
2783 }
2784
2785 fntype_callee = TREE_TYPE (CALL_EXPR_FN (exp_callee));
2786
2787 if (decl_callee)
2788 {
2789 decl_callee = TREE_TYPE (decl_callee);
2790 }
2791 else
2792 {
2793 decl_callee = fntype_callee;
2794
2795 while (FUNCTION_TYPE != TREE_CODE (decl_callee)
2796 && METHOD_TYPE != TREE_CODE (decl_callee))
2797 {
2798 decl_callee = TREE_TYPE (decl_callee);
2799 }
2800 }
2801
2802 /* Ensure that caller and callee have compatible epilogues */
2803
2804 if (cfun->machine->is_interrupt
2805 || cfun->machine->is_signal
2806 || cfun->machine->is_naked
2807 || avr_naked_function_p (decl_callee)
2808 /* FIXME: For OS_task and OS_main, this might be over-conservative. */
2809 || (avr_OS_task_function_p (decl_callee)
2810 != cfun->machine->is_OS_task)
2811 || (avr_OS_main_function_p (decl_callee)
2812 != cfun->machine->is_OS_main))
2813 {
2814 return false;
2815 }
2816
2817 return true;
2818 }
2819
2820 /***********************************************************************
2821 Functions for outputting various mov's for a various modes
2822 ************************************************************************/
2823
2824 /* Return true if a value of mode MODE is read from flash by
2825 __load_* function from libgcc. */
2826
2827 bool
2828 avr_load_libgcc_p (rtx op)
2829 {
2830 machine_mode mode = GET_MODE (op);
2831 int n_bytes = GET_MODE_SIZE (mode);
2832
2833 return (n_bytes > 2
2834 && !AVR_HAVE_LPMX
2835 && avr_mem_flash_p (op));
2836 }
2837
2838 /* Return true if a value of mode MODE is read by __xload_* function. */
2839
2840 bool
2841 avr_xload_libgcc_p (machine_mode mode)
2842 {
2843 int n_bytes = GET_MODE_SIZE (mode);
2844
2845 return (n_bytes > 1
2846 || avr_n_flash > 1);
2847 }
2848
2849
2850 /* Fixme: This is a hack because secondary reloads don't works as expected.
2851
2852 Find an unused d-register to be used as scratch in INSN.
2853 EXCLUDE is either NULL_RTX or some register. In the case where EXCLUDE
2854 is a register, skip all possible return values that overlap EXCLUDE.
2855 The policy for the returned register is similar to that of
2856 `reg_unused_after', i.e. the returned register may overlap the SET_DEST
2857 of INSN.
2858
2859 Return a QImode d-register or NULL_RTX if nothing found. */
2860
2861 static rtx
2862 avr_find_unused_d_reg (rtx_insn *insn, rtx exclude)
2863 {
2864 int regno;
2865 bool isr_p = (avr_interrupt_function_p (current_function_decl)
2866 || avr_signal_function_p (current_function_decl));
2867
2868 for (regno = 16; regno < 32; regno++)
2869 {
2870 rtx reg = all_regs_rtx[regno];
2871
2872 if ((exclude
2873 && reg_overlap_mentioned_p (exclude, reg))
2874 || fixed_regs[regno])
2875 {
2876 continue;
2877 }
2878
2879 /* Try non-live register */
2880
2881 if (!df_regs_ever_live_p (regno)
2882 && (TREE_THIS_VOLATILE (current_function_decl)
2883 || cfun->machine->is_OS_task
2884 || cfun->machine->is_OS_main
2885 || (!isr_p && call_used_regs[regno])))
2886 {
2887 return reg;
2888 }
2889
2890 /* Any live register can be used if it is unused after.
2891 Prologue/epilogue will care for it as needed. */
2892
2893 if (df_regs_ever_live_p (regno)
2894 && reg_unused_after (insn, reg))
2895 {
2896 return reg;
2897 }
2898 }
2899
2900 return NULL_RTX;
2901 }
2902
2903
2904 /* Helper function for the next function in the case where only restricted
2905 version of LPM instruction is available. */
2906
2907 static const char*
2908 avr_out_lpm_no_lpmx (rtx_insn *insn, rtx *xop, int *plen)
2909 {
2910 rtx dest = xop[0];
2911 rtx addr = xop[1];
2912 int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
2913 int regno_dest;
2914
2915 regno_dest = REGNO (dest);
2916
2917 /* The implicit target register of LPM. */
2918 xop[3] = lpm_reg_rtx;
2919
2920 switch (GET_CODE (addr))
2921 {
2922 default:
2923 gcc_unreachable();
2924
2925 case REG:
2926
2927 gcc_assert (REG_Z == REGNO (addr));
2928
2929 switch (n_bytes)
2930 {
2931 default:
2932 gcc_unreachable();
2933
2934 case 1:
2935 avr_asm_len ("%4lpm", xop, plen, 1);
2936
2937 if (regno_dest != LPM_REGNO)
2938 avr_asm_len ("mov %0,%3", xop, plen, 1);
2939
2940 return "";
2941
2942 case 2:
2943 if (REGNO (dest) == REG_Z)
2944 return avr_asm_len ("%4lpm" CR_TAB
2945 "push %3" CR_TAB
2946 "adiw %2,1" CR_TAB
2947 "%4lpm" CR_TAB
2948 "mov %B0,%3" CR_TAB
2949 "pop %A0", xop, plen, 6);
2950
2951 avr_asm_len ("%4lpm" CR_TAB
2952 "mov %A0,%3" CR_TAB
2953 "adiw %2,1" CR_TAB
2954 "%4lpm" CR_TAB
2955 "mov %B0,%3", xop, plen, 5);
2956
2957 if (!reg_unused_after (insn, addr))
2958 avr_asm_len ("sbiw %2,1", xop, plen, 1);
2959
2960 break; /* 2 */
2961 }
2962
2963 break; /* REG */
2964
2965 case POST_INC:
2966
2967 gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
2968 && n_bytes <= 4);
2969
2970 if (regno_dest == LPM_REGNO)
2971 avr_asm_len ("%4lpm" CR_TAB
2972 "adiw %2,1", xop, plen, 2);
2973 else
2974 avr_asm_len ("%4lpm" CR_TAB
2975 "mov %A0,%3" CR_TAB
2976 "adiw %2,1", xop, plen, 3);
2977
2978 if (n_bytes >= 2)
2979 avr_asm_len ("%4lpm" CR_TAB
2980 "mov %B0,%3" CR_TAB
2981 "adiw %2,1", xop, plen, 3);
2982
2983 if (n_bytes >= 3)
2984 avr_asm_len ("%4lpm" CR_TAB
2985 "mov %C0,%3" CR_TAB
2986 "adiw %2,1", xop, plen, 3);
2987
2988 if (n_bytes >= 4)
2989 avr_asm_len ("%4lpm" CR_TAB
2990 "mov %D0,%3" CR_TAB
2991 "adiw %2,1", xop, plen, 3);
2992
2993 break; /* POST_INC */
2994
2995 } /* switch CODE (addr) */
2996
2997 return "";
2998 }
2999
3000
3001 /* If PLEN == NULL: Ouput instructions to load a value from a memory location
3002 OP[1] in AS1 to register OP[0].
3003 If PLEN != 0 set *PLEN to the length in words of the instruction sequence.
3004 Return "". */
3005
3006 const char*
3007 avr_out_lpm (rtx_insn *insn, rtx *op, int *plen)
3008 {
3009 rtx xop[7];
3010 rtx dest = op[0];
3011 rtx src = SET_SRC (single_set (insn));
3012 rtx addr;
3013 int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
3014 int segment;
3015 RTX_CODE code;
3016 addr_space_t as = MEM_ADDR_SPACE (src);
3017
3018 if (plen)
3019 *plen = 0;
3020
3021 if (MEM_P (dest))
3022 {
3023 warning (0, "writing to address space %qs not supported",
3024 avr_addrspace[MEM_ADDR_SPACE (dest)].name);
3025
3026 return "";
3027 }
3028
3029 addr = XEXP (src, 0);
3030 code = GET_CODE (addr);
3031
3032 gcc_assert (REG_P (dest));
3033 gcc_assert (REG == code || POST_INC == code);
3034
3035 xop[0] = dest;
3036 xop[1] = addr;
3037 xop[2] = lpm_addr_reg_rtx;
3038 xop[4] = xstring_empty;
3039 xop[5] = tmp_reg_rtx;
3040 xop[6] = XEXP (rampz_rtx, 0);
3041
3042 segment = avr_addrspace[as].segment;
3043
3044 /* Set RAMPZ as needed. */
3045
3046 if (segment)
3047 {
3048 xop[4] = GEN_INT (segment);
3049 xop[3] = avr_find_unused_d_reg (insn, lpm_addr_reg_rtx);
3050
3051 if (xop[3] != NULL_RTX)
3052 {
3053 avr_asm_len ("ldi %3,%4" CR_TAB
3054 "out %i6,%3", xop, plen, 2);
3055 }
3056 else if (segment == 1)
3057 {
3058 avr_asm_len ("clr %5" CR_TAB
3059 "inc %5" CR_TAB
3060 "out %i6,%5", xop, plen, 3);
3061 }
3062 else
3063 {
3064 avr_asm_len ("mov %5,%2" CR_TAB
3065 "ldi %2,%4" CR_TAB
3066 "out %i6,%2" CR_TAB
3067 "mov %2,%5", xop, plen, 4);
3068 }
3069
3070 xop[4] = xstring_e;
3071
3072 if (!AVR_HAVE_ELPMX)
3073 return avr_out_lpm_no_lpmx (insn, xop, plen);
3074 }
3075 else if (!AVR_HAVE_LPMX)
3076 {
3077 return avr_out_lpm_no_lpmx (insn, xop, plen);
3078 }
3079
3080 /* We have [E]LPMX: Output reading from Flash the comfortable way. */
3081
3082 switch (GET_CODE (addr))
3083 {
3084 default:
3085 gcc_unreachable();
3086
3087 case REG:
3088
3089 gcc_assert (REG_Z == REGNO (addr));
3090
3091 switch (n_bytes)
3092 {
3093 default:
3094 gcc_unreachable();
3095
3096 case 1:
3097 return avr_asm_len ("%4lpm %0,%a2", xop, plen, 1);
3098
3099 case 2:
3100 if (REGNO (dest) == REG_Z)
3101 return avr_asm_len ("%4lpm %5,%a2+" CR_TAB
3102 "%4lpm %B0,%a2" CR_TAB
3103 "mov %A0,%5", xop, plen, 3);
3104 else
3105 {
3106 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3107 "%4lpm %B0,%a2", xop, plen, 2);
3108
3109 if (!reg_unused_after (insn, addr))
3110 avr_asm_len ("sbiw %2,1", xop, plen, 1);
3111 }
3112
3113 break; /* 2 */
3114
3115 case 3:
3116
3117 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3118 "%4lpm %B0,%a2+" CR_TAB
3119 "%4lpm %C0,%a2", xop, plen, 3);
3120
3121 if (!reg_unused_after (insn, addr))
3122 avr_asm_len ("sbiw %2,2", xop, plen, 1);
3123
3124 break; /* 3 */
3125
3126 case 4:
3127
3128 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3129 "%4lpm %B0,%a2+", xop, plen, 2);
3130
3131 if (REGNO (dest) == REG_Z - 2)
3132 return avr_asm_len ("%4lpm %5,%a2+" CR_TAB
3133 "%4lpm %C0,%a2" CR_TAB
3134 "mov %D0,%5", xop, plen, 3);
3135 else
3136 {
3137 avr_asm_len ("%4lpm %C0,%a2+" CR_TAB
3138 "%4lpm %D0,%a2", xop, plen, 2);
3139
3140 if (!reg_unused_after (insn, addr))
3141 avr_asm_len ("sbiw %2,3", xop, plen, 1);
3142 }
3143
3144 break; /* 4 */
3145 } /* n_bytes */
3146
3147 break; /* REG */
3148
3149 case POST_INC:
3150
3151 gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
3152 && n_bytes <= 4);
3153
3154 avr_asm_len ("%4lpm %A0,%a2+", xop, plen, 1);
3155 if (n_bytes >= 2) avr_asm_len ("%4lpm %B0,%a2+", xop, plen, 1);
3156 if (n_bytes >= 3) avr_asm_len ("%4lpm %C0,%a2+", xop, plen, 1);
3157 if (n_bytes >= 4) avr_asm_len ("%4lpm %D0,%a2+", xop, plen, 1);
3158
3159 break; /* POST_INC */
3160
3161 } /* switch CODE (addr) */
3162
3163 if (xop[4] == xstring_e && AVR_HAVE_RAMPD)
3164 {
3165 /* Reset RAMPZ to 0 so that EBI devices don't read garbage from RAM. */
3166
3167 xop[0] = zero_reg_rtx;
3168 avr_asm_len ("out %i6,%0", xop, plen, 1);
3169 }
3170
3171 return "";
3172 }
3173
3174
3175 /* Worker function for xload_8 insn. */
3176
3177 const char*
3178 avr_out_xload (rtx_insn *insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
3179 {
3180 rtx xop[4];
3181
3182 xop[0] = op[0];
3183 xop[1] = op[1];
3184 xop[2] = lpm_addr_reg_rtx;
3185 xop[3] = AVR_HAVE_LPMX ? op[0] : lpm_reg_rtx;
3186
3187 avr_asm_len (AVR_HAVE_LPMX ? "lpm %3,%a2" : "lpm", xop, plen, -1);
3188
3189 avr_asm_len ("sbrc %1,7" CR_TAB
3190 "ld %3,%a2", xop, plen, 2);
3191
3192 if (REGNO (xop[0]) != REGNO (xop[3]))
3193 avr_asm_len ("mov %0,%3", xop, plen, 1);
3194
3195 return "";
3196 }
3197
3198
3199 /* AVRTC-579
3200 If OP is a symbol or a constant expression with value > 0xbf
3201 return FALSE, otherwise TRUE.
3202 This check is used to avoid LDS / STS instruction with invalid memory
3203 access range (valid range 0x40..0xbf). For I/O operand range 0x0..0x3f,
3204 IN / OUT instruction will be generated. */
3205
3206 bool
3207 tiny_valid_direct_memory_access_range (rtx op, machine_mode mode)
3208 {
3209 rtx x;
3210
3211 if (!AVR_TINY)
3212 return true;
3213
3214 x = XEXP (op,0);
3215
3216 if (MEM_P (op) && x && GET_CODE (x) == SYMBOL_REF)
3217 {
3218 return false;
3219 }
3220
3221 if (MEM_P (op) && x && (CONSTANT_ADDRESS_P (x))
3222 && !(IN_RANGE (INTVAL (x), 0, 0xC0 - GET_MODE_SIZE (mode))))
3223 {
3224 return false;
3225 }
3226
3227 return true;
3228 }
3229
3230 const char*
3231 output_movqi (rtx_insn *insn, rtx operands[], int *plen)
3232 {
3233 rtx dest = operands[0];
3234 rtx src = operands[1];
3235
3236 if (avr_mem_flash_p (src)
3237 || avr_mem_flash_p (dest))
3238 {
3239 return avr_out_lpm (insn, operands, plen);
3240 }
3241
3242 gcc_assert (1 == GET_MODE_SIZE (GET_MODE (dest)));
3243
3244 if (REG_P (dest))
3245 {
3246 if (REG_P (src)) /* mov r,r */
3247 {
3248 if (test_hard_reg_class (STACK_REG, dest))
3249 return avr_asm_len ("out %0,%1", operands, plen, -1);
3250 else if (test_hard_reg_class (STACK_REG, src))
3251 return avr_asm_len ("in %0,%1", operands, plen, -1);
3252
3253 return avr_asm_len ("mov %0,%1", operands, plen, -1);
3254 }
3255 else if (CONSTANT_P (src))
3256 {
3257 output_reload_in_const (operands, NULL_RTX, plen, false);
3258 return "";
3259 }
3260 else if (MEM_P (src))
3261 return out_movqi_r_mr (insn, operands, plen); /* mov r,m */
3262 }
3263 else if (MEM_P (dest))
3264 {
3265 rtx xop[2];
3266
3267 xop[0] = dest;
3268 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
3269
3270 return out_movqi_mr_r (insn, xop, plen);
3271 }
3272
3273 return "";
3274 }
3275
3276
3277 const char *
3278 output_movhi (rtx_insn *insn, rtx xop[], int *plen)
3279 {
3280 rtx dest = xop[0];
3281 rtx src = xop[1];
3282
3283 gcc_assert (GET_MODE_SIZE (GET_MODE (dest)) == 2);
3284
3285 if (avr_mem_flash_p (src)
3286 || avr_mem_flash_p (dest))
3287 {
3288 return avr_out_lpm (insn, xop, plen);
3289 }
3290
3291 gcc_assert (2 == GET_MODE_SIZE (GET_MODE (dest)));
3292
3293 if (REG_P (dest))
3294 {
3295 if (REG_P (src)) /* mov r,r */
3296 {
3297 if (test_hard_reg_class (STACK_REG, dest))
3298 {
3299 if (AVR_HAVE_8BIT_SP)
3300 return avr_asm_len ("out __SP_L__,%A1", xop, plen, -1);
3301
3302 if (AVR_XMEGA)
3303 return avr_asm_len ("out __SP_L__,%A1" CR_TAB
3304 "out __SP_H__,%B1", xop, plen, -2);
3305
3306 /* Use simple load of SP if no interrupts are used. */
3307
3308 return TARGET_NO_INTERRUPTS
3309 ? avr_asm_len ("out __SP_H__,%B1" CR_TAB
3310 "out __SP_L__,%A1", xop, plen, -2)
3311 : avr_asm_len ("in __tmp_reg__,__SREG__" CR_TAB
3312 "cli" CR_TAB
3313 "out __SP_H__,%B1" CR_TAB
3314 "out __SREG__,__tmp_reg__" CR_TAB
3315 "out __SP_L__,%A1", xop, plen, -5);
3316 }
3317 else if (test_hard_reg_class (STACK_REG, src))
3318 {
3319 return !AVR_HAVE_SPH
3320 ? avr_asm_len ("in %A0,__SP_L__" CR_TAB
3321 "clr %B0", xop, plen, -2)
3322
3323 : avr_asm_len ("in %A0,__SP_L__" CR_TAB
3324 "in %B0,__SP_H__", xop, plen, -2);
3325 }
3326
3327 return AVR_HAVE_MOVW
3328 ? avr_asm_len ("movw %0,%1", xop, plen, -1)
3329
3330 : avr_asm_len ("mov %A0,%A1" CR_TAB
3331 "mov %B0,%B1", xop, plen, -2);
3332 } /* REG_P (src) */
3333 else if (CONSTANT_P (src))
3334 {
3335 return output_reload_inhi (xop, NULL, plen);
3336 }
3337 else if (MEM_P (src))
3338 {
3339 return out_movhi_r_mr (insn, xop, plen); /* mov r,m */
3340 }
3341 }
3342 else if (MEM_P (dest))
3343 {
3344 rtx xop[2];
3345
3346 xop[0] = dest;
3347 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
3348
3349 return out_movhi_mr_r (insn, xop, plen);
3350 }
3351
3352 fatal_insn ("invalid insn:", insn);
3353
3354 return "";
3355 }
3356
3357
3358 /* Same as out_movqi_r_mr, but TINY does not have ADIW or SBIW */
3359
3360 static const char*
3361 avr_out_movqi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
3362 {
3363 rtx dest = op[0];
3364 rtx src = op[1];
3365 rtx x = XEXP (src, 0);
3366
3367 avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3368 "ld %0,%b1" , op, plen, -3);
3369
3370 if (!reg_overlap_mentioned_p (dest, XEXP (x,0))
3371 && !reg_unused_after (insn, XEXP (x,0)))
3372 avr_asm_len (TINY_SBIW (%I1, %J1, %o1), op, plen, 2);
3373
3374 return "";
3375 }
3376
3377 static const char*
3378 out_movqi_r_mr (rtx_insn *insn, rtx op[], int *plen)
3379 {
3380 rtx dest = op[0];
3381 rtx src = op[1];
3382 rtx x = XEXP (src, 0);
3383
3384 if (CONSTANT_ADDRESS_P (x))
3385 {
3386 int n_words = AVR_TINY ? 1 : 2;
3387 return optimize > 0 && io_address_operand (x, QImode)
3388 ? avr_asm_len ("in %0,%i1", op, plen, -1)
3389 : avr_asm_len ("lds %0,%m1", op, plen, -n_words);
3390 }
3391
3392 if (GET_CODE (x) == PLUS
3393 && REG_P (XEXP (x, 0))
3394 && CONST_INT_P (XEXP (x, 1)))
3395 {
3396 /* memory access by reg+disp */
3397
3398 int disp = INTVAL (XEXP (x, 1));
3399
3400 if (AVR_TINY)
3401 return avr_out_movqi_r_mr_reg_disp_tiny (insn, op, plen);
3402
3403 if (disp - GET_MODE_SIZE (GET_MODE (src)) >= 63)
3404 {
3405 if (REGNO (XEXP (x, 0)) != REG_Y)
3406 fatal_insn ("incorrect insn:",insn);
3407
3408 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
3409 return avr_asm_len ("adiw r28,%o1-63" CR_TAB
3410 "ldd %0,Y+63" CR_TAB
3411 "sbiw r28,%o1-63", op, plen, -3);
3412
3413 return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
3414 "sbci r29,hi8(-%o1)" CR_TAB
3415 "ld %0,Y" CR_TAB
3416 "subi r28,lo8(%o1)" CR_TAB
3417 "sbci r29,hi8(%o1)", op, plen, -5);
3418 }
3419 else if (REGNO (XEXP (x, 0)) == REG_X)
3420 {
3421 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
3422 it but I have this situation with extremal optimizing options. */
3423
3424 avr_asm_len ("adiw r26,%o1" CR_TAB
3425 "ld %0,X", op, plen, -2);
3426
3427 if (!reg_overlap_mentioned_p (dest, XEXP (x,0))
3428 && !reg_unused_after (insn, XEXP (x,0)))
3429 {
3430 avr_asm_len ("sbiw r26,%o1", op, plen, 1);
3431 }
3432
3433 return "";
3434 }
3435
3436 return avr_asm_len ("ldd %0,%1", op, plen, -1);
3437 }
3438
3439 return avr_asm_len ("ld %0,%1", op, plen, -1);
3440 }
3441
3442
3443 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
3444
3445 static const char*
3446 avr_out_movhi_r_mr_reg_no_disp_tiny (rtx op[], int *plen)
3447 {
3448 rtx dest = op[0];
3449 rtx src = op[1];
3450 rtx base = XEXP (src, 0);
3451
3452 int reg_dest = true_regnum (dest);
3453 int reg_base = true_regnum (base);
3454
3455 if (reg_dest == reg_base) /* R = (R) */
3456 return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
3457 "ld %B0,%1" CR_TAB
3458 "mov %A0,__tmp_reg__", op, plen, -3);
3459
3460 return avr_asm_len ("ld %A0,%1" CR_TAB
3461 TINY_ADIW (%E1, %F1, 1) CR_TAB
3462 "ld %B0,%1" CR_TAB
3463 TINY_SBIW (%E1, %F1, 1), op, plen, -6);
3464 }
3465
3466
3467 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
3468
3469 static const char*
3470 avr_out_movhi_r_mr_reg_disp_tiny (rtx op[], int *plen)
3471 {
3472 rtx dest = op[0];
3473 rtx src = op[1];
3474 rtx base = XEXP (src, 0);
3475
3476 int reg_dest = true_regnum (dest);
3477 int reg_base = true_regnum (XEXP (base, 0));
3478
3479 if (reg_base == reg_dest)
3480 {
3481 return avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3482 "ld __tmp_reg__,%b1+" CR_TAB
3483 "ld %B0,%b1" CR_TAB
3484 "mov %A0,__tmp_reg__", op, plen, -5);
3485 }
3486 else
3487 {
3488 return avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3489 "ld %A0,%b1+" CR_TAB
3490 "ld %B0,%b1" CR_TAB
3491 TINY_SBIW (%I1, %J1, %o1+1), op, plen, -6);
3492 }
3493 }
3494
3495
3496 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
3497
3498 static const char*
3499 avr_out_movhi_r_mr_pre_dec_tiny (rtx_insn *insn, rtx op[], int *plen)
3500 {
3501 int mem_volatile_p = 0;
3502 rtx dest = op[0];
3503 rtx src = op[1];
3504 rtx base = XEXP (src, 0);
3505
3506 /* "volatile" forces reading low byte first, even if less efficient,
3507 for correct operation with 16-bit I/O registers. */
3508 mem_volatile_p = MEM_VOLATILE_P (src);
3509
3510 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3511 fatal_insn ("incorrect insn:", insn);
3512
3513 if (!mem_volatile_p)
3514 return avr_asm_len ("ld %B0,%1" CR_TAB
3515 "ld %A0,%1", op, plen, -2);
3516
3517 return avr_asm_len (TINY_SBIW (%I1, %J1, 2) CR_TAB
3518 "ld %A0,%p1+" CR_TAB
3519 "ld %B0,%p1" CR_TAB
3520 TINY_SBIW (%I1, %J1, 1), op, plen, -6);
3521 }
3522
3523
3524 static const char*
3525 out_movhi_r_mr (rtx_insn *insn, rtx op[], int *plen)
3526 {
3527 rtx dest = op[0];
3528 rtx src = op[1];
3529 rtx base = XEXP (src, 0);
3530 int reg_dest = true_regnum (dest);
3531 int reg_base = true_regnum (base);
3532 /* "volatile" forces reading low byte first, even if less efficient,
3533 for correct operation with 16-bit I/O registers. */
3534 int mem_volatile_p = MEM_VOLATILE_P (src);
3535
3536 if (reg_base > 0)
3537 {
3538 if (AVR_TINY)
3539 return avr_out_movhi_r_mr_reg_no_disp_tiny (op, plen);
3540
3541 if (reg_dest == reg_base) /* R = (R) */
3542 return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
3543 "ld %B0,%1" CR_TAB
3544 "mov %A0,__tmp_reg__", op, plen, -3);
3545
3546 if (reg_base != REG_X)
3547 return avr_asm_len ("ld %A0,%1" CR_TAB
3548 "ldd %B0,%1+1", op, plen, -2);
3549
3550 avr_asm_len ("ld %A0,X+" CR_TAB
3551 "ld %B0,X", op, plen, -2);
3552
3553 if (!reg_unused_after (insn, base))
3554 avr_asm_len ("sbiw r26,1", op, plen, 1);
3555
3556 return "";
3557 }
3558 else if (GET_CODE (base) == PLUS) /* (R + i) */
3559 {
3560 int disp = INTVAL (XEXP (base, 1));
3561 int reg_base = true_regnum (XEXP (base, 0));
3562
3563 if (AVR_TINY)
3564 return avr_out_movhi_r_mr_reg_disp_tiny (op, plen);
3565
3566 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3567 {
3568 if (REGNO (XEXP (base, 0)) != REG_Y)
3569 fatal_insn ("incorrect insn:",insn);
3570
3571 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (src))
3572 ? avr_asm_len ("adiw r28,%o1-62" CR_TAB
3573 "ldd %A0,Y+62" CR_TAB
3574 "ldd %B0,Y+63" CR_TAB
3575 "sbiw r28,%o1-62", op, plen, -4)
3576
3577 : avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
3578 "sbci r29,hi8(-%o1)" CR_TAB
3579 "ld %A0,Y" CR_TAB
3580 "ldd %B0,Y+1" CR_TAB
3581 "subi r28,lo8(%o1)" CR_TAB
3582 "sbci r29,hi8(%o1)", op, plen, -6);
3583 }
3584
3585 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
3586 it but I have this situation with extremal
3587 optimization options. */
3588
3589 if (reg_base == REG_X)
3590 return reg_base == reg_dest
3591 ? avr_asm_len ("adiw r26,%o1" CR_TAB
3592 "ld __tmp_reg__,X+" CR_TAB
3593 "ld %B0,X" CR_TAB
3594 "mov %A0,__tmp_reg__", op, plen, -4)
3595
3596 : avr_asm_len ("adiw r26,%o1" CR_TAB
3597 "ld %A0,X+" CR_TAB
3598 "ld %B0,X" CR_TAB
3599 "sbiw r26,%o1+1", op, plen, -4);
3600
3601 return reg_base == reg_dest
3602 ? avr_asm_len ("ldd __tmp_reg__,%A1" CR_TAB
3603 "ldd %B0,%B1" CR_TAB
3604 "mov %A0,__tmp_reg__", op, plen, -3)
3605
3606 : avr_asm_len ("ldd %A0,%A1" CR_TAB
3607 "ldd %B0,%B1", op, plen, -2);
3608 }
3609 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3610 {
3611 if (AVR_TINY)
3612 return avr_out_movhi_r_mr_pre_dec_tiny (insn, op, plen);
3613
3614 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3615 fatal_insn ("incorrect insn:", insn);
3616
3617 if (!mem_volatile_p)
3618 return avr_asm_len ("ld %B0,%1" CR_TAB
3619 "ld %A0,%1", op, plen, -2);
3620
3621 return REGNO (XEXP (base, 0)) == REG_X
3622 ? avr_asm_len ("sbiw r26,2" CR_TAB
3623 "ld %A0,X+" CR_TAB
3624 "ld %B0,X" CR_TAB
3625 "sbiw r26,1", op, plen, -4)
3626
3627 : avr_asm_len ("sbiw %r1,2" CR_TAB
3628 "ld %A0,%p1" CR_TAB
3629 "ldd %B0,%p1+1", op, plen, -3);
3630 }
3631 else if (GET_CODE (base) == POST_INC) /* (R++) */
3632 {
3633 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3634 fatal_insn ("incorrect insn:", insn);
3635
3636 return avr_asm_len ("ld %A0,%1" CR_TAB
3637 "ld %B0,%1", op, plen, -2);
3638 }
3639 else if (CONSTANT_ADDRESS_P (base))
3640 {
3641 int n_words = AVR_TINY ? 2 : 4;
3642 return optimize > 0 && io_address_operand (base, HImode)
3643 ? avr_asm_len ("in %A0,%i1" CR_TAB
3644 "in %B0,%i1+1", op, plen, -2)
3645
3646 : avr_asm_len ("lds %A0,%m1" CR_TAB
3647 "lds %B0,%m1+1", op, plen, -n_words);
3648 }
3649
3650 fatal_insn ("unknown move insn:",insn);
3651 return "";
3652 }
3653
3654 static const char*
3655 avr_out_movsi_r_mr_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *l)
3656 {
3657 rtx dest = op[0];
3658 rtx src = op[1];
3659 rtx base = XEXP (src, 0);
3660 int reg_dest = true_regnum (dest);
3661 int reg_base = true_regnum (base);
3662
3663 if (reg_dest == reg_base)
3664 {
3665 /* "ld r26,-X" is undefined */
3666 return *l = 9, (TINY_ADIW (%E1, %F1, 3) CR_TAB
3667 "ld %D0,%1" CR_TAB
3668 "ld %C0,-%1" CR_TAB
3669 "ld __tmp_reg__,-%1" CR_TAB
3670 TINY_SBIW (%E1, %F1, 1) CR_TAB
3671 "ld %A0,%1" CR_TAB
3672 "mov %B0,__tmp_reg__");
3673 }
3674 else if (reg_dest == reg_base - 2)
3675 {
3676 return *l = 5, ("ld %A0,%1+" CR_TAB
3677 "ld %B0,%1+" CR_TAB
3678 "ld __tmp_reg__,%1+" CR_TAB
3679 "ld %D0,%1" CR_TAB
3680 "mov %C0,__tmp_reg__");
3681 }
3682 else if (reg_unused_after (insn, base))
3683 {
3684 return *l = 4, ("ld %A0,%1+" CR_TAB
3685 "ld %B0,%1+" CR_TAB
3686 "ld %C0,%1+" CR_TAB
3687 "ld %D0,%1");
3688 }
3689 else
3690 {
3691 return *l = 6, ("ld %A0,%1+" CR_TAB
3692 "ld %B0,%1+" CR_TAB
3693 "ld %C0,%1+" CR_TAB
3694 "ld %D0,%1" CR_TAB
3695 TINY_SBIW (%E1, %F1, 3));
3696 }
3697 }
3698
3699
3700 static const char*
3701 avr_out_movsi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *l)
3702 {
3703 rtx dest = op[0];
3704 rtx src = op[1];
3705 rtx base = XEXP (src, 0);
3706 int reg_dest = true_regnum (dest);
3707 int reg_base = true_regnum (XEXP (base, 0));
3708
3709 if (reg_dest == reg_base)
3710 {
3711 /* "ld r26,-X" is undefined */
3712 return *l = 9, (TINY_ADIW (%I1, %J1, %o1+3) CR_TAB
3713 "ld %D0,%b1" CR_TAB
3714 "ld %C0,-%b1" CR_TAB
3715 "ld __tmp_reg__,-%b1" CR_TAB
3716 TINY_SBIW (%I1, %J1, 1) CR_TAB
3717 "ld %A0,%b1" CR_TAB
3718 "mov %B0,__tmp_reg__");
3719 }
3720 else if (reg_dest == reg_base - 2)
3721 {
3722 return *l = 7, (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3723 "ld %A0,%b1+" CR_TAB
3724 "ld %B0,%b1+" CR_TAB
3725 "ld __tmp_reg__,%b1+" CR_TAB
3726 "ld %D0,%b1" CR_TAB
3727 "mov %C0,__tmp_reg__");
3728 }
3729 else if (reg_unused_after (insn, XEXP (base, 0)))
3730 {
3731 return *l = 6, (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3732 "ld %A0,%b1+" CR_TAB
3733 "ld %B0,%b1+" CR_TAB
3734 "ld %C0,%b1+" CR_TAB
3735 "ld %D0,%b1");
3736 }
3737 else
3738 {
3739 return *l = 8, (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3740 "ld %A0,%b1+" CR_TAB
3741 "ld %B0,%b1+" CR_TAB
3742 "ld %C0,%b1+" CR_TAB
3743 "ld %D0,%b1" CR_TAB
3744 TINY_SBIW (%I1, %J1, %o1+3));
3745 }
3746 }
3747
3748 static const char*
3749 out_movsi_r_mr (rtx_insn *insn, rtx op[], int *l)
3750 {
3751 rtx dest = op[0];
3752 rtx src = op[1];
3753 rtx base = XEXP (src, 0);
3754 int reg_dest = true_regnum (dest);
3755 int reg_base = true_regnum (base);
3756 int tmp;
3757
3758 if (!l)
3759 l = &tmp;
3760
3761 if (reg_base > 0)
3762 {
3763 if (AVR_TINY)
3764 return avr_out_movsi_r_mr_reg_no_disp_tiny (insn, op, l);
3765
3766 if (reg_base == REG_X) /* (R26) */
3767 {
3768 if (reg_dest == REG_X)
3769 /* "ld r26,-X" is undefined */
3770 return *l=7, ("adiw r26,3" CR_TAB
3771 "ld r29,X" CR_TAB
3772 "ld r28,-X" CR_TAB
3773 "ld __tmp_reg__,-X" CR_TAB
3774 "sbiw r26,1" CR_TAB
3775 "ld r26,X" CR_TAB
3776 "mov r27,__tmp_reg__");
3777 else if (reg_dest == REG_X - 2)
3778 return *l=5, ("ld %A0,X+" CR_TAB
3779 "ld %B0,X+" CR_TAB
3780 "ld __tmp_reg__,X+" CR_TAB
3781 "ld %D0,X" CR_TAB
3782 "mov %C0,__tmp_reg__");
3783 else if (reg_unused_after (insn, base))
3784 return *l=4, ("ld %A0,X+" CR_TAB
3785 "ld %B0,X+" CR_TAB
3786 "ld %C0,X+" CR_TAB
3787 "ld %D0,X");
3788 else
3789 return *l=5, ("ld %A0,X+" CR_TAB
3790 "ld %B0,X+" CR_TAB
3791 "ld %C0,X+" CR_TAB
3792 "ld %D0,X" CR_TAB
3793 "sbiw r26,3");
3794 }
3795 else
3796 {
3797 if (reg_dest == reg_base)
3798 return *l=5, ("ldd %D0,%1+3" CR_TAB
3799 "ldd %C0,%1+2" CR_TAB
3800 "ldd __tmp_reg__,%1+1" CR_TAB
3801 "ld %A0,%1" CR_TAB
3802 "mov %B0,__tmp_reg__");
3803 else if (reg_base == reg_dest + 2)
3804 return *l=5, ("ld %A0,%1" CR_TAB
3805 "ldd %B0,%1+1" CR_TAB
3806 "ldd __tmp_reg__,%1+2" CR_TAB
3807 "ldd %D0,%1+3" CR_TAB
3808 "mov %C0,__tmp_reg__");
3809 else
3810 return *l=4, ("ld %A0,%1" CR_TAB
3811 "ldd %B0,%1+1" CR_TAB
3812 "ldd %C0,%1+2" CR_TAB
3813 "ldd %D0,%1+3");
3814 }
3815 }
3816 else if (GET_CODE (base) == PLUS) /* (R + i) */
3817 {
3818 int disp = INTVAL (XEXP (base, 1));
3819
3820 if (AVR_TINY)
3821 return avr_out_movsi_r_mr_reg_disp_tiny (insn, op, l);
3822
3823 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3824 {
3825 if (REGNO (XEXP (base, 0)) != REG_Y)
3826 fatal_insn ("incorrect insn:",insn);
3827
3828 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
3829 return *l = 6, ("adiw r28,%o1-60" CR_TAB
3830 "ldd %A0,Y+60" CR_TAB
3831 "ldd %B0,Y+61" CR_TAB
3832 "ldd %C0,Y+62" CR_TAB
3833 "ldd %D0,Y+63" CR_TAB
3834 "sbiw r28,%o1-60");
3835
3836 return *l = 8, ("subi r28,lo8(-%o1)" CR_TAB
3837 "sbci r29,hi8(-%o1)" CR_TAB
3838 "ld %A0,Y" CR_TAB
3839 "ldd %B0,Y+1" CR_TAB
3840 "ldd %C0,Y+2" CR_TAB
3841 "ldd %D0,Y+3" CR_TAB
3842 "subi r28,lo8(%o1)" CR_TAB
3843 "sbci r29,hi8(%o1)");
3844 }
3845
3846 reg_base = true_regnum (XEXP (base, 0));
3847 if (reg_base == REG_X)
3848 {
3849 /* R = (X + d) */
3850 if (reg_dest == REG_X)
3851 {
3852 *l = 7;
3853 /* "ld r26,-X" is undefined */
3854 return ("adiw r26,%o1+3" CR_TAB
3855 "ld r29,X" CR_TAB
3856 "ld r28,-X" CR_TAB
3857 "ld __tmp_reg__,-X" CR_TAB
3858 "sbiw r26,1" CR_TAB
3859 "ld r26,X" CR_TAB
3860 "mov r27,__tmp_reg__");
3861 }
3862 *l = 6;
3863 if (reg_dest == REG_X - 2)
3864 return ("adiw r26,%o1" CR_TAB
3865 "ld r24,X+" CR_TAB
3866 "ld r25,X+" CR_TAB
3867 "ld __tmp_reg__,X+" CR_TAB
3868 "ld r27,X" CR_TAB
3869 "mov r26,__tmp_reg__");
3870
3871 return ("adiw r26,%o1" CR_TAB
3872 "ld %A0,X+" CR_TAB
3873 "ld %B0,X+" CR_TAB
3874 "ld %C0,X+" CR_TAB
3875 "ld %D0,X" CR_TAB
3876 "sbiw r26,%o1+3");
3877 }
3878 if (reg_dest == reg_base)
3879 return *l=5, ("ldd %D0,%D1" CR_TAB
3880 "ldd %C0,%C1" CR_TAB
3881 "ldd __tmp_reg__,%B1" CR_TAB
3882 "ldd %A0,%A1" CR_TAB
3883 "mov %B0,__tmp_reg__");
3884 else if (reg_dest == reg_base - 2)
3885 return *l=5, ("ldd %A0,%A1" CR_TAB
3886 "ldd %B0,%B1" CR_TAB
3887 "ldd __tmp_reg__,%C1" CR_TAB
3888 "ldd %D0,%D1" CR_TAB
3889 "mov %C0,__tmp_reg__");
3890 return *l=4, ("ldd %A0,%A1" CR_TAB
3891 "ldd %B0,%B1" CR_TAB
3892 "ldd %C0,%C1" CR_TAB
3893 "ldd %D0,%D1");
3894 }
3895 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3896 return *l=4, ("ld %D0,%1" CR_TAB
3897 "ld %C0,%1" CR_TAB
3898 "ld %B0,%1" CR_TAB
3899 "ld %A0,%1");
3900 else if (GET_CODE (base) == POST_INC) /* (R++) */
3901 return *l=4, ("ld %A0,%1" CR_TAB
3902 "ld %B0,%1" CR_TAB
3903 "ld %C0,%1" CR_TAB
3904 "ld %D0,%1");
3905 else if (CONSTANT_ADDRESS_P (base))
3906 {
3907 if (io_address_operand (base, SImode))
3908 {
3909 *l = 4;
3910 return ("in %A0,%i1" CR_TAB
3911 "in %B0,%i1+1" CR_TAB
3912 "in %C0,%i1+2" CR_TAB
3913 "in %D0,%i1+3");
3914 }
3915 else
3916 {
3917 *l = AVR_TINY ? 4 : 8;
3918 return ("lds %A0,%m1" CR_TAB
3919 "lds %B0,%m1+1" CR_TAB
3920 "lds %C0,%m1+2" CR_TAB
3921 "lds %D0,%m1+3");
3922 }
3923 }
3924
3925 fatal_insn ("unknown move insn:",insn);
3926 return "";
3927 }
3928
3929 static const char*
3930 avr_out_movsi_mr_r_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *l)
3931 {
3932 rtx dest = op[0];
3933 rtx src = op[1];
3934 rtx base = XEXP (dest, 0);
3935 int reg_base = true_regnum (base);
3936 int reg_src = true_regnum (src);
3937
3938 if (reg_base == reg_src)
3939 {
3940 /* "ld r26,-X" is undefined */
3941 if (reg_unused_after (insn, base))
3942 {
3943 return *l = 7, ("mov __tmp_reg__, %B1" CR_TAB
3944 "st %0,%A1" CR_TAB
3945 TINY_ADIW (%E0, %F0, 1) CR_TAB
3946 "st %0+,__tmp_reg__" CR_TAB
3947 "st %0+,%C1" CR_TAB
3948 "st %0+,%D1");
3949 }
3950 else
3951 {
3952 return *l = 9, ("mov __tmp_reg__, %B1" CR_TAB
3953 "st %0,%A1" CR_TAB
3954 TINY_ADIW (%E0, %F0, 1) CR_TAB
3955 "st %0+,__tmp_reg__" CR_TAB
3956 "st %0+,%C1" CR_TAB
3957 "st %0+,%D1" CR_TAB
3958 TINY_SBIW (%E0, %F0, 3));
3959 }
3960 }
3961 else if (reg_base == reg_src + 2)
3962 {
3963 if (reg_unused_after (insn, base))
3964 return *l = 7, ("mov __zero_reg__,%C1" CR_TAB
3965 "mov __tmp_reg__,%D1" CR_TAB
3966 "st %0+,%A1" CR_TAB
3967 "st %0+,%B1" CR_TAB
3968 "st %0+,__zero_reg__" CR_TAB
3969 "st %0,__tmp_reg__" CR_TAB
3970 "clr __zero_reg__");
3971 else
3972 return *l = 9, ("mov __zero_reg__,%C1" CR_TAB
3973 "mov __tmp_reg__,%D1" CR_TAB
3974 "st %0+,%A1" CR_TAB
3975 "st %0+,%B1" CR_TAB
3976 "st %0+,__zero_reg__" CR_TAB
3977 "st %0,__tmp_reg__" CR_TAB
3978 "clr __zero_reg__" CR_TAB
3979 TINY_SBIW (%E0, %F0, 3));
3980 }
3981
3982 return *l = 6, ("st %0+,%A1" CR_TAB
3983 "st %0+,%B1" CR_TAB
3984 "st %0+,%C1" CR_TAB
3985 "st %0,%D1" CR_TAB
3986 TINY_SBIW (%E0, %F0, 3));
3987 }
3988
3989 static const char*
3990 avr_out_movsi_mr_r_reg_disp_tiny (rtx op[], int *l)
3991 {
3992 rtx dest = op[0];
3993 rtx src = op[1];
3994 rtx base = XEXP (dest, 0);
3995 int reg_base = REGNO (XEXP (base, 0));
3996 int reg_src =true_regnum (src);
3997
3998 if (reg_base == reg_src)
3999 {
4000 *l = 11;
4001 return ("mov __tmp_reg__,%A2" CR_TAB
4002 "mov __zero_reg__,%B2" CR_TAB
4003 TINY_ADIW (%I0, %J0, %o0) CR_TAB
4004 "st %b0+,__tmp_reg__" CR_TAB
4005 "st %b0+,__zero_reg__" CR_TAB
4006 "st %b0+,%C2" CR_TAB
4007 "st %b0,%D2" CR_TAB
4008 "clr __zero_reg__" CR_TAB
4009 TINY_SBIW (%I0, %J0, %o0+3));
4010 }
4011 else if (reg_src == reg_base - 2)
4012 {
4013 *l = 11;
4014 return ("mov __tmp_reg__,%C2" CR_TAB
4015 "mov __zero_reg__,%D2" CR_TAB
4016 TINY_ADIW (%I0, %J0, %o0) CR_TAB
4017 "st %b0+,%A0" CR_TAB
4018 "st %b0+,%B0" CR_TAB
4019 "st %b0+,__tmp_reg__" CR_TAB
4020 "st %b0,__zero_reg__" CR_TAB
4021 "clr __zero_reg__" CR_TAB
4022 TINY_SBIW (%I0, %J0, %o0+3));
4023 }
4024 *l = 8;
4025 return (TINY_ADIW (%I0, %J0, %o0) CR_TAB
4026 "st %b0+,%A1" CR_TAB
4027 "st %b0+,%B1" CR_TAB
4028 "st %b0+,%C1" CR_TAB
4029 "st %b0,%D1" CR_TAB
4030 TINY_SBIW (%I0, %J0, %o0+3));
4031 }
4032
4033 static const char*
4034 out_movsi_mr_r (rtx_insn *insn, rtx op[], int *l)
4035 {
4036 rtx dest = op[0];
4037 rtx src = op[1];
4038 rtx base = XEXP (dest, 0);
4039 int reg_base = true_regnum (base);
4040 int reg_src = true_regnum (src);
4041 int tmp;
4042
4043 if (!l)
4044 l = &tmp;
4045
4046 if (CONSTANT_ADDRESS_P (base))
4047 {
4048 if (io_address_operand (base, SImode))
4049 {
4050 return *l=4,("out %i0, %A1" CR_TAB
4051 "out %i0+1,%B1" CR_TAB
4052 "out %i0+2,%C1" CR_TAB
4053 "out %i0+3,%D1");
4054 }
4055 else
4056 {
4057 *l = AVR_TINY ? 4 : 8;
4058 return ("sts %m0,%A1" CR_TAB
4059 "sts %m0+1,%B1" CR_TAB
4060 "sts %m0+2,%C1" CR_TAB
4061 "sts %m0+3,%D1");
4062 }
4063 }
4064
4065 if (reg_base > 0) /* (r) */
4066 {
4067 if (AVR_TINY)
4068 return avr_out_movsi_mr_r_reg_no_disp_tiny (insn, op, l);
4069
4070 if (reg_base == REG_X) /* (R26) */
4071 {
4072 if (reg_src == REG_X)
4073 {
4074 /* "st X+,r26" is undefined */
4075 if (reg_unused_after (insn, base))
4076 return *l=6, ("mov __tmp_reg__,r27" CR_TAB
4077 "st X,r26" CR_TAB
4078 "adiw r26,1" CR_TAB
4079 "st X+,__tmp_reg__" CR_TAB
4080 "st X+,r28" CR_TAB
4081 "st X,r29");
4082 else
4083 return *l=7, ("mov __tmp_reg__,r27" CR_TAB
4084 "st X,r26" CR_TAB
4085 "adiw r26,1" CR_TAB
4086 "st X+,__tmp_reg__" CR_TAB
4087 "st X+,r28" CR_TAB
4088 "st X,r29" CR_TAB
4089 "sbiw r26,3");
4090 }
4091 else if (reg_base == reg_src + 2)
4092 {
4093 if (reg_unused_after (insn, base))
4094 return *l=7, ("mov __zero_reg__,%C1" CR_TAB
4095 "mov __tmp_reg__,%D1" CR_TAB
4096 "st %0+,%A1" CR_TAB
4097 "st %0+,%B1" CR_TAB
4098 "st %0+,__zero_reg__" CR_TAB
4099 "st %0,__tmp_reg__" CR_TAB
4100 "clr __zero_reg__");
4101 else
4102 return *l=8, ("mov __zero_reg__,%C1" CR_TAB
4103 "mov __tmp_reg__,%D1" CR_TAB
4104 "st %0+,%A1" CR_TAB
4105 "st %0+,%B1" CR_TAB
4106 "st %0+,__zero_reg__" CR_TAB
4107 "st %0,__tmp_reg__" CR_TAB
4108 "clr __zero_reg__" CR_TAB
4109 "sbiw r26,3");
4110 }
4111 return *l=5, ("st %0+,%A1" CR_TAB
4112 "st %0+,%B1" CR_TAB
4113 "st %0+,%C1" CR_TAB
4114 "st %0,%D1" CR_TAB
4115 "sbiw r26,3");
4116 }
4117 else
4118 return *l=4, ("st %0,%A1" CR_TAB
4119 "std %0+1,%B1" CR_TAB
4120 "std %0+2,%C1" CR_TAB
4121 "std %0+3,%D1");
4122 }
4123 else if (GET_CODE (base) == PLUS) /* (R + i) */
4124 {
4125 int disp = INTVAL (XEXP (base, 1));
4126
4127 if (AVR_TINY)
4128 return avr_out_movsi_mr_r_reg_disp_tiny (op, l);
4129
4130 reg_base = REGNO (XEXP (base, 0));
4131 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
4132 {
4133 if (reg_base != REG_Y)
4134 fatal_insn ("incorrect insn:",insn);
4135
4136 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
4137 return *l = 6, ("adiw r28,%o0-60" CR_TAB
4138 "std Y+60,%A1" CR_TAB
4139 "std Y+61,%B1" CR_TAB
4140 "std Y+62,%C1" CR_TAB
4141 "std Y+63,%D1" CR_TAB
4142 "sbiw r28,%o0-60");
4143
4144 return *l = 8, ("subi r28,lo8(-%o0)" CR_TAB
4145 "sbci r29,hi8(-%o0)" CR_TAB
4146 "st Y,%A1" CR_TAB
4147 "std Y+1,%B1" CR_TAB
4148 "std Y+2,%C1" CR_TAB
4149 "std Y+3,%D1" CR_TAB
4150 "subi r28,lo8(%o0)" CR_TAB
4151 "sbci r29,hi8(%o0)");
4152 }
4153 if (reg_base == REG_X)
4154 {
4155 /* (X + d) = R */
4156 if (reg_src == REG_X)
4157 {
4158 *l = 9;
4159 return ("mov __tmp_reg__,r26" CR_TAB
4160 "mov __zero_reg__,r27" CR_TAB
4161 "adiw r26,%o0" CR_TAB
4162 "st X+,__tmp_reg__" CR_TAB
4163 "st X+,__zero_reg__" CR_TAB
4164 "st X+,r28" CR_TAB
4165 "st X,r29" CR_TAB
4166 "clr __zero_reg__" CR_TAB
4167 "sbiw r26,%o0+3");
4168 }
4169 else if (reg_src == REG_X - 2)
4170 {
4171 *l = 9;
4172 return ("mov __tmp_reg__,r26" CR_TAB
4173 "mov __zero_reg__,r27" CR_TAB
4174 "adiw r26,%o0" CR_TAB
4175 "st X+,r24" CR_TAB
4176 "st X+,r25" CR_TAB
4177 "st X+,__tmp_reg__" CR_TAB
4178 "st X,__zero_reg__" CR_TAB
4179 "clr __zero_reg__" CR_TAB
4180 "sbiw r26,%o0+3");
4181 }
4182 *l = 6;
4183 return ("adiw r26,%o0" CR_TAB
4184 "st X+,%A1" CR_TAB
4185 "st X+,%B1" CR_TAB
4186 "st X+,%C1" CR_TAB
4187 "st X,%D1" CR_TAB
4188 "sbiw r26,%o0+3");
4189 }
4190 return *l=4, ("std %A0,%A1" CR_TAB
4191 "std %B0,%B1" CR_TAB
4192 "std %C0,%C1" CR_TAB
4193 "std %D0,%D1");
4194 }
4195 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4196 return *l=4, ("st %0,%D1" CR_TAB
4197 "st %0,%C1" CR_TAB
4198 "st %0,%B1" CR_TAB
4199 "st %0,%A1");
4200 else if (GET_CODE (base) == POST_INC) /* (R++) */
4201 return *l=4, ("st %0,%A1" CR_TAB
4202 "st %0,%B1" CR_TAB
4203 "st %0,%C1" CR_TAB
4204 "st %0,%D1");
4205 fatal_insn ("unknown move insn:",insn);
4206 return "";
4207 }
4208
4209 const char *
4210 output_movsisf (rtx_insn *insn, rtx operands[], int *l)
4211 {
4212 int dummy;
4213 rtx dest = operands[0];
4214 rtx src = operands[1];
4215 int *real_l = l;
4216
4217 if (avr_mem_flash_p (src)
4218 || avr_mem_flash_p (dest))
4219 {
4220 return avr_out_lpm (insn, operands, real_l);
4221 }
4222
4223 if (!l)
4224 l = &dummy;
4225
4226 gcc_assert (4 == GET_MODE_SIZE (GET_MODE (dest)));
4227 if (REG_P (dest))
4228 {
4229 if (REG_P (src)) /* mov r,r */
4230 {
4231 if (true_regnum (dest) > true_regnum (src))
4232 {
4233 if (AVR_HAVE_MOVW)
4234 {
4235 *l = 2;
4236 return ("movw %C0,%C1" CR_TAB
4237 "movw %A0,%A1");
4238 }
4239 *l = 4;
4240 return ("mov %D0,%D1" CR_TAB
4241 "mov %C0,%C1" CR_TAB
4242 "mov %B0,%B1" CR_TAB
4243 "mov %A0,%A1");
4244 }
4245 else
4246 {
4247 if (AVR_HAVE_MOVW)
4248 {
4249 *l = 2;
4250 return ("movw %A0,%A1" CR_TAB
4251 "movw %C0,%C1");
4252 }
4253 *l = 4;
4254 return ("mov %A0,%A1" CR_TAB
4255 "mov %B0,%B1" CR_TAB
4256 "mov %C0,%C1" CR_TAB
4257 "mov %D0,%D1");
4258 }
4259 }
4260 else if (CONSTANT_P (src))
4261 {
4262 return output_reload_insisf (operands, NULL_RTX, real_l);
4263 }
4264 else if (MEM_P (src))
4265 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
4266 }
4267 else if (MEM_P (dest))
4268 {
4269 const char *templ;
4270
4271 if (src == CONST0_RTX (GET_MODE (dest)))
4272 operands[1] = zero_reg_rtx;
4273
4274 templ = out_movsi_mr_r (insn, operands, real_l);
4275
4276 if (!real_l)
4277 output_asm_insn (templ, operands);
4278
4279 operands[1] = src;
4280 return "";
4281 }
4282 fatal_insn ("invalid insn:", insn);
4283 return "";
4284 }
4285
4286
4287 /* Handle loads of 24-bit types from memory to register. */
4288
4289 static const char*
4290 avr_out_load_psi_reg_no_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
4291 {
4292 rtx dest = op[0];
4293 rtx src = op[1];
4294 rtx base = XEXP (src, 0);
4295 int reg_dest = true_regnum (dest);
4296 int reg_base = true_regnum (base);
4297
4298 if (reg_base == reg_dest)
4299 {
4300 return avr_asm_len (TINY_ADIW (%E1, %F1, 2) CR_TAB
4301 "ld %C0,%1" CR_TAB
4302 "ld __tmp_reg__,-%1" CR_TAB
4303 TINY_SBIW (%E1, %F1, 1) CR_TAB
4304 "ld %A0,%1" CR_TAB
4305 "mov %B0,__tmp_reg__", op, plen, -8);
4306 }
4307 else
4308 {
4309 return avr_asm_len ("ld %A0,%1+" CR_TAB
4310 "ld %B0,%1+" CR_TAB
4311 "ld %C0,%1", op, plen, -3);
4312
4313 if (reg_dest != reg_base - 2 &&
4314 !reg_unused_after (insn, base))
4315 {
4316 avr_asm_len (TINY_SBIW (%E1, %F1, 2), op, plen, 2);
4317 }
4318 return "";
4319 }
4320 }
4321
4322 static const char*
4323 avr_out_load_psi_reg_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
4324 {
4325 rtx dest = op[0];
4326 rtx src = op[1];
4327 rtx base = XEXP (src, 0);
4328 int reg_dest = true_regnum (dest);
4329 int reg_base = true_regnum (base);
4330
4331 reg_base = true_regnum (XEXP (base, 0));
4332 if (reg_base == reg_dest)
4333 {
4334 return avr_asm_len (TINY_ADIW (%I1, %J1, %o1+2) CR_TAB
4335 "ld %C0,%b1" CR_TAB
4336 "ld __tmp_reg__,-%b1" CR_TAB
4337 TINY_SBIW (%I1, %J1, 1) CR_TAB
4338 "ld %A0,%b1" CR_TAB
4339 "mov %B0,__tmp_reg__", op, plen, -8);
4340 }
4341 else
4342 {
4343 avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
4344 "ld %A0,%b1+" CR_TAB
4345 "ld %B0,%b1+" CR_TAB
4346 "ld %C0,%b1", op, plen, -5);
4347
4348 if (reg_dest != (reg_base - 2)
4349 && !reg_unused_after (insn, XEXP (base, 0)))
4350 avr_asm_len (TINY_SBIW (%I1, %J1, %o1+2), op, plen, 2);
4351
4352 return "";
4353 }
4354 }
4355
4356 static const char*
4357 avr_out_load_psi (rtx_insn *insn, rtx *op, int *plen)
4358 {
4359 rtx dest = op[0];
4360 rtx src = op[1];
4361 rtx base = XEXP (src, 0);
4362 int reg_dest = true_regnum (dest);
4363 int reg_base = true_regnum (base);
4364
4365 if (reg_base > 0)
4366 {
4367 if (AVR_TINY)
4368 return avr_out_load_psi_reg_no_disp_tiny (insn, op, plen);
4369
4370 if (reg_base == REG_X) /* (R26) */
4371 {
4372 if (reg_dest == REG_X)
4373 /* "ld r26,-X" is undefined */
4374 return avr_asm_len ("adiw r26,2" CR_TAB
4375 "ld r28,X" CR_TAB
4376 "ld __tmp_reg__,-X" CR_TAB
4377 "sbiw r26,1" CR_TAB
4378 "ld r26,X" CR_TAB
4379 "mov r27,__tmp_reg__", op, plen, -6);
4380 else
4381 {
4382 avr_asm_len ("ld %A0,X+" CR_TAB
4383 "ld %B0,X+" CR_TAB
4384 "ld %C0,X", op, plen, -3);
4385
4386 if (reg_dest != REG_X - 2
4387 && !reg_unused_after (insn, base))
4388 {
4389 avr_asm_len ("sbiw r26,2", op, plen, 1);
4390 }
4391
4392 return "";
4393 }
4394 }
4395 else /* reg_base != REG_X */
4396 {
4397 if (reg_dest == reg_base)
4398 return avr_asm_len ("ldd %C0,%1+2" CR_TAB
4399 "ldd __tmp_reg__,%1+1" CR_TAB
4400 "ld %A0,%1" CR_TAB
4401 "mov %B0,__tmp_reg__", op, plen, -4);
4402 else
4403 return avr_asm_len ("ld %A0,%1" CR_TAB
4404 "ldd %B0,%1+1" CR_TAB
4405 "ldd %C0,%1+2", op, plen, -3);
4406 }
4407 }
4408 else if (GET_CODE (base) == PLUS) /* (R + i) */
4409 {
4410 int disp = INTVAL (XEXP (base, 1));
4411
4412 if (AVR_TINY)
4413 return avr_out_load_psi_reg_disp_tiny (insn, op, plen);
4414
4415 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
4416 {
4417 if (REGNO (XEXP (base, 0)) != REG_Y)
4418 fatal_insn ("incorrect insn:",insn);
4419
4420 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
4421 return avr_asm_len ("adiw r28,%o1-61" CR_TAB
4422 "ldd %A0,Y+61" CR_TAB
4423 "ldd %B0,Y+62" CR_TAB
4424 "ldd %C0,Y+63" CR_TAB
4425 "sbiw r28,%o1-61", op, plen, -5);
4426
4427 return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
4428 "sbci r29,hi8(-%o1)" CR_TAB
4429 "ld %A0,Y" CR_TAB
4430 "ldd %B0,Y+1" CR_TAB
4431 "ldd %C0,Y+2" CR_TAB
4432 "subi r28,lo8(%o1)" CR_TAB
4433 "sbci r29,hi8(%o1)", op, plen, -7);
4434 }
4435
4436 reg_base = true_regnum (XEXP (base, 0));
4437 if (reg_base == REG_X)
4438 {
4439 /* R = (X + d) */
4440 if (reg_dest == REG_X)
4441 {
4442 /* "ld r26,-X" is undefined */
4443 return avr_asm_len ("adiw r26,%o1+2" CR_TAB
4444 "ld r28,X" CR_TAB
4445 "ld __tmp_reg__,-X" CR_TAB
4446 "sbiw r26,1" CR_TAB
4447 "ld r26,X" CR_TAB
4448 "mov r27,__tmp_reg__", op, plen, -6);
4449 }
4450
4451 avr_asm_len ("adiw r26,%o1" CR_TAB
4452 "ld %A0,X+" CR_TAB
4453 "ld %B0,X+" CR_TAB
4454 "ld %C0,X", op, plen, -4);
4455
4456 if (reg_dest != REG_W
4457 && !reg_unused_after (insn, XEXP (base, 0)))
4458 avr_asm_len ("sbiw r26,%o1+2", op, plen, 1);
4459
4460 return "";
4461 }
4462
4463 if (reg_dest == reg_base)
4464 return avr_asm_len ("ldd %C0,%C1" CR_TAB
4465 "ldd __tmp_reg__,%B1" CR_TAB
4466 "ldd %A0,%A1" CR_TAB
4467 "mov %B0,__tmp_reg__", op, plen, -4);
4468
4469 return avr_asm_len ("ldd %A0,%A1" CR_TAB
4470 "ldd %B0,%B1" CR_TAB
4471 "ldd %C0,%C1", op, plen, -3);
4472 }
4473 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4474 return avr_asm_len ("ld %C0,%1" CR_TAB
4475 "ld %B0,%1" CR_TAB
4476 "ld %A0,%1", op, plen, -3);
4477 else if (GET_CODE (base) == POST_INC) /* (R++) */
4478 return avr_asm_len ("ld %A0,%1" CR_TAB
4479 "ld %B0,%1" CR_TAB
4480 "ld %C0,%1", op, plen, -3);
4481
4482 else if (CONSTANT_ADDRESS_P (base))
4483 {
4484 int n_words = AVR_TINY ? 3 : 6;
4485 return avr_asm_len ("lds %A0,%m1" CR_TAB
4486 "lds %B0,%m1+1" CR_TAB
4487 "lds %C0,%m1+2", op, plen , -n_words);
4488 }
4489
4490 fatal_insn ("unknown move insn:",insn);
4491 return "";
4492 }
4493
4494
4495 static const char*
4496 avr_out_store_psi_reg_no_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
4497 {
4498 rtx dest = op[0];
4499 rtx src = op[1];
4500 rtx base = XEXP (dest, 0);
4501 int reg_base = true_regnum (base);
4502 int reg_src = true_regnum (src);
4503
4504 if (reg_base == reg_src)
4505 {
4506 avr_asm_len ("st %0,%A1" CR_TAB
4507 "mov __tmp_reg__,%B1" CR_TAB
4508 TINY_ADIW (%E0, %F0, 1) CR_TAB /* st X+, r27 is undefined */
4509 "st %0+,__tmp_reg__" CR_TAB
4510 "st %0,%C1", op, plen, -6);
4511
4512 }
4513 else if (reg_src == reg_base - 2)
4514 {
4515 avr_asm_len ("st %0,%A1" CR_TAB
4516 "mov __tmp_reg__,%C1" CR_TAB
4517 TINY_ADIW (%E0, %F0, 1) CR_TAB
4518 "st %0+,%B1" CR_TAB
4519 "st %0,__tmp_reg__", op, plen, 6);
4520 }
4521 else
4522 {
4523 avr_asm_len ("st %0+,%A1" CR_TAB
4524 "st %0+,%B1" CR_TAB
4525 "st %0,%C1", op, plen, -3);
4526 }
4527
4528 if (!reg_unused_after (insn, base))
4529 avr_asm_len (TINY_SBIW (%E0, %F0, 2), op, plen, 2);
4530
4531 return "";
4532 }
4533
4534 static const char*
4535 avr_out_store_psi_reg_disp_tiny (rtx *op, int *plen)
4536 {
4537 rtx dest = op[0];
4538 rtx src = op[1];
4539 rtx base = XEXP (dest, 0);
4540 int reg_base = REGNO (XEXP (base, 0));
4541 int reg_src = true_regnum (src);
4542
4543 if (reg_src == reg_base)
4544 {
4545 return avr_asm_len ("mov __tmp_reg__,%A1" CR_TAB
4546 "mov __zero_reg__,%B1" CR_TAB
4547 TINY_ADIW (%I0, %J0, %o0) CR_TAB
4548 "st %b0+,__tmp_reg__" CR_TAB
4549 "st %b0+,__zero_reg__" CR_TAB
4550 "st %b0,%C1" CR_TAB
4551 "clr __zero_reg__" CR_TAB
4552 TINY_SBIW (%I0, %J0, %o0+2), op, plen, -10);
4553 }
4554 else if (reg_src == reg_base - 2)
4555 {
4556 return avr_asm_len ("mov __tmp_reg__,%C1" CR_TAB
4557 TINY_ADIW (%I0, %J0, %o0) CR_TAB
4558 "st %b0+,%A1" CR_TAB
4559 "st %b0+,%B1" CR_TAB
4560 "st %b0,__tmp_reg__" CR_TAB
4561 TINY_SBIW (%I0, %J0, %o0+2), op, plen, -8);
4562 }
4563
4564 return avr_asm_len (TINY_ADIW (%I0, %J0, %o0) CR_TAB
4565 "st %b0+,%A1" CR_TAB
4566 "st %b0+,%B1" CR_TAB
4567 "st %b0,%C1" CR_TAB
4568 TINY_SBIW (%I0, %J0, %o0+2), op, plen, -7);
4569 }
4570
4571 /* Handle store of 24-bit type from register or zero to memory. */
4572
4573 static const char*
4574 avr_out_store_psi (rtx_insn *insn, rtx *op, int *plen)
4575 {
4576 rtx dest = op[0];
4577 rtx src = op[1];
4578 rtx base = XEXP (dest, 0);
4579 int reg_base = true_regnum (base);
4580
4581 if (CONSTANT_ADDRESS_P (base))
4582 {
4583 int n_words = AVR_TINY ? 3 : 6;
4584 return avr_asm_len ("sts %m0,%A1" CR_TAB
4585 "sts %m0+1,%B1" CR_TAB
4586 "sts %m0+2,%C1", op, plen, -n_words);
4587 }
4588
4589 if (reg_base > 0) /* (r) */
4590 {
4591 if (AVR_TINY)
4592 return avr_out_store_psi_reg_no_disp_tiny (insn, op, plen);
4593
4594 if (reg_base == REG_X) /* (R26) */
4595 {
4596 gcc_assert (!reg_overlap_mentioned_p (base, src));
4597
4598 avr_asm_len ("st %0+,%A1" CR_TAB
4599 "st %0+,%B1" CR_TAB
4600 "st %0,%C1", op, plen, -3);
4601
4602 if (!reg_unused_after (insn, base))
4603 avr_asm_len ("sbiw r26,2", op, plen, 1);
4604
4605 return "";
4606 }
4607 else
4608 return avr_asm_len ("st %0,%A1" CR_TAB
4609 "std %0+1,%B1" CR_TAB
4610 "std %0+2,%C1", op, plen, -3);
4611 }
4612 else if (GET_CODE (base) == PLUS) /* (R + i) */
4613 {
4614 int disp = INTVAL (XEXP (base, 1));
4615
4616 if (AVR_TINY)
4617 return avr_out_store_psi_reg_disp_tiny (op, plen);
4618
4619 reg_base = REGNO (XEXP (base, 0));
4620
4621 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
4622 {
4623 if (reg_base != REG_Y)
4624 fatal_insn ("incorrect insn:",insn);
4625
4626 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
4627 return avr_asm_len ("adiw r28,%o0-61" CR_TAB
4628 "std Y+61,%A1" CR_TAB
4629 "std Y+62,%B1" CR_TAB
4630 "std Y+63,%C1" CR_TAB
4631 "sbiw r28,%o0-61", op, plen, -5);
4632
4633 return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
4634 "sbci r29,hi8(-%o0)" CR_TAB
4635 "st Y,%A1" CR_TAB
4636 "std Y+1,%B1" CR_TAB
4637 "std Y+2,%C1" CR_TAB
4638 "subi r28,lo8(%o0)" CR_TAB
4639 "sbci r29,hi8(%o0)", op, plen, -7);
4640 }
4641 if (reg_base == REG_X)
4642 {
4643 /* (X + d) = R */
4644 gcc_assert (!reg_overlap_mentioned_p (XEXP (base, 0), src));
4645
4646 avr_asm_len ("adiw r26,%o0" CR_TAB
4647 "st X+,%A1" CR_TAB
4648 "st X+,%B1" CR_TAB
4649 "st X,%C1", op, plen, -4);
4650
4651 if (!reg_unused_after (insn, XEXP (base, 0)))
4652 avr_asm_len ("sbiw r26,%o0+2", op, plen, 1);
4653
4654 return "";
4655 }
4656
4657 return avr_asm_len ("std %A0,%A1" CR_TAB
4658 "std %B0,%B1" CR_TAB
4659 "std %C0,%C1", op, plen, -3);
4660 }
4661 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4662 return avr_asm_len ("st %0,%C1" CR_TAB
4663 "st %0,%B1" CR_TAB
4664 "st %0,%A1", op, plen, -3);
4665 else if (GET_CODE (base) == POST_INC) /* (R++) */
4666 return avr_asm_len ("st %0,%A1" CR_TAB
4667 "st %0,%B1" CR_TAB
4668 "st %0,%C1", op, plen, -3);
4669
4670 fatal_insn ("unknown move insn:",insn);
4671 return "";
4672 }
4673
4674
4675 /* Move around 24-bit stuff. */
4676
4677 const char *
4678 avr_out_movpsi (rtx_insn *insn, rtx *op, int *plen)
4679 {
4680 rtx dest = op[0];
4681 rtx src = op[1];
4682
4683 if (avr_mem_flash_p (src)
4684 || avr_mem_flash_p (dest))
4685 {
4686 return avr_out_lpm (insn, op, plen);
4687 }
4688
4689 if (register_operand (dest, VOIDmode))
4690 {
4691 if (register_operand (src, VOIDmode)) /* mov r,r */
4692 {
4693 if (true_regnum (dest) > true_regnum (src))
4694 {
4695 avr_asm_len ("mov %C0,%C1", op, plen, -1);
4696
4697 if (AVR_HAVE_MOVW)
4698 return avr_asm_len ("movw %A0,%A1", op, plen, 1);
4699 else
4700 return avr_asm_len ("mov %B0,%B1" CR_TAB
4701 "mov %A0,%A1", op, plen, 2);
4702 }
4703 else
4704 {
4705 if (AVR_HAVE_MOVW)
4706 avr_asm_len ("movw %A0,%A1", op, plen, -1);
4707 else
4708 avr_asm_len ("mov %A0,%A1" CR_TAB
4709 "mov %B0,%B1", op, plen, -2);
4710
4711 return avr_asm_len ("mov %C0,%C1", op, plen, 1);
4712 }
4713 }
4714 else if (CONSTANT_P (src))
4715 {
4716 return avr_out_reload_inpsi (op, NULL_RTX, plen);
4717 }
4718 else if (MEM_P (src))
4719 return avr_out_load_psi (insn, op, plen); /* mov r,m */
4720 }
4721 else if (MEM_P (dest))
4722 {
4723 rtx xop[2];
4724
4725 xop[0] = dest;
4726 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
4727
4728 return avr_out_store_psi (insn, xop, plen);
4729 }
4730
4731 fatal_insn ("invalid insn:", insn);
4732 return "";
4733 }
4734
4735 static const char*
4736 avr_out_movqi_mr_r_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
4737 {
4738 rtx dest = op[0];
4739 rtx src = op[1];
4740 rtx x = XEXP (dest, 0);
4741
4742 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
4743 {
4744 avr_asm_len ("mov __tmp_reg__,%1" CR_TAB
4745 TINY_ADIW (%I0, %J0, %o0) CR_TAB
4746 "st %b0,__tmp_reg__", op, plen, -4);
4747 }
4748 else
4749 {
4750 avr_asm_len (TINY_ADIW (%I0, %J0, %o0) CR_TAB
4751 "st %b0,%1" , op, plen, -3);
4752 }
4753
4754 if (!reg_unused_after (insn, XEXP (x,0)))
4755 avr_asm_len (TINY_SBIW (%I0, %J0, %o0), op, plen, 2);
4756
4757 return "";
4758 }
4759
4760 static const char*
4761 out_movqi_mr_r (rtx_insn *insn, rtx op[], int *plen)
4762 {
4763 rtx dest = op[0];
4764 rtx src = op[1];
4765 rtx x = XEXP (dest, 0);
4766
4767 if (CONSTANT_ADDRESS_P (x))
4768 {
4769 int n_words = AVR_TINY ? 1 : 2;
4770 return optimize > 0 && io_address_operand (x, QImode)
4771 ? avr_asm_len ("out %i0,%1", op, plen, -1)
4772 : avr_asm_len ("sts %m0,%1", op, plen, -n_words);
4773 }
4774 else if (GET_CODE (x) == PLUS
4775 && REG_P (XEXP (x, 0))
4776 && CONST_INT_P (XEXP (x, 1)))
4777 {
4778 /* memory access by reg+disp */
4779
4780 int disp = INTVAL (XEXP (x, 1));
4781
4782 if (AVR_TINY)
4783 return avr_out_movqi_mr_r_reg_disp_tiny (insn, op, plen);
4784
4785 if (disp - GET_MODE_SIZE (GET_MODE (dest)) >= 63)
4786 {
4787 if (REGNO (XEXP (x, 0)) != REG_Y)
4788 fatal_insn ("incorrect insn:",insn);
4789
4790 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
4791 return avr_asm_len ("adiw r28,%o0-63" CR_TAB
4792 "std Y+63,%1" CR_TAB
4793 "sbiw r28,%o0-63", op, plen, -3);
4794
4795 return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
4796 "sbci r29,hi8(-%o0)" CR_TAB
4797 "st Y,%1" CR_TAB
4798 "subi r28,lo8(%o0)" CR_TAB
4799 "sbci r29,hi8(%o0)", op, plen, -5);
4800 }
4801 else if (REGNO (XEXP (x,0)) == REG_X)
4802 {
4803 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
4804 {
4805 avr_asm_len ("mov __tmp_reg__,%1" CR_TAB
4806 "adiw r26,%o0" CR_TAB
4807 "st X,__tmp_reg__", op, plen, -3);
4808 }
4809 else
4810 {
4811 avr_asm_len ("adiw r26,%o0" CR_TAB
4812 "st X,%1", op, plen, -2);
4813 }
4814
4815 if (!reg_unused_after (insn, XEXP (x,0)))
4816 avr_asm_len ("sbiw r26,%o0", op, plen, 1);
4817
4818 return "";
4819 }
4820
4821 return avr_asm_len ("std %0,%1", op, plen, -1);
4822 }
4823
4824 return avr_asm_len ("st %0,%1", op, plen, -1);
4825 }
4826
4827
4828 /* Helper for the next function for XMEGA. It does the same
4829 but with low byte first. */
4830
4831 static const char*
4832 avr_out_movhi_mr_r_xmega (rtx_insn *insn, rtx op[], int *plen)
4833 {
4834 rtx dest = op[0];
4835 rtx src = op[1];
4836 rtx base = XEXP (dest, 0);
4837 int reg_base = true_regnum (base);
4838 int reg_src = true_regnum (src);
4839
4840 /* "volatile" forces writing low byte first, even if less efficient,
4841 for correct operation with 16-bit I/O registers like SP. */
4842 int mem_volatile_p = MEM_VOLATILE_P (dest);
4843
4844 if (CONSTANT_ADDRESS_P (base))
4845 {
4846 int n_words = AVR_TINY ? 2 : 4;
4847 return optimize > 0 && io_address_operand (base, HImode)
4848 ? avr_asm_len ("out %i0,%A1" CR_TAB
4849 "out %i0+1,%B1", op, plen, -2)
4850
4851 : avr_asm_len ("sts %m0,%A1" CR_TAB
4852 "sts %m0+1,%B1", op, plen, -n_words);
4853 }
4854
4855 if (reg_base > 0)
4856 {
4857 if (reg_base != REG_X)
4858 return avr_asm_len ("st %0,%A1" CR_TAB
4859 "std %0+1,%B1", op, plen, -2);
4860
4861 if (reg_src == REG_X)
4862 /* "st X+,r26" and "st -X,r26" are undefined. */
4863 avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
4864 "st X,r26" CR_TAB
4865 "adiw r26,1" CR_TAB
4866 "st X,__tmp_reg__", op, plen, -4);
4867 else
4868 avr_asm_len ("st X+,%A1" CR_TAB
4869 "st X,%B1", op, plen, -2);
4870
4871 return reg_unused_after (insn, base)
4872 ? ""
4873 : avr_asm_len ("sbiw r26,1", op, plen, 1);
4874 }
4875 else if (GET_CODE (base) == PLUS)
4876 {
4877 int disp = INTVAL (XEXP (base, 1));
4878 reg_base = REGNO (XEXP (base, 0));
4879 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
4880 {
4881 if (reg_base != REG_Y)
4882 fatal_insn ("incorrect insn:",insn);
4883
4884 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))
4885 ? avr_asm_len ("adiw r28,%o0-62" CR_TAB
4886 "std Y+62,%A1" CR_TAB
4887 "std Y+63,%B1" CR_TAB
4888 "sbiw r28,%o0-62", op, plen, -4)
4889
4890 : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
4891 "sbci r29,hi8(-%o0)" CR_TAB
4892 "st Y,%A1" CR_TAB
4893 "std Y+1,%B1" CR_TAB
4894 "subi r28,lo8(%o0)" CR_TAB
4895 "sbci r29,hi8(%o0)", op, plen, -6);
4896 }
4897
4898 if (reg_base != REG_X)
4899 return avr_asm_len ("std %A0,%A1" CR_TAB
4900 "std %B0,%B1", op, plen, -2);
4901 /* (X + d) = R */
4902 return reg_src == REG_X
4903 ? avr_asm_len ("mov __tmp_reg__,r26" CR_TAB
4904 "mov __zero_reg__,r27" CR_TAB
4905 "adiw r26,%o0" CR_TAB
4906 "st X+,__tmp_reg__" CR_TAB
4907 "st X,__zero_reg__" CR_TAB
4908 "clr __zero_reg__" CR_TAB
4909 "sbiw r26,%o0+1", op, plen, -7)
4910
4911 : avr_asm_len ("adiw r26,%o0" CR_TAB
4912 "st X+,%A1" CR_TAB
4913 "st X,%B1" CR_TAB
4914 "sbiw r26,%o0+1", op, plen, -4);
4915 }
4916 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4917 {
4918 if (!mem_volatile_p)
4919 return avr_asm_len ("st %0,%B1" CR_TAB
4920 "st %0,%A1", op, plen, -2);
4921
4922 return REGNO (XEXP (base, 0)) == REG_X
4923 ? avr_asm_len ("sbiw r26,2" CR_TAB
4924 "st X+,%A1" CR_TAB
4925 "st X,%B1" CR_TAB
4926 "sbiw r26,1", op, plen, -4)
4927
4928 : avr_asm_len ("sbiw %r0,2" CR_TAB
4929 "st %p0,%A1" CR_TAB
4930 "std %p0+1,%B1", op, plen, -3);
4931 }
4932 else if (GET_CODE (base) == POST_INC) /* (R++) */
4933 {
4934 return avr_asm_len ("st %0,%A1" CR_TAB
4935 "st %0,%B1", op, plen, -2);
4936
4937 }
4938 fatal_insn ("unknown move insn:",insn);
4939 return "";
4940 }
4941
4942 static const char*
4943 avr_out_movhi_mr_r_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
4944 {
4945 rtx dest = op[0];
4946 rtx src = op[1];
4947 rtx base = XEXP (dest, 0);
4948 int reg_base = true_regnum (base);
4949 int reg_src = true_regnum (src);
4950 int mem_volatile_p = MEM_VOLATILE_P (dest);
4951
4952 if (reg_base == reg_src)
4953 {
4954 return !mem_volatile_p && reg_unused_after (insn, src)
4955 ? avr_asm_len ("mov __tmp_reg__,%B1" CR_TAB
4956 "st %0,%A1" CR_TAB
4957 TINY_ADIW (%E0, %F0, 1) CR_TAB
4958 "st %0,__tmp_reg__", op, plen, -5)
4959 : avr_asm_len ("mov __tmp_reg__,%B1" CR_TAB
4960 TINY_ADIW (%E0, %F0, 1) CR_TAB
4961 "st %0,__tmp_reg__" CR_TAB
4962 TINY_SBIW (%E0, %F0, 1) CR_TAB
4963 "st %0, %A1", op, plen, -7);
4964 }
4965
4966 return !mem_volatile_p && reg_unused_after (insn, base)
4967 ? avr_asm_len ("st %0+,%A1" CR_TAB
4968 "st %0,%B1", op, plen, -2)
4969 : avr_asm_len (TINY_ADIW (%E0, %F0, 1) CR_TAB
4970 "st %0,%B1" CR_TAB
4971 "st -%0,%A1", op, plen, -4);
4972 }
4973
4974 static const char*
4975 avr_out_movhi_mr_r_reg_disp_tiny (rtx op[], int *plen)
4976 {
4977 rtx dest = op[0];
4978 rtx src = op[1];
4979 rtx base = XEXP (dest, 0);
4980 int reg_base = REGNO (XEXP (base, 0));
4981 int reg_src = true_regnum (src);
4982
4983 return reg_src == reg_base
4984 ? avr_asm_len ("mov __tmp_reg__,%A1" CR_TAB
4985 "mov __zero_reg__,%B1" CR_TAB
4986 TINY_ADIW (%I0, %J0, %o0+1) CR_TAB
4987 "st %b0,__zero_reg__" CR_TAB
4988 "st -%b0,__tmp_reg__" CR_TAB
4989 "clr __zero_reg__" CR_TAB
4990 TINY_SBIW (%I0, %J0, %o0), op, plen, -9)
4991
4992 : avr_asm_len (TINY_ADIW (%I0, %J0, %o0+1) CR_TAB
4993 "st %b0,%B1" CR_TAB
4994 "st -%b0,%A1" CR_TAB
4995 TINY_SBIW (%I0, %J0, %o0), op, plen, -6);
4996 }
4997
4998 static const char*
4999 avr_out_movhi_mr_r_post_inc_tiny (rtx op[], int *plen)
5000 {
5001 return avr_asm_len (TINY_ADIW (%I0, %J0, 1) CR_TAB
5002 "st %p0,%B1" CR_TAB
5003 "st -%p0,%A1" CR_TAB
5004 TINY_ADIW (%I0, %J0, 2), op, plen, -6);
5005 }
5006
5007 static const char*
5008 out_movhi_mr_r (rtx_insn *insn, rtx op[], int *plen)
5009 {
5010 rtx dest = op[0];
5011 rtx src = op[1];
5012 rtx base = XEXP (dest, 0);
5013 int reg_base = true_regnum (base);
5014 int reg_src = true_regnum (src);
5015 int mem_volatile_p;
5016
5017 /* "volatile" forces writing high-byte first (no-xmega) resp.
5018 low-byte first (xmega) even if less efficient, for correct
5019 operation with 16-bit I/O registers like. */
5020
5021 if (AVR_XMEGA)
5022 return avr_out_movhi_mr_r_xmega (insn, op, plen);
5023
5024 mem_volatile_p = MEM_VOLATILE_P (dest);
5025
5026 if (CONSTANT_ADDRESS_P (base))
5027 {
5028 int n_words = AVR_TINY ? 2 : 4;
5029 return optimize > 0 && io_address_operand (base, HImode)
5030 ? avr_asm_len ("out %i0+1,%B1" CR_TAB
5031 "out %i0,%A1", op, plen, -2)
5032
5033 : avr_asm_len ("sts %m0+1,%B1" CR_TAB
5034 "sts %m0,%A1", op, plen, -n_words);
5035 }
5036
5037 if (reg_base > 0)
5038 {
5039 if (AVR_TINY)
5040 return avr_out_movhi_mr_r_reg_no_disp_tiny (insn, op, plen);
5041
5042 if (reg_base != REG_X)
5043 return avr_asm_len ("std %0+1,%B1" CR_TAB
5044 "st %0,%A1", op, plen, -2);
5045
5046 if (reg_src == REG_X)
5047 /* "st X+,r26" and "st -X,r26" are undefined. */
5048 return !mem_volatile_p && reg_unused_after (insn, src)
5049 ? avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
5050 "st X,r26" CR_TAB
5051 "adiw r26,1" CR_TAB
5052 "st X,__tmp_reg__", op, plen, -4)
5053
5054 : avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
5055 "adiw r26,1" CR_TAB
5056 "st X,__tmp_reg__" CR_TAB
5057 "sbiw r26,1" CR_TAB
5058 "st X,r26", op, plen, -5);
5059
5060 return !mem_volatile_p && reg_unused_after (insn, base)
5061 ? avr_asm_len ("st X+,%A1" CR_TAB
5062 "st X,%B1", op, plen, -2)
5063 : avr_asm_len ("adiw r26,1" CR_TAB
5064 "st X,%B1" CR_TAB
5065 "st -X,%A1", op, plen, -3);
5066 }
5067 else if (GET_CODE (base) == PLUS)
5068 {
5069 int disp = INTVAL (XEXP (base, 1));
5070
5071 if (AVR_TINY)
5072 return avr_out_movhi_mr_r_reg_disp_tiny (op, plen);
5073
5074 reg_base = REGNO (XEXP (base, 0));
5075 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
5076 {
5077 if (reg_base != REG_Y)
5078 fatal_insn ("incorrect insn:",insn);
5079
5080 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))
5081 ? avr_asm_len ("adiw r28,%o0-62" CR_TAB
5082 "std Y+63,%B1" CR_TAB
5083 "std Y+62,%A1" CR_TAB
5084 "sbiw r28,%o0-62", op, plen, -4)
5085
5086 : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
5087 "sbci r29,hi8(-%o0)" CR_TAB
5088 "std Y+1,%B1" CR_TAB
5089 "st Y,%A1" CR_TAB
5090 "subi r28,lo8(%o0)" CR_TAB
5091 "sbci r29,hi8(%o0)", op, plen, -6);
5092 }
5093
5094 if (reg_base != REG_X)
5095 return avr_asm_len ("std %B0,%B1" CR_TAB
5096 "std %A0,%A1", op, plen, -2);
5097 /* (X + d) = R */
5098 return reg_src == REG_X
5099 ? avr_asm_len ("mov __tmp_reg__,r26" CR_TAB
5100 "mov __zero_reg__,r27" CR_TAB
5101 "adiw r26,%o0+1" CR_TAB
5102 "st X,__zero_reg__" CR_TAB
5103 "st -X,__tmp_reg__" CR_TAB
5104 "clr __zero_reg__" CR_TAB
5105 "sbiw r26,%o0", op, plen, -7)
5106
5107 : avr_asm_len ("adiw r26,%o0+1" CR_TAB
5108 "st X,%B1" CR_TAB
5109 "st -X,%A1" CR_TAB
5110 "sbiw r26,%o0", op, plen, -4);
5111 }
5112 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
5113 {
5114 return avr_asm_len ("st %0,%B1" CR_TAB
5115 "st %0,%A1", op, plen, -2);
5116 }
5117 else if (GET_CODE (base) == POST_INC) /* (R++) */
5118 {
5119 if (!mem_volatile_p)
5120 return avr_asm_len ("st %0,%A1" CR_TAB
5121 "st %0,%B1", op, plen, -2);
5122
5123 if (AVR_TINY)
5124 return avr_out_movhi_mr_r_post_inc_tiny (op, plen);
5125
5126 return REGNO (XEXP (base, 0)) == REG_X
5127 ? avr_asm_len ("adiw r26,1" CR_TAB
5128 "st X,%B1" CR_TAB
5129 "st -X,%A1" CR_TAB
5130 "adiw r26,2", op, plen, -4)
5131
5132 : avr_asm_len ("std %p0+1,%B1" CR_TAB
5133 "st %p0,%A1" CR_TAB
5134 "adiw %r0,2", op, plen, -3);
5135 }
5136 fatal_insn ("unknown move insn:",insn);
5137 return "";
5138 }
5139
5140 /* Return 1 if frame pointer for current function required. */
5141
5142 static bool
5143 avr_frame_pointer_required_p (void)
5144 {
5145 return (cfun->calls_alloca
5146 || cfun->calls_setjmp
5147 || cfun->has_nonlocal_label
5148 || crtl->args.info.nregs == 0
5149 || get_frame_size () > 0);
5150 }
5151
5152 /* Returns the condition of compare insn INSN, or UNKNOWN. */
5153
5154 static RTX_CODE
5155 compare_condition (rtx_insn *insn)
5156 {
5157 rtx_insn *next = next_real_insn (insn);
5158
5159 if (next && JUMP_P (next))
5160 {
5161 rtx pat = PATTERN (next);
5162 rtx src = SET_SRC (pat);
5163
5164 if (IF_THEN_ELSE == GET_CODE (src))
5165 return GET_CODE (XEXP (src, 0));
5166 }
5167
5168 return UNKNOWN;
5169 }
5170
5171
5172 /* Returns true iff INSN is a tst insn that only tests the sign. */
5173
5174 static bool
5175 compare_sign_p (rtx_insn *insn)
5176 {
5177 RTX_CODE cond = compare_condition (insn);
5178 return (cond == GE || cond == LT);
5179 }
5180
5181
5182 /* Returns true iff the next insn is a JUMP_INSN with a condition
5183 that needs to be swapped (GT, GTU, LE, LEU). */
5184
5185 static bool
5186 compare_diff_p (rtx_insn *insn)
5187 {
5188 RTX_CODE cond = compare_condition (insn);
5189 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
5190 }
5191
5192 /* Returns true iff INSN is a compare insn with the EQ or NE condition. */
5193
5194 static bool
5195 compare_eq_p (rtx_insn *insn)
5196 {
5197 RTX_CODE cond = compare_condition (insn);
5198 return (cond == EQ || cond == NE);
5199 }
5200
5201
5202 /* Output compare instruction
5203
5204 compare (XOP[0], XOP[1])
5205
5206 for a register XOP[0] and a compile-time constant XOP[1]. Return "".
5207 XOP[2] is an 8-bit scratch register as needed.
5208
5209 PLEN == NULL: Output instructions.
5210 PLEN != NULL: Set *PLEN to the length (in words) of the sequence.
5211 Don't output anything. */
5212
5213 const char*
5214 avr_out_compare (rtx_insn *insn, rtx *xop, int *plen)
5215 {
5216 /* Register to compare and value to compare against. */
5217 rtx xreg = xop[0];
5218 rtx xval = xop[1];
5219
5220 /* MODE of the comparison. */
5221 machine_mode mode;
5222
5223 /* Number of bytes to operate on. */
5224 int i, n_bytes = GET_MODE_SIZE (GET_MODE (xreg));
5225
5226 /* Value (0..0xff) held in clobber register xop[2] or -1 if unknown. */
5227 int clobber_val = -1;
5228
5229 /* Map fixed mode operands to integer operands with the same binary
5230 representation. They are easier to handle in the remainder. */
5231
5232 if (CONST_FIXED_P (xval))
5233 {
5234 xreg = avr_to_int_mode (xop[0]);
5235 xval = avr_to_int_mode (xop[1]);
5236 }
5237
5238 mode = GET_MODE (xreg);
5239
5240 gcc_assert (REG_P (xreg));
5241 gcc_assert ((CONST_INT_P (xval) && n_bytes <= 4)
5242 || (const_double_operand (xval, VOIDmode) && n_bytes == 8));
5243
5244 if (plen)
5245 *plen = 0;
5246
5247 /* Comparisons == +/-1 and != +/-1 can be done similar to camparing
5248 against 0 by ORing the bytes. This is one instruction shorter.
5249 Notice that 64-bit comparisons are always against reg:ALL8 18 (ACC_A)
5250 and therefore don't use this. */
5251
5252 if (!test_hard_reg_class (LD_REGS, xreg)
5253 && compare_eq_p (insn)
5254 && reg_unused_after (insn, xreg))
5255 {
5256 if (xval == const1_rtx)
5257 {
5258 avr_asm_len ("dec %A0" CR_TAB
5259 "or %A0,%B0", xop, plen, 2);
5260
5261 if (n_bytes >= 3)
5262 avr_asm_len ("or %A0,%C0", xop, plen, 1);
5263
5264 if (n_bytes >= 4)
5265 avr_asm_len ("or %A0,%D0", xop, plen, 1);
5266
5267 return "";
5268 }
5269 else if (xval == constm1_rtx)
5270 {
5271 if (n_bytes >= 4)
5272 avr_asm_len ("and %A0,%D0", xop, plen, 1);
5273
5274 if (n_bytes >= 3)
5275 avr_asm_len ("and %A0,%C0", xop, plen, 1);
5276
5277 return avr_asm_len ("and %A0,%B0" CR_TAB
5278 "com %A0", xop, plen, 2);
5279 }
5280 }
5281
5282 for (i = 0; i < n_bytes; i++)
5283 {
5284 /* We compare byte-wise. */
5285 rtx reg8 = simplify_gen_subreg (QImode, xreg, mode, i);
5286 rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
5287
5288 /* 8-bit value to compare with this byte. */
5289 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
5290
5291 /* Registers R16..R31 can operate with immediate. */
5292 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
5293
5294 xop[0] = reg8;
5295 xop[1] = gen_int_mode (val8, QImode);
5296
5297 /* Word registers >= R24 can use SBIW/ADIW with 0..63. */
5298
5299 if (i == 0
5300 && test_hard_reg_class (ADDW_REGS, reg8))
5301 {
5302 int val16 = trunc_int_for_mode (INTVAL (xval), HImode);
5303
5304 if (IN_RANGE (val16, 0, 63)
5305 && (val8 == 0
5306 || reg_unused_after (insn, xreg)))
5307 {
5308 if (AVR_TINY)
5309 avr_asm_len (TINY_SBIW (%A0, %B0, %1), xop, plen, 2);
5310 else
5311 avr_asm_len ("sbiw %0,%1", xop, plen, 1);
5312
5313 i++;
5314 continue;
5315 }
5316
5317 if (n_bytes == 2
5318 && IN_RANGE (val16, -63, -1)
5319 && compare_eq_p (insn)
5320 && reg_unused_after (insn, xreg))
5321 {
5322 return AVR_TINY
5323 ? avr_asm_len (TINY_ADIW (%A0, %B0, %n1), xop, plen, 2)
5324 : avr_asm_len ("adiw %0,%n1", xop, plen, 1);
5325 }
5326 }
5327
5328 /* Comparing against 0 is easy. */
5329
5330 if (val8 == 0)
5331 {
5332 avr_asm_len (i == 0
5333 ? "cp %0,__zero_reg__"
5334 : "cpc %0,__zero_reg__", xop, plen, 1);
5335 continue;
5336 }
5337
5338 /* Upper registers can compare and subtract-with-carry immediates.
5339 Notice that compare instructions do the same as respective subtract
5340 instruction; the only difference is that comparisons don't write
5341 the result back to the target register. */
5342
5343 if (ld_reg_p)
5344 {
5345 if (i == 0)
5346 {
5347 avr_asm_len ("cpi %0,%1", xop, plen, 1);
5348 continue;
5349 }
5350 else if (reg_unused_after (insn, xreg))
5351 {
5352 avr_asm_len ("sbci %0,%1", xop, plen, 1);
5353 continue;
5354 }
5355 }
5356
5357 /* Must load the value into the scratch register. */
5358
5359 gcc_assert (REG_P (xop[2]));
5360
5361 if (clobber_val != (int) val8)
5362 avr_asm_len ("ldi %2,%1", xop, plen, 1);
5363 clobber_val = (int) val8;
5364
5365 avr_asm_len (i == 0
5366 ? "cp %0,%2"
5367 : "cpc %0,%2", xop, plen, 1);
5368 }
5369
5370 return "";
5371 }
5372
5373
5374 /* Prepare operands of compare_const_di2 to be used with avr_out_compare. */
5375
5376 const char*
5377 avr_out_compare64 (rtx_insn *insn, rtx *op, int *plen)
5378 {
5379 rtx xop[3];
5380
5381 xop[0] = gen_rtx_REG (DImode, 18);
5382 xop[1] = op[0];
5383 xop[2] = op[1];
5384
5385 return avr_out_compare (insn, xop, plen);
5386 }
5387
5388 /* Output test instruction for HImode. */
5389
5390 const char*
5391 avr_out_tsthi (rtx_insn *insn, rtx *op, int *plen)
5392 {
5393 if (compare_sign_p (insn))
5394 {
5395 avr_asm_len ("tst %B0", op, plen, -1);
5396 }
5397 else if (reg_unused_after (insn, op[0])
5398 && compare_eq_p (insn))
5399 {
5400 /* Faster than sbiw if we can clobber the operand. */
5401 avr_asm_len ("or %A0,%B0", op, plen, -1);
5402 }
5403 else
5404 {
5405 avr_out_compare (insn, op, plen);
5406 }
5407
5408 return "";
5409 }
5410
5411
5412 /* Output test instruction for PSImode. */
5413
5414 const char*
5415 avr_out_tstpsi (rtx_insn *insn, rtx *op, int *plen)
5416 {
5417 if (compare_sign_p (insn))
5418 {
5419 avr_asm_len ("tst %C0", op, plen, -1);
5420 }
5421 else if (reg_unused_after (insn, op[0])
5422 && compare_eq_p (insn))
5423 {
5424 /* Faster than sbiw if we can clobber the operand. */
5425 avr_asm_len ("or %A0,%B0" CR_TAB
5426 "or %A0,%C0", op, plen, -2);
5427 }
5428 else
5429 {
5430 avr_out_compare (insn, op, plen);
5431 }
5432
5433 return "";
5434 }
5435
5436
5437 /* Output test instruction for SImode. */
5438
5439 const char*
5440 avr_out_tstsi (rtx_insn *insn, rtx *op, int *plen)
5441 {
5442 if (compare_sign_p (insn))
5443 {
5444 avr_asm_len ("tst %D0", op, plen, -1);
5445 }
5446 else if (reg_unused_after (insn, op[0])
5447 && compare_eq_p (insn))
5448 {
5449 /* Faster than sbiw if we can clobber the operand. */
5450 avr_asm_len ("or %A0,%B0" CR_TAB
5451 "or %A0,%C0" CR_TAB
5452 "or %A0,%D0", op, plen, -3);
5453 }
5454 else
5455 {
5456 avr_out_compare (insn, op, plen);
5457 }
5458
5459 return "";
5460 }
5461
5462
5463 /* Generate asm equivalent for various shifts. This only handles cases
5464 that are not already carefully hand-optimized in ?sh??i3_out.
5465
5466 OPERANDS[0] resp. %0 in TEMPL is the operand to be shifted.
5467 OPERANDS[2] is the shift count as CONST_INT, MEM or REG.
5468 OPERANDS[3] is a QImode scratch register from LD regs if
5469 available and SCRATCH, otherwise (no scratch available)
5470
5471 TEMPL is an assembler template that shifts by one position.
5472 T_LEN is the length of this template. */
5473
5474 void
5475 out_shift_with_cnt (const char *templ, rtx_insn *insn, rtx operands[],
5476 int *plen, int t_len)
5477 {
5478 bool second_label = true;
5479 bool saved_in_tmp = false;
5480 bool use_zero_reg = false;
5481 rtx op[5];
5482
5483 op[0] = operands[0];
5484 op[1] = operands[1];
5485 op[2] = operands[2];
5486 op[3] = operands[3];
5487
5488 if (plen)
5489 *plen = 0;
5490
5491 if (CONST_INT_P (operands[2]))
5492 {
5493 bool scratch = (GET_CODE (PATTERN (insn)) == PARALLEL
5494 && REG_P (operands[3]));
5495 int count = INTVAL (operands[2]);
5496 int max_len = 10; /* If larger than this, always use a loop. */
5497
5498 if (count <= 0)
5499 return;
5500
5501 if (count < 8 && !scratch)
5502 use_zero_reg = true;
5503
5504 if (optimize_size)
5505 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
5506
5507 if (t_len * count <= max_len)
5508 {
5509 /* Output shifts inline with no loop - faster. */
5510
5511 while (count-- > 0)
5512 avr_asm_len (templ, op, plen, t_len);
5513
5514 return;
5515 }
5516
5517 if (scratch)
5518 {
5519 avr_asm_len ("ldi %3,%2", op, plen, 1);
5520 }
5521 else if (use_zero_reg)
5522 {
5523 /* Hack to save one word: use __zero_reg__ as loop counter.
5524 Set one bit, then shift in a loop until it is 0 again. */
5525
5526 op[3] = zero_reg_rtx;
5527
5528 avr_asm_len ("set" CR_TAB
5529 "bld %3,%2-1", op, plen, 2);
5530 }
5531 else
5532 {
5533 /* No scratch register available, use one from LD_REGS (saved in
5534 __tmp_reg__) that doesn't overlap with registers to shift. */
5535
5536 op[3] = all_regs_rtx[((REGNO (op[0]) - 1) & 15) + 16];
5537 op[4] = tmp_reg_rtx;
5538 saved_in_tmp = true;
5539
5540 avr_asm_len ("mov %4,%3" CR_TAB
5541 "ldi %3,%2", op, plen, 2);
5542 }
5543
5544 second_label = false;
5545 }
5546 else if (MEM_P (op[2]))
5547 {
5548 rtx op_mov[2];
5549
5550 op_mov[0] = op[3] = tmp_reg_rtx;
5551 op_mov[1] = op[2];
5552
5553 out_movqi_r_mr (insn, op_mov, plen);
5554 }
5555 else if (register_operand (op[2], QImode))
5556 {
5557 op[3] = op[2];
5558
5559 if (!reg_unused_after (insn, op[2])
5560 || reg_overlap_mentioned_p (op[0], op[2]))
5561 {
5562 op[3] = tmp_reg_rtx;
5563 avr_asm_len ("mov %3,%2", op, plen, 1);
5564 }
5565 }
5566 else
5567 fatal_insn ("bad shift insn:", insn);
5568
5569 if (second_label)
5570 avr_asm_len ("rjmp 2f", op, plen, 1);
5571
5572 avr_asm_len ("1:", op, plen, 0);
5573 avr_asm_len (templ, op, plen, t_len);
5574
5575 if (second_label)
5576 avr_asm_len ("2:", op, plen, 0);
5577
5578 avr_asm_len (use_zero_reg ? "lsr %3" : "dec %3", op, plen, 1);
5579 avr_asm_len (second_label ? "brpl 1b" : "brne 1b", op, plen, 1);
5580
5581 if (saved_in_tmp)
5582 avr_asm_len ("mov %3,%4", op, plen, 1);
5583 }
5584
5585
5586 /* 8bit shift left ((char)x << i) */
5587
5588 const char *
5589 ashlqi3_out (rtx_insn *insn, rtx operands[], int *len)
5590 {
5591 if (GET_CODE (operands[2]) == CONST_INT)
5592 {
5593 int k;
5594
5595 if (!len)
5596 len = &k;
5597
5598 switch (INTVAL (operands[2]))
5599 {
5600 default:
5601 if (INTVAL (operands[2]) < 8)
5602 break;
5603
5604 *len = 1;
5605 return "clr %0";
5606
5607 case 1:
5608 *len = 1;
5609 return "lsl %0";
5610
5611 case 2:
5612 *len = 2;
5613 return ("lsl %0" CR_TAB
5614 "lsl %0");
5615
5616 case 3:
5617 *len = 3;
5618 return ("lsl %0" CR_TAB
5619 "lsl %0" CR_TAB
5620 "lsl %0");
5621
5622 case 4:
5623 if (test_hard_reg_class (LD_REGS, operands[0]))
5624 {
5625 *len = 2;
5626 return ("swap %0" CR_TAB
5627 "andi %0,0xf0");
5628 }
5629 *len = 4;
5630 return ("lsl %0" CR_TAB
5631 "lsl %0" CR_TAB
5632 "lsl %0" CR_TAB
5633 "lsl %0");
5634
5635 case 5:
5636 if (test_hard_reg_class (LD_REGS, operands[0]))
5637 {
5638 *len = 3;
5639 return ("swap %0" CR_TAB
5640 "lsl %0" CR_TAB
5641 "andi %0,0xe0");
5642 }
5643 *len = 5;
5644 return ("lsl %0" CR_TAB
5645 "lsl %0" CR_TAB
5646 "lsl %0" CR_TAB
5647 "lsl %0" CR_TAB
5648 "lsl %0");
5649
5650 case 6:
5651 if (test_hard_reg_class (LD_REGS, operands[0]))
5652 {
5653 *len = 4;
5654 return ("swap %0" CR_TAB
5655 "lsl %0" CR_TAB
5656 "lsl %0" CR_TAB
5657 "andi %0,0xc0");
5658 }
5659 *len = 6;
5660 return ("lsl %0" CR_TAB
5661 "lsl %0" CR_TAB
5662 "lsl %0" CR_TAB
5663 "lsl %0" CR_TAB
5664 "lsl %0" CR_TAB
5665 "lsl %0");
5666
5667 case 7:
5668 *len = 3;
5669 return ("ror %0" CR_TAB
5670 "clr %0" CR_TAB
5671 "ror %0");
5672 }
5673 }
5674 else if (CONSTANT_P (operands[2]))
5675 fatal_insn ("internal compiler error. Incorrect shift:", insn);
5676
5677 out_shift_with_cnt ("lsl %0",
5678 insn, operands, len, 1);
5679 return "";
5680 }
5681
5682
5683 /* 16bit shift left ((short)x << i) */
5684
5685 const char *
5686 ashlhi3_out (rtx_insn *insn, rtx operands[], int *len)
5687 {
5688 if (GET_CODE (operands[2]) == CONST_INT)
5689 {
5690 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
5691 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
5692 int k;
5693 int *t = len;
5694
5695 if (!len)
5696 len = &k;
5697
5698 switch (INTVAL (operands[2]))
5699 {
5700 default:
5701 if (INTVAL (operands[2]) < 16)
5702 break;
5703
5704 *len = 2;
5705 return ("clr %B0" CR_TAB
5706 "clr %A0");
5707
5708 case 4:
5709 if (optimize_size && scratch)
5710 break; /* 5 */
5711 if (ldi_ok)
5712 {
5713 *len = 6;
5714 return ("swap %A0" CR_TAB
5715 "swap %B0" CR_TAB
5716 "andi %B0,0xf0" CR_TAB
5717 "eor %B0,%A0" CR_TAB
5718 "andi %A0,0xf0" CR_TAB
5719 "eor %B0,%A0");
5720 }
5721 if (scratch)
5722 {
5723 *len = 7;
5724 return ("swap %A0" CR_TAB
5725 "swap %B0" CR_TAB
5726 "ldi %3,0xf0" CR_TAB
5727 "and %B0,%3" CR_TAB
5728 "eor %B0,%A0" CR_TAB
5729 "and %A0,%3" CR_TAB
5730 "eor %B0,%A0");
5731 }
5732 break; /* optimize_size ? 6 : 8 */
5733
5734 case 5:
5735 if (optimize_size)
5736 break; /* scratch ? 5 : 6 */
5737 if (ldi_ok)
5738 {
5739 *len = 8;
5740 return ("lsl %A0" CR_TAB
5741 "rol %B0" CR_TAB
5742 "swap %A0" CR_TAB
5743 "swap %B0" CR_TAB
5744 "andi %B0,0xf0" CR_TAB
5745 "eor %B0,%A0" CR_TAB
5746 "andi %A0,0xf0" CR_TAB
5747 "eor %B0,%A0");
5748 }
5749 if (scratch)
5750 {
5751 *len = 9;
5752 return ("lsl %A0" CR_TAB
5753 "rol %B0" CR_TAB
5754 "swap %A0" CR_TAB
5755 "swap %B0" CR_TAB
5756 "ldi %3,0xf0" CR_TAB
5757 "and %B0,%3" CR_TAB
5758 "eor %B0,%A0" CR_TAB
5759 "and %A0,%3" CR_TAB
5760 "eor %B0,%A0");
5761 }
5762 break; /* 10 */
5763
5764 case 6:
5765 if (optimize_size)
5766 break; /* scratch ? 5 : 6 */
5767 *len = 9;
5768 return ("clr __tmp_reg__" CR_TAB
5769 "lsr %B0" CR_TAB
5770 "ror %A0" CR_TAB
5771 "ror __tmp_reg__" CR_TAB
5772 "lsr %B0" CR_TAB
5773 "ror %A0" CR_TAB
5774 "ror __tmp_reg__" CR_TAB
5775 "mov %B0,%A0" CR_TAB
5776 "mov %A0,__tmp_reg__");
5777
5778 case 7:
5779 *len = 5;
5780 return ("lsr %B0" CR_TAB
5781 "mov %B0,%A0" CR_TAB
5782 "clr %A0" CR_TAB
5783 "ror %B0" CR_TAB
5784 "ror %A0");
5785
5786 case 8:
5787 return *len = 2, ("mov %B0,%A1" CR_TAB
5788 "clr %A0");
5789
5790 case 9:
5791 *len = 3;
5792 return ("mov %B0,%A0" CR_TAB
5793 "clr %A0" CR_TAB
5794 "lsl %B0");
5795
5796 case 10:
5797 *len = 4;
5798 return ("mov %B0,%A0" CR_TAB
5799 "clr %A0" CR_TAB
5800 "lsl %B0" CR_TAB
5801 "lsl %B0");
5802
5803 case 11:
5804 *len = 5;
5805 return ("mov %B0,%A0" CR_TAB
5806 "clr %A0" CR_TAB
5807 "lsl %B0" CR_TAB
5808 "lsl %B0" CR_TAB
5809 "lsl %B0");
5810
5811 case 12:
5812 if (ldi_ok)
5813 {
5814 *len = 4;
5815 return ("mov %B0,%A0" CR_TAB
5816 "clr %A0" CR_TAB
5817 "swap %B0" CR_TAB
5818 "andi %B0,0xf0");
5819 }
5820 if (scratch)
5821 {
5822 *len = 5;
5823 return ("mov %B0,%A0" CR_TAB
5824 "clr %A0" CR_TAB
5825 "swap %B0" CR_TAB
5826 "ldi %3,0xf0" CR_TAB
5827 "and %B0,%3");
5828 }
5829 *len = 6;
5830 return ("mov %B0,%A0" CR_TAB
5831 "clr %A0" CR_TAB
5832 "lsl %B0" CR_TAB
5833 "lsl %B0" CR_TAB
5834 "lsl %B0" CR_TAB
5835 "lsl %B0");
5836
5837 case 13:
5838 if (ldi_ok)
5839 {
5840 *len = 5;
5841 return ("mov %B0,%A0" CR_TAB
5842 "clr %A0" CR_TAB
5843 "swap %B0" CR_TAB
5844 "lsl %B0" CR_TAB
5845 "andi %B0,0xe0");
5846 }
5847 if (AVR_HAVE_MUL && scratch)
5848 {
5849 *len = 5;
5850 return ("ldi %3,0x20" CR_TAB
5851 "mul %A0,%3" CR_TAB
5852 "mov %B0,r0" CR_TAB
5853 "clr %A0" CR_TAB
5854 "clr __zero_reg__");
5855 }
5856 if (optimize_size && scratch)
5857 break; /* 5 */
5858 if (scratch)
5859 {
5860 *len = 6;
5861 return ("mov %B0,%A0" CR_TAB
5862 "clr %A0" CR_TAB
5863 "swap %B0" CR_TAB
5864 "lsl %B0" CR_TAB
5865 "ldi %3,0xe0" CR_TAB
5866 "and %B0,%3");
5867 }
5868 if (AVR_HAVE_MUL)
5869 {
5870 *len = 6;
5871 return ("set" CR_TAB
5872 "bld r1,5" CR_TAB
5873 "mul %A0,r1" CR_TAB
5874 "mov %B0,r0" CR_TAB
5875 "clr %A0" CR_TAB
5876 "clr __zero_reg__");
5877 }
5878 *len = 7;
5879 return ("mov %B0,%A0" CR_TAB
5880 "clr %A0" CR_TAB
5881 "lsl %B0" CR_TAB
5882 "lsl %B0" CR_TAB
5883 "lsl %B0" CR_TAB
5884 "lsl %B0" CR_TAB
5885 "lsl %B0");
5886
5887 case 14:
5888 if (AVR_HAVE_MUL && ldi_ok)
5889 {
5890 *len = 5;
5891 return ("ldi %B0,0x40" CR_TAB
5892 "mul %A0,%B0" CR_TAB
5893 "mov %B0,r0" CR_TAB
5894 "clr %A0" CR_TAB
5895 "clr __zero_reg__");
5896 }
5897 if (AVR_HAVE_MUL && scratch)
5898 {
5899 *len = 5;
5900 return ("ldi %3,0x40" CR_TAB
5901 "mul %A0,%3" CR_TAB
5902 "mov %B0,r0" CR_TAB
5903 "clr %A0" CR_TAB
5904 "clr __zero_reg__");
5905 }
5906 if (optimize_size && ldi_ok)
5907 {
5908 *len = 5;
5909 return ("mov %B0,%A0" CR_TAB
5910 "ldi %A0,6" "\n1:\t"
5911 "lsl %B0" CR_TAB
5912 "dec %A0" CR_TAB
5913 "brne 1b");
5914 }
5915 if (optimize_size && scratch)
5916 break; /* 5 */
5917 *len = 6;
5918 return ("clr %B0" CR_TAB
5919 "lsr %A0" CR_TAB
5920 "ror %B0" CR_TAB
5921 "lsr %A0" CR_TAB
5922 "ror %B0" CR_TAB
5923 "clr %A0");
5924
5925 case 15:
5926 *len = 4;
5927 return ("clr %B0" CR_TAB
5928 "lsr %A0" CR_TAB
5929 "ror %B0" CR_TAB
5930 "clr %A0");
5931 }
5932 len = t;
5933 }
5934 out_shift_with_cnt ("lsl %A0" CR_TAB
5935 "rol %B0", insn, operands, len, 2);
5936 return "";
5937 }
5938
5939
5940 /* 24-bit shift left */
5941
5942 const char*
5943 avr_out_ashlpsi3 (rtx_insn *insn, rtx *op, int *plen)
5944 {
5945 if (plen)
5946 *plen = 0;
5947
5948 if (CONST_INT_P (op[2]))
5949 {
5950 switch (INTVAL (op[2]))
5951 {
5952 default:
5953 if (INTVAL (op[2]) < 24)
5954 break;
5955
5956 return avr_asm_len ("clr %A0" CR_TAB
5957 "clr %B0" CR_TAB
5958 "clr %C0", op, plen, 3);
5959
5960 case 8:
5961 {
5962 int reg0 = REGNO (op[0]);
5963 int reg1 = REGNO (op[1]);
5964
5965 if (reg0 >= reg1)
5966 return avr_asm_len ("mov %C0,%B1" CR_TAB
5967 "mov %B0,%A1" CR_TAB
5968 "clr %A0", op, plen, 3);
5969 else
5970 return avr_asm_len ("clr %A0" CR_TAB
5971 "mov %B0,%A1" CR_TAB
5972 "mov %C0,%B1", op, plen, 3);
5973 }
5974
5975 case 16:
5976 {
5977 int reg0 = REGNO (op[0]);
5978 int reg1 = REGNO (op[1]);
5979
5980 if (reg0 + 2 != reg1)
5981 avr_asm_len ("mov %C0,%A0", op, plen, 1);
5982
5983 return avr_asm_len ("clr %B0" CR_TAB
5984 "clr %A0", op, plen, 2);
5985 }
5986
5987 case 23:
5988 return avr_asm_len ("clr %C0" CR_TAB
5989 "lsr %A0" CR_TAB
5990 "ror %C0" CR_TAB
5991 "clr %B0" CR_TAB
5992 "clr %A0", op, plen, 5);
5993 }
5994 }
5995
5996 out_shift_with_cnt ("lsl %A0" CR_TAB
5997 "rol %B0" CR_TAB
5998 "rol %C0", insn, op, plen, 3);
5999 return "";
6000 }
6001
6002
6003 /* 32bit shift left ((long)x << i) */
6004
6005 const char *
6006 ashlsi3_out (rtx_insn *insn, rtx operands[], int *len)
6007 {
6008 if (GET_CODE (operands[2]) == CONST_INT)
6009 {
6010 int k;
6011 int *t = len;
6012
6013 if (!len)
6014 len = &k;
6015
6016 switch (INTVAL (operands[2]))
6017 {
6018 default:
6019 if (INTVAL (operands[2]) < 32)
6020 break;
6021
6022 if (AVR_HAVE_MOVW)
6023 return *len = 3, ("clr %D0" CR_TAB
6024 "clr %C0" CR_TAB
6025 "movw %A0,%C0");
6026 *len = 4;
6027 return ("clr %D0" CR_TAB
6028 "clr %C0" CR_TAB
6029 "clr %B0" CR_TAB
6030 "clr %A0");
6031
6032 case 8:
6033 {
6034 int reg0 = true_regnum (operands[0]);
6035 int reg1 = true_regnum (operands[1]);
6036 *len = 4;
6037 if (reg0 >= reg1)
6038 return ("mov %D0,%C1" CR_TAB
6039 "mov %C0,%B1" CR_TAB
6040 "mov %B0,%A1" CR_TAB
6041 "clr %A0");
6042 else
6043 return ("clr %A0" CR_TAB
6044 "mov %B0,%A1" CR_TAB
6045 "mov %C0,%B1" CR_TAB
6046 "mov %D0,%C1");
6047 }
6048
6049 case 16:
6050 {
6051 int reg0 = true_regnum (operands[0]);
6052 int reg1 = true_regnum (operands[1]);
6053 if (reg0 + 2 == reg1)
6054 return *len = 2, ("clr %B0" CR_TAB
6055 "clr %A0");
6056 if (AVR_HAVE_MOVW)
6057 return *len = 3, ("movw %C0,%A1" CR_TAB
6058 "clr %B0" CR_TAB
6059 "clr %A0");
6060 else
6061 return *len = 4, ("mov %C0,%A1" CR_TAB
6062 "mov %D0,%B1" CR_TAB
6063 "clr %B0" CR_TAB
6064 "clr %A0");
6065 }
6066
6067 case 24:
6068 *len = 4;
6069 return ("mov %D0,%A1" CR_TAB
6070 "clr %C0" CR_TAB
6071 "clr %B0" CR_TAB
6072 "clr %A0");
6073
6074 case 31:
6075 *len = 6;
6076 return ("clr %D0" CR_TAB
6077 "lsr %A0" CR_TAB
6078 "ror %D0" CR_TAB
6079 "clr %C0" CR_TAB
6080 "clr %B0" CR_TAB
6081 "clr %A0");
6082 }
6083 len = t;
6084 }
6085 out_shift_with_cnt ("lsl %A0" CR_TAB
6086 "rol %B0" CR_TAB
6087 "rol %C0" CR_TAB
6088 "rol %D0", insn, operands, len, 4);
6089 return "";
6090 }
6091
6092 /* 8bit arithmetic shift right ((signed char)x >> i) */
6093
6094 const char *
6095 ashrqi3_out (rtx_insn *insn, rtx operands[], int *len)
6096 {
6097 if (GET_CODE (operands[2]) == CONST_INT)
6098 {
6099 int k;
6100
6101 if (!len)
6102 len = &k;
6103
6104 switch (INTVAL (operands[2]))
6105 {
6106 case 1:
6107 *len = 1;
6108 return "asr %0";
6109
6110 case 2:
6111 *len = 2;
6112 return ("asr %0" CR_TAB
6113 "asr %0");
6114
6115 case 3:
6116 *len = 3;
6117 return ("asr %0" CR_TAB
6118 "asr %0" CR_TAB
6119 "asr %0");
6120
6121 case 4:
6122 *len = 4;
6123 return ("asr %0" CR_TAB
6124 "asr %0" CR_TAB
6125 "asr %0" CR_TAB
6126 "asr %0");
6127
6128 case 5:
6129 *len = 5;
6130 return ("asr %0" CR_TAB
6131 "asr %0" CR_TAB
6132 "asr %0" CR_TAB
6133 "asr %0" CR_TAB
6134 "asr %0");
6135
6136 case 6:
6137 *len = 4;
6138 return ("bst %0,6" CR_TAB
6139 "lsl %0" CR_TAB
6140 "sbc %0,%0" CR_TAB
6141 "bld %0,0");
6142
6143 default:
6144 if (INTVAL (operands[2]) < 8)
6145 break;
6146
6147 /* fall through */
6148
6149 case 7:
6150 *len = 2;
6151 return ("lsl %0" CR_TAB
6152 "sbc %0,%0");
6153 }
6154 }
6155 else if (CONSTANT_P (operands[2]))
6156 fatal_insn ("internal compiler error. Incorrect shift:", insn);
6157
6158 out_shift_with_cnt ("asr %0",
6159 insn, operands, len, 1);
6160 return "";
6161 }
6162
6163
6164 /* 16bit arithmetic shift right ((signed short)x >> i) */
6165
6166 const char *
6167 ashrhi3_out (rtx_insn *insn, rtx operands[], int *len)
6168 {
6169 if (GET_CODE (operands[2]) == CONST_INT)
6170 {
6171 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
6172 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
6173 int k;
6174 int *t = len;
6175
6176 if (!len)
6177 len = &k;
6178
6179 switch (INTVAL (operands[2]))
6180 {
6181 case 4:
6182 case 5:
6183 /* XXX try to optimize this too? */
6184 break;
6185
6186 case 6:
6187 if (optimize_size)
6188 break; /* scratch ? 5 : 6 */
6189 *len = 8;
6190 return ("mov __tmp_reg__,%A0" CR_TAB
6191 "mov %A0,%B0" CR_TAB
6192 "lsl __tmp_reg__" CR_TAB
6193 "rol %A0" CR_TAB
6194 "sbc %B0,%B0" CR_TAB
6195 "lsl __tmp_reg__" CR_TAB
6196 "rol %A0" CR_TAB
6197 "rol %B0");
6198
6199 case 7:
6200 *len = 4;
6201 return ("lsl %A0" CR_TAB
6202 "mov %A0,%B0" CR_TAB
6203 "rol %A0" CR_TAB
6204 "sbc %B0,%B0");
6205
6206 case 8:
6207 {
6208 int reg0 = true_regnum (operands[0]);
6209 int reg1 = true_regnum (operands[1]);
6210
6211 if (reg0 == reg1)
6212 return *len = 3, ("mov %A0,%B0" CR_TAB
6213 "lsl %B0" CR_TAB
6214 "sbc %B0,%B0");
6215 else
6216 return *len = 4, ("mov %A0,%B1" CR_TAB
6217 "clr %B0" CR_TAB
6218 "sbrc %A0,7" CR_TAB
6219 "dec %B0");
6220 }
6221
6222 case 9:
6223 *len = 4;
6224 return ("mov %A0,%B0" CR_TAB
6225 "lsl %B0" CR_TAB
6226 "sbc %B0,%B0" CR_TAB
6227 "asr %A0");
6228
6229 case 10:
6230 *len = 5;
6231 return ("mov %A0,%B0" CR_TAB
6232 "lsl %B0" CR_TAB
6233 "sbc %B0,%B0" CR_TAB
6234 "asr %A0" CR_TAB
6235 "asr %A0");
6236
6237 case 11:
6238 if (AVR_HAVE_MUL && ldi_ok)
6239 {
6240 *len = 5;
6241 return ("ldi %A0,0x20" CR_TAB
6242 "muls %B0,%A0" CR_TAB
6243 "mov %A0,r1" CR_TAB
6244 "sbc %B0,%B0" CR_TAB
6245 "clr __zero_reg__");
6246 }
6247 if (optimize_size && scratch)
6248 break; /* 5 */
6249 *len = 6;
6250 return ("mov %A0,%B0" CR_TAB
6251 "lsl %B0" CR_TAB
6252 "sbc %B0,%B0" CR_TAB
6253 "asr %A0" CR_TAB
6254 "asr %A0" CR_TAB
6255 "asr %A0");
6256
6257 case 12:
6258 if (AVR_HAVE_MUL && ldi_ok)
6259 {
6260 *len = 5;
6261 return ("ldi %A0,0x10" CR_TAB
6262 "muls %B0,%A0" CR_TAB
6263 "mov %A0,r1" CR_TAB
6264 "sbc %B0,%B0" CR_TAB
6265 "clr __zero_reg__");
6266 }
6267 if (optimize_size && scratch)
6268 break; /* 5 */
6269 *len = 7;
6270 return ("mov %A0,%B0" CR_TAB
6271 "lsl %B0" CR_TAB
6272 "sbc %B0,%B0" CR_TAB
6273 "asr %A0" CR_TAB
6274 "asr %A0" CR_TAB
6275 "asr %A0" CR_TAB
6276 "asr %A0");
6277
6278 case 13:
6279 if (AVR_HAVE_MUL && ldi_ok)
6280 {
6281 *len = 5;
6282 return ("ldi %A0,0x08" CR_TAB
6283 "muls %B0,%A0" CR_TAB
6284 "mov %A0,r1" CR_TAB
6285 "sbc %B0,%B0" CR_TAB
6286 "clr __zero_reg__");
6287 }
6288 if (optimize_size)
6289 break; /* scratch ? 5 : 7 */
6290 *len = 8;
6291 return ("mov %A0,%B0" CR_TAB
6292 "lsl %B0" CR_TAB
6293 "sbc %B0,%B0" CR_TAB
6294 "asr %A0" CR_TAB
6295 "asr %A0" CR_TAB
6296 "asr %A0" CR_TAB
6297 "asr %A0" CR_TAB
6298 "asr %A0");
6299
6300 case 14:
6301 *len = 5;
6302 return ("lsl %B0" CR_TAB
6303 "sbc %A0,%A0" CR_TAB
6304 "lsl %B0" CR_TAB
6305 "mov %B0,%A0" CR_TAB
6306 "rol %A0");
6307
6308 default:
6309 if (INTVAL (operands[2]) < 16)
6310 break;
6311
6312 /* fall through */
6313
6314 case 15:
6315 return *len = 3, ("lsl %B0" CR_TAB
6316 "sbc %A0,%A0" CR_TAB
6317 "mov %B0,%A0");
6318 }
6319 len = t;
6320 }
6321 out_shift_with_cnt ("asr %B0" CR_TAB
6322 "ror %A0", insn, operands, len, 2);
6323 return "";
6324 }
6325
6326
6327 /* 24-bit arithmetic shift right */
6328
6329 const char*
6330 avr_out_ashrpsi3 (rtx_insn *insn, rtx *op, int *plen)
6331 {
6332 int dest = REGNO (op[0]);
6333 int src = REGNO (op[1]);
6334
6335 if (CONST_INT_P (op[2]))
6336 {
6337 if (plen)
6338 *plen = 0;
6339
6340 switch (INTVAL (op[2]))
6341 {
6342 case 8:
6343 if (dest <= src)
6344 return avr_asm_len ("mov %A0,%B1" CR_TAB
6345 "mov %B0,%C1" CR_TAB
6346 "clr %C0" CR_TAB
6347 "sbrc %B0,7" CR_TAB
6348 "dec %C0", op, plen, 5);
6349 else
6350 return avr_asm_len ("clr %C0" CR_TAB
6351 "sbrc %C1,7" CR_TAB
6352 "dec %C0" CR_TAB
6353 "mov %B0,%C1" CR_TAB
6354 "mov %A0,%B1", op, plen, 5);
6355
6356 case 16:
6357 if (dest != src + 2)
6358 avr_asm_len ("mov %A0,%C1", op, plen, 1);
6359
6360 return avr_asm_len ("clr %B0" CR_TAB
6361 "sbrc %A0,7" CR_TAB
6362 "com %B0" CR_TAB
6363 "mov %C0,%B0", op, plen, 4);
6364
6365 default:
6366 if (INTVAL (op[2]) < 24)
6367 break;
6368
6369 /* fall through */
6370
6371 case 23:
6372 return avr_asm_len ("lsl %C0" CR_TAB
6373 "sbc %A0,%A0" CR_TAB
6374 "mov %B0,%A0" CR_TAB
6375 "mov %C0,%A0", op, plen, 4);
6376 } /* switch */
6377 }
6378
6379 out_shift_with_cnt ("asr %C0" CR_TAB
6380 "ror %B0" CR_TAB
6381 "ror %A0", insn, op, plen, 3);
6382 return "";
6383 }
6384
6385
6386 /* 32-bit arithmetic shift right ((signed long)x >> i) */
6387
6388 const char *
6389 ashrsi3_out (rtx_insn *insn, rtx operands[], int *len)
6390 {
6391 if (GET_CODE (operands[2]) == CONST_INT)
6392 {
6393 int k;
6394 int *t = len;
6395
6396 if (!len)
6397 len = &k;
6398
6399 switch (INTVAL (operands[2]))
6400 {
6401 case 8:
6402 {
6403 int reg0 = true_regnum (operands[0]);
6404 int reg1 = true_regnum (operands[1]);
6405 *len=6;
6406 if (reg0 <= reg1)
6407 return ("mov %A0,%B1" CR_TAB
6408 "mov %B0,%C1" CR_TAB
6409 "mov %C0,%D1" CR_TAB
6410 "clr %D0" CR_TAB
6411 "sbrc %C0,7" CR_TAB
6412 "dec %D0");
6413 else
6414 return ("clr %D0" CR_TAB
6415 "sbrc %D1,7" CR_TAB
6416 "dec %D0" CR_TAB
6417 "mov %C0,%D1" CR_TAB
6418 "mov %B0,%C1" CR_TAB
6419 "mov %A0,%B1");
6420 }
6421
6422 case 16:
6423 {
6424 int reg0 = true_regnum (operands[0]);
6425 int reg1 = true_regnum (operands[1]);
6426
6427 if (reg0 == reg1 + 2)
6428 return *len = 4, ("clr %D0" CR_TAB
6429 "sbrc %B0,7" CR_TAB
6430 "com %D0" CR_TAB
6431 "mov %C0,%D0");
6432 if (AVR_HAVE_MOVW)
6433 return *len = 5, ("movw %A0,%C1" CR_TAB
6434 "clr %D0" CR_TAB
6435 "sbrc %B0,7" CR_TAB
6436 "com %D0" CR_TAB
6437 "mov %C0,%D0");
6438 else
6439 return *len = 6, ("mov %B0,%D1" CR_TAB
6440 "mov %A0,%C1" CR_TAB
6441 "clr %D0" CR_TAB
6442 "sbrc %B0,7" CR_TAB
6443 "com %D0" CR_TAB
6444 "mov %C0,%D0");
6445 }
6446
6447 case 24:
6448 return *len = 6, ("mov %A0,%D1" CR_TAB
6449 "clr %D0" CR_TAB
6450 "sbrc %A0,7" CR_TAB
6451 "com %D0" CR_TAB
6452 "mov %B0,%D0" CR_TAB
6453 "mov %C0,%D0");
6454
6455 default:
6456 if (INTVAL (operands[2]) < 32)
6457 break;
6458
6459 /* fall through */
6460
6461 case 31:
6462 if (AVR_HAVE_MOVW)
6463 return *len = 4, ("lsl %D0" CR_TAB
6464 "sbc %A0,%A0" CR_TAB
6465 "mov %B0,%A0" CR_TAB
6466 "movw %C0,%A0");
6467 else
6468 return *len = 5, ("lsl %D0" CR_TAB
6469 "sbc %A0,%A0" CR_TAB
6470 "mov %B0,%A0" CR_TAB
6471 "mov %C0,%A0" CR_TAB
6472 "mov %D0,%A0");
6473 }
6474 len = t;
6475 }
6476 out_shift_with_cnt ("asr %D0" CR_TAB
6477 "ror %C0" CR_TAB
6478 "ror %B0" CR_TAB
6479 "ror %A0", insn, operands, len, 4);
6480 return "";
6481 }
6482
6483 /* 8-bit logic shift right ((unsigned char)x >> i) */
6484
6485 const char *
6486 lshrqi3_out (rtx_insn *insn, rtx operands[], int *len)
6487 {
6488 if (GET_CODE (operands[2]) == CONST_INT)
6489 {
6490 int k;
6491
6492 if (!len)
6493 len = &k;
6494
6495 switch (INTVAL (operands[2]))
6496 {
6497 default:
6498 if (INTVAL (operands[2]) < 8)
6499 break;
6500
6501 *len = 1;
6502 return "clr %0";
6503
6504 case 1:
6505 *len = 1;
6506 return "lsr %0";
6507
6508 case 2:
6509 *len = 2;
6510 return ("lsr %0" CR_TAB
6511 "lsr %0");
6512 case 3:
6513 *len = 3;
6514 return ("lsr %0" CR_TAB
6515 "lsr %0" CR_TAB
6516 "lsr %0");
6517
6518 case 4:
6519 if (test_hard_reg_class (LD_REGS, operands[0]))
6520 {
6521 *len=2;
6522 return ("swap %0" CR_TAB
6523 "andi %0,0x0f");
6524 }
6525 *len = 4;
6526 return ("lsr %0" CR_TAB
6527 "lsr %0" CR_TAB
6528 "lsr %0" CR_TAB
6529 "lsr %0");
6530
6531 case 5:
6532 if (test_hard_reg_class (LD_REGS, operands[0]))
6533 {
6534 *len = 3;
6535 return ("swap %0" CR_TAB
6536 "lsr %0" CR_TAB
6537 "andi %0,0x7");
6538 }
6539 *len = 5;
6540 return ("lsr %0" CR_TAB
6541 "lsr %0" CR_TAB
6542 "lsr %0" CR_TAB
6543 "lsr %0" CR_TAB
6544 "lsr %0");
6545
6546 case 6:
6547 if (test_hard_reg_class (LD_REGS, operands[0]))
6548 {
6549 *len = 4;
6550 return ("swap %0" CR_TAB
6551 "lsr %0" CR_TAB
6552 "lsr %0" CR_TAB
6553 "andi %0,0x3");
6554 }
6555 *len = 6;
6556 return ("lsr %0" CR_TAB
6557 "lsr %0" CR_TAB
6558 "lsr %0" CR_TAB
6559 "lsr %0" CR_TAB
6560 "lsr %0" CR_TAB
6561 "lsr %0");
6562
6563 case 7:
6564 *len = 3;
6565 return ("rol %0" CR_TAB
6566 "clr %0" CR_TAB
6567 "rol %0");
6568 }
6569 }
6570 else if (CONSTANT_P (operands[2]))
6571 fatal_insn ("internal compiler error. Incorrect shift:", insn);
6572
6573 out_shift_with_cnt ("lsr %0",
6574 insn, operands, len, 1);
6575 return "";
6576 }
6577
6578 /* 16-bit logic shift right ((unsigned short)x >> i) */
6579
6580 const char *
6581 lshrhi3_out (rtx_insn *insn, rtx operands[], int *len)
6582 {
6583 if (GET_CODE (operands[2]) == CONST_INT)
6584 {
6585 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
6586 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
6587 int k;
6588 int *t = len;
6589
6590 if (!len)
6591 len = &k;
6592
6593 switch (INTVAL (operands[2]))
6594 {
6595 default:
6596 if (INTVAL (operands[2]) < 16)
6597 break;
6598
6599 *len = 2;
6600 return ("clr %B0" CR_TAB
6601 "clr %A0");
6602
6603 case 4:
6604 if (optimize_size && scratch)
6605 break; /* 5 */
6606 if (ldi_ok)
6607 {
6608 *len = 6;
6609 return ("swap %B0" CR_TAB
6610 "swap %A0" CR_TAB
6611 "andi %A0,0x0f" CR_TAB
6612 "eor %A0,%B0" CR_TAB
6613 "andi %B0,0x0f" CR_TAB
6614 "eor %A0,%B0");
6615 }
6616 if (scratch)
6617 {
6618 *len = 7;
6619 return ("swap %B0" CR_TAB
6620 "swap %A0" CR_TAB
6621 "ldi %3,0x0f" CR_TAB
6622 "and %A0,%3" CR_TAB
6623 "eor %A0,%B0" CR_TAB
6624 "and %B0,%3" CR_TAB
6625 "eor %A0,%B0");
6626 }
6627 break; /* optimize_size ? 6 : 8 */
6628
6629 case 5:
6630 if (optimize_size)
6631 break; /* scratch ? 5 : 6 */
6632 if (ldi_ok)
6633 {
6634 *len = 8;
6635 return ("lsr %B0" CR_TAB
6636 "ror %A0" CR_TAB
6637 "swap %B0" CR_TAB
6638 "swap %A0" CR_TAB
6639 "andi %A0,0x0f" CR_TAB
6640 "eor %A0,%B0" CR_TAB
6641 "andi %B0,0x0f" CR_TAB
6642 "eor %A0,%B0");
6643 }
6644 if (scratch)
6645 {
6646 *len = 9;
6647 return ("lsr %B0" CR_TAB
6648 "ror %A0" CR_TAB
6649 "swap %B0" CR_TAB
6650 "swap %A0" CR_TAB
6651 "ldi %3,0x0f" CR_TAB
6652 "and %A0,%3" CR_TAB
6653 "eor %A0,%B0" CR_TAB
6654 "and %B0,%3" CR_TAB
6655 "eor %A0,%B0");
6656 }
6657 break; /* 10 */
6658
6659 case 6:
6660 if (optimize_size)
6661 break; /* scratch ? 5 : 6 */
6662 *len = 9;
6663 return ("clr __tmp_reg__" CR_TAB
6664 "lsl %A0" CR_TAB
6665 "rol %B0" CR_TAB
6666 "rol __tmp_reg__" CR_TAB
6667 "lsl %A0" CR_TAB
6668 "rol %B0" CR_TAB
6669 "rol __tmp_reg__" CR_TAB
6670 "mov %A0,%B0" CR_TAB
6671 "mov %B0,__tmp_reg__");
6672
6673 case 7:
6674 *len = 5;
6675 return ("lsl %A0" CR_TAB
6676 "mov %A0,%B0" CR_TAB
6677 "rol %A0" CR_TAB
6678 "sbc %B0,%B0" CR_TAB
6679 "neg %B0");
6680
6681 case 8:
6682 return *len = 2, ("mov %A0,%B1" CR_TAB
6683 "clr %B0");
6684
6685 case 9:
6686 *len = 3;
6687 return ("mov %A0,%B0" CR_TAB
6688 "clr %B0" CR_TAB
6689 "lsr %A0");
6690
6691 case 10:
6692 *len = 4;
6693 return ("mov %A0,%B0" CR_TAB
6694 "clr %B0" CR_TAB
6695 "lsr %A0" CR_TAB
6696 "lsr %A0");
6697
6698 case 11:
6699 *len = 5;
6700 return ("mov %A0,%B0" CR_TAB
6701 "clr %B0" CR_TAB
6702 "lsr %A0" CR_TAB
6703 "lsr %A0" CR_TAB
6704 "lsr %A0");
6705
6706 case 12:
6707 if (ldi_ok)
6708 {
6709 *len = 4;
6710 return ("mov %A0,%B0" CR_TAB
6711 "clr %B0" CR_TAB
6712 "swap %A0" CR_TAB
6713 "andi %A0,0x0f");
6714 }
6715 if (scratch)
6716 {
6717 *len = 5;
6718 return ("mov %A0,%B0" CR_TAB
6719 "clr %B0" CR_TAB
6720 "swap %A0" CR_TAB
6721 "ldi %3,0x0f" CR_TAB
6722 "and %A0,%3");
6723 }
6724 *len = 6;
6725 return ("mov %A0,%B0" CR_TAB
6726 "clr %B0" CR_TAB
6727 "lsr %A0" CR_TAB
6728 "lsr %A0" CR_TAB
6729 "lsr %A0" CR_TAB
6730 "lsr %A0");
6731
6732 case 13:
6733 if (ldi_ok)
6734 {
6735 *len = 5;
6736 return ("mov %A0,%B0" CR_TAB
6737 "clr %B0" CR_TAB
6738 "swap %A0" CR_TAB
6739 "lsr %A0" CR_TAB
6740 "andi %A0,0x07");
6741 }
6742 if (AVR_HAVE_MUL && scratch)
6743 {
6744 *len = 5;
6745 return ("ldi %3,0x08" CR_TAB
6746 "mul %B0,%3" CR_TAB
6747 "mov %A0,r1" CR_TAB
6748 "clr %B0" CR_TAB
6749 "clr __zero_reg__");
6750 }
6751 if (optimize_size && scratch)
6752 break; /* 5 */
6753 if (scratch)
6754 {
6755 *len = 6;
6756 return ("mov %A0,%B0" CR_TAB
6757 "clr %B0" CR_TAB
6758 "swap %A0" CR_TAB
6759 "lsr %A0" CR_TAB
6760 "ldi %3,0x07" CR_TAB
6761 "and %A0,%3");
6762 }
6763 if (AVR_HAVE_MUL)
6764 {
6765 *len = 6;
6766 return ("set" CR_TAB
6767 "bld r1,3" CR_TAB
6768 "mul %B0,r1" CR_TAB
6769 "mov %A0,r1" CR_TAB
6770 "clr %B0" CR_TAB
6771 "clr __zero_reg__");
6772 }
6773 *len = 7;
6774 return ("mov %A0,%B0" CR_TAB
6775 "clr %B0" CR_TAB
6776 "lsr %A0" CR_TAB
6777 "lsr %A0" CR_TAB
6778 "lsr %A0" CR_TAB
6779 "lsr %A0" CR_TAB
6780 "lsr %A0");
6781
6782 case 14:
6783 if (AVR_HAVE_MUL && ldi_ok)
6784 {
6785 *len = 5;
6786 return ("ldi %A0,0x04" CR_TAB
6787 "mul %B0,%A0" CR_TAB
6788 "mov %A0,r1" CR_TAB
6789 "clr %B0" CR_TAB
6790 "clr __zero_reg__");
6791 }
6792 if (AVR_HAVE_MUL && scratch)
6793 {
6794 *len = 5;
6795 return ("ldi %3,0x04" CR_TAB
6796 "mul %B0,%3" CR_TAB
6797 "mov %A0,r1" CR_TAB
6798 "clr %B0" CR_TAB
6799 "clr __zero_reg__");
6800 }
6801 if (optimize_size && ldi_ok)
6802 {
6803 *len = 5;
6804 return ("mov %A0,%B0" CR_TAB
6805 "ldi %B0,6" "\n1:\t"
6806 "lsr %A0" CR_TAB
6807 "dec %B0" CR_TAB
6808 "brne 1b");
6809 }
6810 if (optimize_size && scratch)
6811 break; /* 5 */
6812 *len = 6;
6813 return ("clr %A0" CR_TAB
6814 "lsl %B0" CR_TAB
6815 "rol %A0" CR_TAB
6816 "lsl %B0" CR_TAB
6817 "rol %A0" CR_TAB
6818 "clr %B0");
6819
6820 case 15:
6821 *len = 4;
6822 return ("clr %A0" CR_TAB
6823 "lsl %B0" CR_TAB
6824 "rol %A0" CR_TAB
6825 "clr %B0");
6826 }
6827 len = t;
6828 }
6829 out_shift_with_cnt ("lsr %B0" CR_TAB
6830 "ror %A0", insn, operands, len, 2);
6831 return "";
6832 }
6833
6834
6835 /* 24-bit logic shift right */
6836
6837 const char*
6838 avr_out_lshrpsi3 (rtx_insn *insn, rtx *op, int *plen)
6839 {
6840 int dest = REGNO (op[0]);
6841 int src = REGNO (op[1]);
6842
6843 if (CONST_INT_P (op[2]))
6844 {
6845 if (plen)
6846 *plen = 0;
6847
6848 switch (INTVAL (op[2]))
6849 {
6850 case 8:
6851 if (dest <= src)
6852 return avr_asm_len ("mov %A0,%B1" CR_TAB
6853 "mov %B0,%C1" CR_TAB
6854 "clr %C0", op, plen, 3);
6855 else
6856 return avr_asm_len ("clr %C0" CR_TAB
6857 "mov %B0,%C1" CR_TAB
6858 "mov %A0,%B1", op, plen, 3);
6859
6860 case 16:
6861 if (dest != src + 2)
6862 avr_asm_len ("mov %A0,%C1", op, plen, 1);
6863
6864 return avr_asm_len ("clr %B0" CR_TAB
6865 "clr %C0", op, plen, 2);
6866
6867 default:
6868 if (INTVAL (op[2]) < 24)
6869 break;
6870
6871 /* fall through */
6872
6873 case 23:
6874 return avr_asm_len ("clr %A0" CR_TAB
6875 "sbrc %C0,7" CR_TAB
6876 "inc %A0" CR_TAB
6877 "clr %B0" CR_TAB
6878 "clr %C0", op, plen, 5);
6879 } /* switch */
6880 }
6881
6882 out_shift_with_cnt ("lsr %C0" CR_TAB
6883 "ror %B0" CR_TAB
6884 "ror %A0", insn, op, plen, 3);
6885 return "";
6886 }
6887
6888
6889 /* 32-bit logic shift right ((unsigned int)x >> i) */
6890
6891 const char *
6892 lshrsi3_out (rtx_insn *insn, rtx operands[], int *len)
6893 {
6894 if (GET_CODE (operands[2]) == CONST_INT)
6895 {
6896 int k;
6897 int *t = len;
6898
6899 if (!len)
6900 len = &k;
6901
6902 switch (INTVAL (operands[2]))
6903 {
6904 default:
6905 if (INTVAL (operands[2]) < 32)
6906 break;
6907
6908 if (AVR_HAVE_MOVW)
6909 return *len = 3, ("clr %D0" CR_TAB
6910 "clr %C0" CR_TAB
6911 "movw %A0,%C0");
6912 *len = 4;
6913 return ("clr %D0" CR_TAB
6914 "clr %C0" CR_TAB
6915 "clr %B0" CR_TAB
6916 "clr %A0");
6917
6918 case 8:
6919 {
6920 int reg0 = true_regnum (operands[0]);
6921 int reg1 = true_regnum (operands[1]);
6922 *len = 4;
6923 if (reg0 <= reg1)
6924 return ("mov %A0,%B1" CR_TAB
6925 "mov %B0,%C1" CR_TAB
6926 "mov %C0,%D1" CR_TAB
6927 "clr %D0");
6928 else
6929 return ("clr %D0" CR_TAB
6930 "mov %C0,%D1" CR_TAB
6931 "mov %B0,%C1" CR_TAB
6932 "mov %A0,%B1");
6933 }
6934
6935 case 16:
6936 {
6937 int reg0 = true_regnum (operands[0]);
6938 int reg1 = true_regnum (operands[1]);
6939
6940 if (reg0 == reg1 + 2)
6941 return *len = 2, ("clr %C0" CR_TAB
6942 "clr %D0");
6943 if (AVR_HAVE_MOVW)
6944 return *len = 3, ("movw %A0,%C1" CR_TAB
6945 "clr %C0" CR_TAB
6946 "clr %D0");
6947 else
6948 return *len = 4, ("mov %B0,%D1" CR_TAB
6949 "mov %A0,%C1" CR_TAB
6950 "clr %C0" CR_TAB
6951 "clr %D0");
6952 }
6953
6954 case 24:
6955 return *len = 4, ("mov %A0,%D1" CR_TAB
6956 "clr %B0" CR_TAB
6957 "clr %C0" CR_TAB
6958 "clr %D0");
6959
6960 case 31:
6961 *len = 6;
6962 return ("clr %A0" CR_TAB
6963 "sbrc %D0,7" CR_TAB
6964 "inc %A0" CR_TAB
6965 "clr %B0" CR_TAB
6966 "clr %C0" CR_TAB
6967 "clr %D0");
6968 }
6969 len = t;
6970 }
6971 out_shift_with_cnt ("lsr %D0" CR_TAB
6972 "ror %C0" CR_TAB
6973 "ror %B0" CR_TAB
6974 "ror %A0", insn, operands, len, 4);
6975 return "";
6976 }
6977
6978
6979 /* Output addition of register XOP[0] and compile time constant XOP[2].
6980 CODE == PLUS: perform addition by using ADD instructions or
6981 CODE == MINUS: perform addition by using SUB instructions:
6982
6983 XOP[0] = XOP[0] + XOP[2]
6984
6985 Or perform addition/subtraction with register XOP[2] depending on CODE:
6986
6987 XOP[0] = XOP[0] +/- XOP[2]
6988
6989 If PLEN == NULL, print assembler instructions to perform the operation;
6990 otherwise, set *PLEN to the length of the instruction sequence (in words)
6991 printed with PLEN == NULL. XOP[3] is an 8-bit scratch register or NULL_RTX.
6992 Set *PCC to effect on cc0 according to respective CC_* insn attribute.
6993
6994 CODE_SAT == UNKNOWN: Perform ordinary, non-saturating operation.
6995 CODE_SAT != UNKNOWN: Perform operation and saturate according to CODE_SAT.
6996 If CODE_SAT != UNKNOWN then SIGN contains the sign of the summand resp.
6997 the subtrahend in the original insn, provided it is a compile time constant.
6998 In all other cases, SIGN is 0.
6999
7000 If OUT_LABEL is true, print the final 0: label which is needed for
7001 saturated addition / subtraction. The only case where OUT_LABEL = false
7002 is useful is for saturated addition / subtraction performed during
7003 fixed-point rounding, cf. `avr_out_round'. */
7004
7005 static void
7006 avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc,
7007 enum rtx_code code_sat, int sign, bool out_label)
7008 {
7009 /* MODE of the operation. */
7010 machine_mode mode = GET_MODE (xop[0]);
7011
7012 /* INT_MODE of the same size. */
7013 machine_mode imode = int_mode_for_mode (mode);
7014
7015 /* Number of bytes to operate on. */
7016 int i, n_bytes = GET_MODE_SIZE (mode);
7017
7018 /* Value (0..0xff) held in clobber register op[3] or -1 if unknown. */
7019 int clobber_val = -1;
7020
7021 /* op[0]: 8-bit destination register
7022 op[1]: 8-bit const int
7023 op[2]: 8-bit scratch register */
7024 rtx op[3];
7025
7026 /* Started the operation? Before starting the operation we may skip
7027 adding 0. This is no more true after the operation started because
7028 carry must be taken into account. */
7029 bool started = false;
7030
7031 /* Value to add. There are two ways to add VAL: R += VAL and R -= -VAL. */
7032 rtx xval = xop[2];
7033
7034 /* Output a BRVC instruction. Only needed with saturation. */
7035 bool out_brvc = true;
7036
7037 if (plen)
7038 *plen = 0;
7039
7040 if (REG_P (xop[2]))
7041 {
7042 *pcc = MINUS == code ? (int) CC_SET_CZN : (int) CC_CLOBBER;
7043
7044 for (i = 0; i < n_bytes; i++)
7045 {
7046 /* We operate byte-wise on the destination. */
7047 op[0] = simplify_gen_subreg (QImode, xop[0], mode, i);
7048 op[1] = simplify_gen_subreg (QImode, xop[2], mode, i);
7049
7050 if (i == 0)
7051 avr_asm_len (code == PLUS ? "add %0,%1" : "sub %0,%1",
7052 op, plen, 1);
7053 else
7054 avr_asm_len (code == PLUS ? "adc %0,%1" : "sbc %0,%1",
7055 op, plen, 1);
7056 }
7057
7058 if (reg_overlap_mentioned_p (xop[0], xop[2]))
7059 {
7060 gcc_assert (REGNO (xop[0]) == REGNO (xop[2]));
7061
7062 if (MINUS == code)
7063 return;
7064 }
7065
7066 goto saturate;
7067 }
7068
7069 /* Except in the case of ADIW with 16-bit register (see below)
7070 addition does not set cc0 in a usable way. */
7071
7072 *pcc = (MINUS == code) ? CC_SET_CZN : CC_CLOBBER;
7073
7074 if (CONST_FIXED_P (xval))
7075 xval = avr_to_int_mode (xval);
7076
7077 /* Adding/Subtracting zero is a no-op. */
7078
7079 if (xval == const0_rtx)
7080 {
7081 *pcc = CC_NONE;
7082 return;
7083 }
7084
7085 if (MINUS == code)
7086 xval = simplify_unary_operation (NEG, imode, xval, imode);
7087
7088 op[2] = xop[3];
7089
7090 if (SS_PLUS == code_sat && MINUS == code
7091 && sign < 0
7092 && 0x80 == (INTVAL (simplify_gen_subreg (QImode, xval, imode, n_bytes-1))
7093 & GET_MODE_MASK (QImode)))
7094 {
7095 /* We compute x + 0x80 by means of SUB instructions. We negated the
7096 constant subtrahend above and are left with x - (-128) so that we
7097 need something like SUBI r,128 which does not exist because SUBI sets
7098 V according to the sign of the subtrahend. Notice the only case
7099 where this must be done is when NEG overflowed in case [2s] because
7100 the V computation needs the right sign of the subtrahend. */
7101
7102 rtx msb = simplify_gen_subreg (QImode, xop[0], mode, n_bytes-1);
7103
7104 avr_asm_len ("subi %0,128" CR_TAB
7105 "brmi 0f", &msb, plen, 2);
7106 out_brvc = false;
7107
7108 goto saturate;
7109 }
7110
7111 for (i = 0; i < n_bytes; i++)
7112 {
7113 /* We operate byte-wise on the destination. */
7114 rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
7115 rtx xval8 = simplify_gen_subreg (QImode, xval, imode, i);
7116
7117 /* 8-bit value to operate with this byte. */
7118 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
7119
7120 /* Registers R16..R31 can operate with immediate. */
7121 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
7122
7123 op[0] = reg8;
7124 op[1] = gen_int_mode (val8, QImode);
7125
7126 /* To get usable cc0 no low-bytes must have been skipped. */
7127
7128 if (i && !started)
7129 *pcc = CC_CLOBBER;
7130
7131 if (!started
7132 && i % 2 == 0
7133 && i + 2 <= n_bytes
7134 && test_hard_reg_class (ADDW_REGS, reg8))
7135 {
7136 rtx xval16 = simplify_gen_subreg (HImode, xval, imode, i);
7137 unsigned int val16 = UINTVAL (xval16) & GET_MODE_MASK (HImode);
7138
7139 /* Registers R24, X, Y, Z can use ADIW/SBIW with constants < 64
7140 i.e. operate word-wise. */
7141
7142 if (val16 < 64)
7143 {
7144 if (val16 != 0)
7145 {
7146 started = true;
7147 avr_asm_len (code == PLUS ? "adiw %0,%1" : "sbiw %0,%1",
7148 op, plen, 1);
7149
7150 if (n_bytes == 2 && PLUS == code)
7151 *pcc = CC_SET_CZN;
7152 }
7153
7154 i++;
7155 continue;
7156 }
7157 }
7158
7159 if (val8 == 0)
7160 {
7161 if (started)
7162 avr_asm_len (code == PLUS
7163 ? "adc %0,__zero_reg__" : "sbc %0,__zero_reg__",
7164 op, plen, 1);
7165 continue;
7166 }
7167 else if ((val8 == 1 || val8 == 0xff)
7168 && UNKNOWN == code_sat
7169 && !started
7170 && i == n_bytes - 1)
7171 {
7172 avr_asm_len ((code == PLUS) ^ (val8 == 1) ? "dec %0" : "inc %0",
7173 op, plen, 1);
7174 *pcc = CC_CLOBBER;
7175 break;
7176 }
7177
7178 switch (code)
7179 {
7180 case PLUS:
7181
7182 gcc_assert (plen != NULL || (op[2] && REG_P (op[2])));
7183
7184 if (plen != NULL && UNKNOWN != code_sat)
7185 {
7186 /* This belongs to the x + 0x80 corner case. The code with
7187 ADD instruction is not smaller, thus make this case
7188 expensive so that the caller won't pick it. */
7189
7190 *plen += 10;
7191 break;
7192 }
7193
7194 if (clobber_val != (int) val8)
7195 avr_asm_len ("ldi %2,%1", op, plen, 1);
7196 clobber_val = (int) val8;
7197
7198 avr_asm_len (started ? "adc %0,%2" : "add %0,%2", op, plen, 1);
7199
7200 break; /* PLUS */
7201
7202 case MINUS:
7203
7204 if (ld_reg_p)
7205 avr_asm_len (started ? "sbci %0,%1" : "subi %0,%1", op, plen, 1);
7206 else
7207 {
7208 gcc_assert (plen != NULL || REG_P (op[2]));
7209
7210 if (clobber_val != (int) val8)
7211 avr_asm_len ("ldi %2,%1", op, plen, 1);
7212 clobber_val = (int) val8;
7213
7214 avr_asm_len (started ? "sbc %0,%2" : "sub %0,%2", op, plen, 1);
7215 }
7216
7217 break; /* MINUS */
7218
7219 default:
7220 /* Unknown code */
7221 gcc_unreachable();
7222 }
7223
7224 started = true;
7225
7226 } /* for all sub-bytes */
7227
7228 saturate:
7229
7230 if (UNKNOWN == code_sat)
7231 return;
7232
7233 *pcc = (int) CC_CLOBBER;
7234
7235 /* Vanilla addition/subtraction is done. We are left with saturation.
7236
7237 We have to compute A = A <op> B where A is a register and
7238 B is a register or a non-zero compile time constant CONST.
7239 A is register class "r" if unsigned && B is REG. Otherwise, A is in "d".
7240 B stands for the original operand $2 in INSN. In the case of B = CONST,
7241 SIGN in { -1, 1 } is the sign of B. Otherwise, SIGN is 0.
7242
7243 CODE is the instruction flavor we use in the asm sequence to perform <op>.
7244
7245
7246 unsigned
7247 operation | code | sat if | b is | sat value | case
7248 -----------------+-------+----------+--------------+-----------+-------
7249 + as a + b | add | C == 1 | const, reg | u+ = 0xff | [1u]
7250 + as a - (-b) | sub | C == 0 | const | u+ = 0xff | [2u]
7251 - as a - b | sub | C == 1 | const, reg | u- = 0 | [3u]
7252 - as a + (-b) | add | C == 0 | const | u- = 0 | [4u]
7253
7254
7255 signed
7256 operation | code | sat if | b is | sat value | case
7257 -----------------+-------+----------+--------------+-----------+-------
7258 + as a + b | add | V == 1 | const, reg | s+ | [1s]
7259 + as a - (-b) | sub | V == 1 | const | s+ | [2s]
7260 - as a - b | sub | V == 1 | const, reg | s- | [3s]
7261 - as a + (-b) | add | V == 1 | const | s- | [4s]
7262
7263 s+ = b < 0 ? -0x80 : 0x7f
7264 s- = b < 0 ? 0x7f : -0x80
7265
7266 The cases a - b actually perform a - (-(-b)) if B is CONST.
7267 */
7268
7269 op[0] = simplify_gen_subreg (QImode, xop[0], mode, n_bytes-1);
7270 op[1] = n_bytes > 1
7271 ? simplify_gen_subreg (QImode, xop[0], mode, n_bytes-2)
7272 : NULL_RTX;
7273
7274 bool need_copy = true;
7275 int len_call = 1 + AVR_HAVE_JMP_CALL;
7276
7277 switch (code_sat)
7278 {
7279 default:
7280 gcc_unreachable();
7281
7282 case SS_PLUS:
7283 case SS_MINUS:
7284
7285 if (out_brvc)
7286 avr_asm_len ("brvc 0f", op, plen, 1);
7287
7288 if (reg_overlap_mentioned_p (xop[0], xop[2]))
7289 {
7290 /* [1s,reg] */
7291
7292 if (n_bytes == 1)
7293 avr_asm_len ("ldi %0,0x7f" CR_TAB
7294 "adc %0,__zero_reg__", op, plen, 2);
7295 else
7296 avr_asm_len ("ldi %0,0x7f" CR_TAB
7297 "ldi %1,0xff" CR_TAB
7298 "adc %1,__zero_reg__" CR_TAB
7299 "adc %0,__zero_reg__", op, plen, 4);
7300 }
7301 else if (sign == 0 && PLUS == code)
7302 {
7303 /* [1s,reg] */
7304
7305 op[2] = simplify_gen_subreg (QImode, xop[2], mode, n_bytes-1);
7306
7307 if (n_bytes == 1)
7308 avr_asm_len ("ldi %0,0x80" CR_TAB
7309 "sbrs %2,7" CR_TAB
7310 "dec %0", op, plen, 3);
7311 else
7312 avr_asm_len ("ldi %0,0x80" CR_TAB
7313 "cp %2,%0" CR_TAB
7314 "sbc %1,%1" CR_TAB
7315 "sbci %0,0", op, plen, 4);
7316 }
7317 else if (sign == 0 && MINUS == code)
7318 {
7319 /* [3s,reg] */
7320
7321 op[2] = simplify_gen_subreg (QImode, xop[2], mode, n_bytes-1);
7322
7323 if (n_bytes == 1)
7324 avr_asm_len ("ldi %0,0x7f" CR_TAB
7325 "sbrs %2,7" CR_TAB
7326 "inc %0", op, plen, 3);
7327 else
7328 avr_asm_len ("ldi %0,0x7f" CR_TAB
7329 "cp %0,%2" CR_TAB
7330 "sbc %1,%1" CR_TAB
7331 "sbci %0,-1", op, plen, 4);
7332 }
7333 else if ((sign < 0) ^ (SS_MINUS == code_sat))
7334 {
7335 /* [1s,const,B < 0] [2s,B < 0] */
7336 /* [3s,const,B > 0] [4s,B > 0] */
7337
7338 if (n_bytes == 8)
7339 {
7340 avr_asm_len ("%~call __clr_8", op, plen, len_call);
7341 need_copy = false;
7342 }
7343
7344 avr_asm_len ("ldi %0,0x80", op, plen, 1);
7345 if (n_bytes > 1 && need_copy)
7346 avr_asm_len ("clr %1", op, plen, 1);
7347 }
7348 else if ((sign > 0) ^ (SS_MINUS == code_sat))
7349 {
7350 /* [1s,const,B > 0] [2s,B > 0] */
7351 /* [3s,const,B < 0] [4s,B < 0] */
7352
7353 if (n_bytes == 8)
7354 {
7355 avr_asm_len ("sec" CR_TAB
7356 "%~call __sbc_8", op, plen, 1 + len_call);
7357 need_copy = false;
7358 }
7359
7360 avr_asm_len ("ldi %0,0x7f", op, plen, 1);
7361 if (n_bytes > 1 && need_copy)
7362 avr_asm_len ("ldi %1,0xff", op, plen, 1);
7363 }
7364 else
7365 gcc_unreachable();
7366
7367 break;
7368
7369 case US_PLUS:
7370 /* [1u] : [2u] */
7371
7372 avr_asm_len (PLUS == code ? "brcc 0f" : "brcs 0f", op, plen, 1);
7373
7374 if (n_bytes == 8)
7375 {
7376 if (MINUS == code)
7377 avr_asm_len ("sec", op, plen, 1);
7378 avr_asm_len ("%~call __sbc_8", op, plen, len_call);
7379
7380 need_copy = false;
7381 }
7382 else
7383 {
7384 if (MINUS == code && !test_hard_reg_class (LD_REGS, op[0]))
7385 avr_asm_len ("sec" CR_TAB
7386 "sbc %0,%0", op, plen, 2);
7387 else
7388 avr_asm_len (PLUS == code ? "sbc %0,%0" : "ldi %0,0xff",
7389 op, plen, 1);
7390 }
7391 break; /* US_PLUS */
7392
7393 case US_MINUS:
7394 /* [4u] : [3u] */
7395
7396 avr_asm_len (PLUS == code ? "brcs 0f" : "brcc 0f", op, plen, 1);
7397
7398 if (n_bytes == 8)
7399 {
7400 avr_asm_len ("%~call __clr_8", op, plen, len_call);
7401 need_copy = false;
7402 }
7403 else
7404 avr_asm_len ("clr %0", op, plen, 1);
7405
7406 break;
7407 }
7408
7409 /* We set the MSB in the unsigned case and the 2 MSBs in the signed case.
7410 Now copy the right value to the LSBs. */
7411
7412 if (need_copy && n_bytes > 1)
7413 {
7414 if (US_MINUS == code_sat || US_PLUS == code_sat)
7415 {
7416 avr_asm_len ("mov %1,%0", op, plen, 1);
7417
7418 if (n_bytes > 2)
7419 {
7420 op[0] = xop[0];
7421 if (AVR_HAVE_MOVW)
7422 avr_asm_len ("movw %0,%1", op, plen, 1);
7423 else
7424 avr_asm_len ("mov %A0,%1" CR_TAB
7425 "mov %B0,%1", op, plen, 2);
7426 }
7427 }
7428 else if (n_bytes > 2)
7429 {
7430 op[0] = xop[0];
7431 avr_asm_len ("mov %A0,%1" CR_TAB
7432 "mov %B0,%1", op, plen, 2);
7433 }
7434 }
7435
7436 if (need_copy && n_bytes == 8)
7437 {
7438 if (AVR_HAVE_MOVW)
7439 avr_asm_len ("movw %r0+2,%0" CR_TAB
7440 "movw %r0+4,%0", xop, plen, 2);
7441 else
7442 avr_asm_len ("mov %r0+2,%0" CR_TAB
7443 "mov %r0+3,%0" CR_TAB
7444 "mov %r0+4,%0" CR_TAB
7445 "mov %r0+5,%0", xop, plen, 4);
7446 }
7447
7448 if (out_label)
7449 avr_asm_len ("0:", op, plen, 0);
7450 }
7451
7452
7453 /* Output addition/subtraction of register XOP[0] and a constant XOP[2] that
7454 is ont a compile-time constant:
7455
7456 XOP[0] = XOP[0] +/- XOP[2]
7457
7458 This is a helper for the function below. The only insns that need this
7459 are additions/subtraction for pointer modes, i.e. HImode and PSImode. */
7460
7461 static const char*
7462 avr_out_plus_symbol (rtx *xop, enum rtx_code code, int *plen, int *pcc)
7463 {
7464 machine_mode mode = GET_MODE (xop[0]);
7465
7466 /* Only pointer modes want to add symbols. */
7467
7468 gcc_assert (mode == HImode || mode == PSImode);
7469
7470 *pcc = MINUS == code ? (int) CC_SET_CZN : (int) CC_SET_N;
7471
7472 avr_asm_len (PLUS == code
7473 ? "subi %A0,lo8(-(%2))" CR_TAB "sbci %B0,hi8(-(%2))"
7474 : "subi %A0,lo8(%2)" CR_TAB "sbci %B0,hi8(%2)",
7475 xop, plen, -2);
7476
7477 if (PSImode == mode)
7478 avr_asm_len (PLUS == code
7479 ? "sbci %C0,hlo8(-(%2))"
7480 : "sbci %C0,hlo8(%2)", xop, plen, 1);
7481 return "";
7482 }
7483
7484
7485 /* Prepare operands of addition/subtraction to be used with avr_out_plus_1.
7486
7487 INSN is a single_set insn or an insn pattern with a binary operation as
7488 SET_SRC that is one of: PLUS, SS_PLUS, US_PLUS, MINUS, SS_MINUS, US_MINUS.
7489
7490 XOP are the operands of INSN. In the case of 64-bit operations with
7491 constant XOP[] has just one element: The summand/subtrahend in XOP[0].
7492 The non-saturating insns up to 32 bits may or may not supply a "d" class
7493 scratch as XOP[3].
7494
7495 If PLEN == NULL output the instructions.
7496 If PLEN != NULL set *PLEN to the length of the sequence in words.
7497
7498 PCC is a pointer to store the instructions' effect on cc0.
7499 PCC may be NULL.
7500
7501 PLEN and PCC default to NULL.
7502
7503 OUT_LABEL defaults to TRUE. For a description, see AVR_OUT_PLUS_1.
7504
7505 Return "" */
7506
7507 const char*
7508 avr_out_plus (rtx insn, rtx *xop, int *plen, int *pcc, bool out_label)
7509 {
7510 int cc_plus, cc_minus, cc_dummy;
7511 int len_plus, len_minus;
7512 rtx op[4];
7513 rtx xpattern = INSN_P (insn) ? single_set (as_a <rtx_insn *> (insn)) : insn;
7514 rtx xdest = SET_DEST (xpattern);
7515 machine_mode mode = GET_MODE (xdest);
7516 machine_mode imode = int_mode_for_mode (mode);
7517 int n_bytes = GET_MODE_SIZE (mode);
7518 enum rtx_code code_sat = GET_CODE (SET_SRC (xpattern));
7519 enum rtx_code code
7520 = (PLUS == code_sat || SS_PLUS == code_sat || US_PLUS == code_sat
7521 ? PLUS : MINUS);
7522
7523 if (!pcc)
7524 pcc = &cc_dummy;
7525
7526 /* PLUS and MINUS don't saturate: Use modular wrap-around. */
7527
7528 if (PLUS == code_sat || MINUS == code_sat)
7529 code_sat = UNKNOWN;
7530
7531 if (n_bytes <= 4 && REG_P (xop[2]))
7532 {
7533 avr_out_plus_1 (xop, plen, code, pcc, code_sat, 0, out_label);
7534 return "";
7535 }
7536
7537 if (8 == n_bytes)
7538 {
7539 op[0] = gen_rtx_REG (DImode, ACC_A);
7540 op[1] = gen_rtx_REG (DImode, ACC_A);
7541 op[2] = avr_to_int_mode (xop[0]);
7542 }
7543 else
7544 {
7545 if (!REG_P (xop[2])
7546 && !CONST_INT_P (xop[2])
7547 && !CONST_FIXED_P (xop[2]))
7548 {
7549 return avr_out_plus_symbol (xop, code, plen, pcc);
7550 }
7551
7552 op[0] = avr_to_int_mode (xop[0]);
7553 op[1] = avr_to_int_mode (xop[1]);
7554 op[2] = avr_to_int_mode (xop[2]);
7555 }
7556
7557 /* Saturations and 64-bit operations don't have a clobber operand.
7558 For the other cases, the caller will provide a proper XOP[3]. */
7559
7560 xpattern = INSN_P (insn) ? PATTERN (insn) : insn;
7561 op[3] = PARALLEL == GET_CODE (xpattern) ? xop[3] : NULL_RTX;
7562
7563 /* Saturation will need the sign of the original operand. */
7564
7565 rtx xmsb = simplify_gen_subreg (QImode, op[2], imode, n_bytes-1);
7566 int sign = INTVAL (xmsb) < 0 ? -1 : 1;
7567
7568 /* If we subtract and the subtrahend is a constant, then negate it
7569 so that avr_out_plus_1 can be used. */
7570
7571 if (MINUS == code)
7572 op[2] = simplify_unary_operation (NEG, imode, op[2], imode);
7573
7574 /* Work out the shortest sequence. */
7575
7576 avr_out_plus_1 (op, &len_minus, MINUS, &cc_minus, code_sat, sign, out_label);
7577 avr_out_plus_1 (op, &len_plus, PLUS, &cc_plus, code_sat, sign, out_label);
7578
7579 if (plen)
7580 {
7581 *plen = (len_minus <= len_plus) ? len_minus : len_plus;
7582 *pcc = (len_minus <= len_plus) ? cc_minus : cc_plus;
7583 }
7584 else if (len_minus <= len_plus)
7585 avr_out_plus_1 (op, NULL, MINUS, pcc, code_sat, sign, out_label);
7586 else
7587 avr_out_plus_1 (op, NULL, PLUS, pcc, code_sat, sign, out_label);
7588
7589 return "";
7590 }
7591
7592
7593 /* Output bit operation (IOR, AND, XOR) with register XOP[0] and compile
7594 time constant XOP[2]:
7595
7596 XOP[0] = XOP[0] <op> XOP[2]
7597
7598 and return "". If PLEN == NULL, print assembler instructions to perform the
7599 operation; otherwise, set *PLEN to the length of the instruction sequence
7600 (in words) printed with PLEN == NULL. XOP[3] is either an 8-bit clobber
7601 register or SCRATCH if no clobber register is needed for the operation.
7602 INSN is an INSN_P or a pattern of an insn. */
7603
7604 const char*
7605 avr_out_bitop (rtx insn, rtx *xop, int *plen)
7606 {
7607 /* CODE and MODE of the operation. */
7608 rtx xpattern = INSN_P (insn) ? single_set (as_a <rtx_insn *> (insn)) : insn;
7609 enum rtx_code code = GET_CODE (SET_SRC (xpattern));
7610 machine_mode mode = GET_MODE (xop[0]);
7611
7612 /* Number of bytes to operate on. */
7613 int i, n_bytes = GET_MODE_SIZE (mode);
7614
7615 /* Value of T-flag (0 or 1) or -1 if unknow. */
7616 int set_t = -1;
7617
7618 /* Value (0..0xff) held in clobber register op[3] or -1 if unknown. */
7619 int clobber_val = -1;
7620
7621 /* op[0]: 8-bit destination register
7622 op[1]: 8-bit const int
7623 op[2]: 8-bit clobber register or SCRATCH
7624 op[3]: 8-bit register containing 0xff or NULL_RTX */
7625 rtx op[4];
7626
7627 op[2] = xop[3];
7628 op[3] = NULL_RTX;
7629
7630 if (plen)
7631 *plen = 0;
7632
7633 for (i = 0; i < n_bytes; i++)
7634 {
7635 /* We operate byte-wise on the destination. */
7636 rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
7637 rtx xval8 = simplify_gen_subreg (QImode, xop[2], mode, i);
7638
7639 /* 8-bit value to operate with this byte. */
7640 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
7641
7642 /* Number of bits set in the current byte of the constant. */
7643 int pop8 = avr_popcount (val8);
7644
7645 /* Registers R16..R31 can operate with immediate. */
7646 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
7647
7648 op[0] = reg8;
7649 op[1] = GEN_INT (val8);
7650
7651 switch (code)
7652 {
7653 case IOR:
7654
7655 if (0 == pop8)
7656 continue;
7657 else if (ld_reg_p)
7658 avr_asm_len ("ori %0,%1", op, plen, 1);
7659 else if (1 == pop8)
7660 {
7661 if (set_t != 1)
7662 avr_asm_len ("set", op, plen, 1);
7663 set_t = 1;
7664
7665 op[1] = GEN_INT (exact_log2 (val8));
7666 avr_asm_len ("bld %0,%1", op, plen, 1);
7667 }
7668 else if (8 == pop8)
7669 {
7670 if (op[3] != NULL_RTX)
7671 avr_asm_len ("mov %0,%3", op, plen, 1);
7672 else
7673 avr_asm_len ("clr %0" CR_TAB
7674 "dec %0", op, plen, 2);
7675
7676 op[3] = op[0];
7677 }
7678 else
7679 {
7680 if (clobber_val != (int) val8)
7681 avr_asm_len ("ldi %2,%1", op, plen, 1);
7682 clobber_val = (int) val8;
7683
7684 avr_asm_len ("or %0,%2", op, plen, 1);
7685 }
7686
7687 continue; /* IOR */
7688
7689 case AND:
7690
7691 if (8 == pop8)
7692 continue;
7693 else if (0 == pop8)
7694 avr_asm_len ("clr %0", op, plen, 1);
7695 else if (ld_reg_p)
7696 avr_asm_len ("andi %0,%1", op, plen, 1);
7697 else if (7 == pop8)
7698 {
7699 if (set_t != 0)
7700 avr_asm_len ("clt", op, plen, 1);
7701 set_t = 0;
7702
7703 op[1] = GEN_INT (exact_log2 (GET_MODE_MASK (QImode) & ~val8));
7704 avr_asm_len ("bld %0,%1", op, plen, 1);
7705 }
7706 else
7707 {
7708 if (clobber_val != (int) val8)
7709 avr_asm_len ("ldi %2,%1", op, plen, 1);
7710 clobber_val = (int) val8;
7711
7712 avr_asm_len ("and %0,%2", op, plen, 1);
7713 }
7714
7715 continue; /* AND */
7716
7717 case XOR:
7718
7719 if (0 == pop8)
7720 continue;
7721 else if (8 == pop8)
7722 avr_asm_len ("com %0", op, plen, 1);
7723 else if (ld_reg_p && val8 == (1 << 7))
7724 avr_asm_len ("subi %0,%1", op, plen, 1);
7725 else
7726 {
7727 if (clobber_val != (int) val8)
7728 avr_asm_len ("ldi %2,%1", op, plen, 1);
7729 clobber_val = (int) val8;
7730
7731 avr_asm_len ("eor %0,%2", op, plen, 1);
7732 }
7733
7734 continue; /* XOR */
7735
7736 default:
7737 /* Unknown rtx_code */
7738 gcc_unreachable();
7739 }
7740 } /* for all sub-bytes */
7741
7742 return "";
7743 }
7744
7745
7746 /* Output sign extension from XOP[1] to XOP[0] and return "".
7747 If PLEN == NULL, print assembler instructions to perform the operation;
7748 otherwise, set *PLEN to the length of the instruction sequence (in words)
7749 as printed with PLEN == NULL. */
7750
7751 const char*
7752 avr_out_sign_extend (rtx_insn *insn, rtx *xop, int *plen)
7753 {
7754 // Size in bytes of source resp. destination operand.
7755 unsigned n_src = GET_MODE_SIZE (GET_MODE (xop[1]));
7756 unsigned n_dest = GET_MODE_SIZE (GET_MODE (xop[0]));
7757 rtx r_msb = all_regs_rtx[REGNO (xop[1]) + n_src - 1];
7758
7759 if (plen)
7760 *plen = 0;
7761
7762 // Copy destination to source
7763
7764 if (REGNO (xop[0]) != REGNO (xop[1]))
7765 {
7766 gcc_assert (n_src <= 2);
7767
7768 if (n_src == 2)
7769 avr_asm_len (AVR_HAVE_MOVW
7770 ? "movw %0,%1"
7771 : "mov %B0,%B1", xop, plen, 1);
7772 if (n_src == 1 || !AVR_HAVE_MOVW)
7773 avr_asm_len ("mov %A0,%A1", xop, plen, 1);
7774 }
7775
7776 // Set Carry to the sign bit MSB.7...
7777
7778 if (REGNO (xop[0]) == REGNO (xop[1])
7779 || !reg_unused_after (insn, r_msb))
7780 {
7781 avr_asm_len ("mov __tmp_reg__,%0", &r_msb, plen, 1);
7782 r_msb = tmp_reg_rtx;
7783 }
7784
7785 avr_asm_len ("lsl %0", &r_msb, plen, 1);
7786
7787 // ...and propagate it to all the new sign bits
7788
7789 for (unsigned n = n_src; n < n_dest; n++)
7790 avr_asm_len ("sbc %0,%0", &all_regs_rtx[REGNO (xop[0]) + n], plen, 1);
7791
7792 return "";
7793 }
7794
7795
7796 /* PLEN == NULL: Output code to add CONST_INT OP[0] to SP.
7797 PLEN != NULL: Set *PLEN to the length of that sequence.
7798 Return "". */
7799
7800 const char*
7801 avr_out_addto_sp (rtx *op, int *plen)
7802 {
7803 int pc_len = AVR_2_BYTE_PC ? 2 : 3;
7804 int addend = INTVAL (op[0]);
7805
7806 if (plen)
7807 *plen = 0;
7808
7809 if (addend < 0)
7810 {
7811 if (flag_verbose_asm || flag_print_asm_name)
7812 avr_asm_len (ASM_COMMENT_START "SP -= %n0", op, plen, 0);
7813
7814 while (addend <= -pc_len)
7815 {
7816 addend += pc_len;
7817 avr_asm_len ("rcall .", op, plen, 1);
7818 }
7819
7820 while (addend++ < 0)
7821 avr_asm_len ("push __zero_reg__", op, plen, 1);
7822 }
7823 else if (addend > 0)
7824 {
7825 if (flag_verbose_asm || flag_print_asm_name)
7826 avr_asm_len (ASM_COMMENT_START "SP += %0", op, plen, 0);
7827
7828 while (addend-- > 0)
7829 avr_asm_len ("pop __tmp_reg__", op, plen, 1);
7830 }
7831
7832 return "";
7833 }
7834
7835
7836 /* Outputs instructions needed for fixed point type conversion.
7837 This includes converting between any fixed point type, as well
7838 as converting to any integer type. Conversion between integer
7839 types is not supported.
7840
7841 Converting signed fractional types requires a bit shift if converting
7842 to or from any unsigned fractional type because the decimal place is
7843 shifted by 1 bit. When the destination is a signed fractional, the sign
7844 is stored in either the carry or T bit. */
7845
7846 const char*
7847 avr_out_fract (rtx_insn *insn, rtx operands[], bool intsigned, int *plen)
7848 {
7849 size_t i;
7850 rtx xop[6];
7851 RTX_CODE shift = UNKNOWN;
7852 bool sign_in_carry = false;
7853 bool msb_in_carry = false;
7854 bool lsb_in_tmp_reg = false;
7855 bool lsb_in_carry = false;
7856 bool frac_rounded = false;
7857 const char *code_ashift = "lsl %0";
7858
7859
7860 #define MAY_CLOBBER(RR) \
7861 /* Shorthand used below. */ \
7862 ((sign_bytes \
7863 && IN_RANGE (RR, dest.regno_msb - sign_bytes + 1, dest.regno_msb)) \
7864 || (offset && IN_RANGE (RR, dest.regno, dest.regno_msb)) \
7865 || (reg_unused_after (insn, all_regs_rtx[RR]) \
7866 && !IN_RANGE (RR, dest.regno, dest.regno_msb)))
7867
7868 struct
7869 {
7870 /* bytes : Length of operand in bytes.
7871 ibyte : Length of integral part in bytes.
7872 fbyte, fbit : Length of fractional part in bytes, bits. */
7873
7874 bool sbit;
7875 unsigned fbit, bytes, ibyte, fbyte;
7876 unsigned regno, regno_msb;
7877 } dest, src, *val[2] = { &dest, &src };
7878
7879 if (plen)
7880 *plen = 0;
7881
7882 /* Step 0: Determine information on source and destination operand we
7883 ====== will need in the remainder. */
7884
7885 for (i = 0; i < sizeof (val) / sizeof (*val); i++)
7886 {
7887 machine_mode mode;
7888
7889 xop[i] = operands[i];
7890
7891 mode = GET_MODE (xop[i]);
7892
7893 val[i]->bytes = GET_MODE_SIZE (mode);
7894 val[i]->regno = REGNO (xop[i]);
7895 val[i]->regno_msb = REGNO (xop[i]) + val[i]->bytes - 1;
7896
7897 if (SCALAR_INT_MODE_P (mode))
7898 {
7899 val[i]->sbit = intsigned;
7900 val[i]->fbit = 0;
7901 }
7902 else if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
7903 {
7904 val[i]->sbit = SIGNED_SCALAR_FIXED_POINT_MODE_P (mode);
7905 val[i]->fbit = GET_MODE_FBIT (mode);
7906 }
7907 else
7908 fatal_insn ("unsupported fixed-point conversion", insn);
7909
7910 val[i]->fbyte = (1 + val[i]->fbit) / BITS_PER_UNIT;
7911 val[i]->ibyte = val[i]->bytes - val[i]->fbyte;
7912 }
7913
7914 // Byte offset of the decimal point taking into account different place
7915 // of the decimal point in input and output and different register numbers
7916 // of input and output.
7917 int offset = dest.regno - src.regno + dest.fbyte - src.fbyte;
7918
7919 // Number of destination bytes that will come from sign / zero extension.
7920 int sign_bytes = (dest.ibyte - src.ibyte) * (dest.ibyte > src.ibyte);
7921
7922 // Number of bytes at the low end to be filled with zeros.
7923 int zero_bytes = (dest.fbyte - src.fbyte) * (dest.fbyte > src.fbyte);
7924
7925 // Do we have a 16-Bit register that is cleared?
7926 rtx clrw = NULL_RTX;
7927
7928 bool sign_extend = src.sbit && sign_bytes;
7929
7930 if (0 == dest.fbit % 8 && 7 == src.fbit % 8)
7931 shift = ASHIFT;
7932 else if (7 == dest.fbit % 8 && 0 == src.fbit % 8)
7933 shift = ASHIFTRT;
7934 else if (dest.fbit % 8 == src.fbit % 8)
7935 shift = UNKNOWN;
7936 else
7937 gcc_unreachable();
7938
7939 /* If we need to round the fraction part, we might need to save/round it
7940 before clobbering any of it in Step 1. Also, we might want to do
7941 the rounding now to make use of LD_REGS. */
7942 if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
7943 && SCALAR_ACCUM_MODE_P (GET_MODE (xop[1]))
7944 && !TARGET_FRACT_CONV_TRUNC)
7945 {
7946 bool overlap
7947 = (src.regno <=
7948 (offset ? dest.regno_msb - sign_bytes : dest.regno + zero_bytes - 1)
7949 && dest.regno - offset -1 >= dest.regno);
7950 unsigned s0 = dest.regno - offset -1;
7951 bool use_src = true;
7952 unsigned sn;
7953 unsigned copied_msb = src.regno_msb;
7954 bool have_carry = false;
7955
7956 if (src.ibyte > dest.ibyte)
7957 copied_msb -= src.ibyte - dest.ibyte;
7958
7959 for (sn = s0; sn <= copied_msb; sn++)
7960 if (!IN_RANGE (sn, dest.regno, dest.regno_msb)
7961 && !reg_unused_after (insn, all_regs_rtx[sn]))
7962 use_src = false;
7963 if (use_src && TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], s0))
7964 {
7965 avr_asm_len ("tst %0" CR_TAB "brpl 0f",
7966 &all_regs_rtx[src.regno_msb], plen, 2);
7967 sn = src.regno;
7968 if (sn < s0)
7969 {
7970 if (TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], sn))
7971 avr_asm_len ("cpi %0,1", &all_regs_rtx[sn], plen, 1);
7972 else
7973 avr_asm_len ("sec" CR_TAB
7974 "cpc %0,__zero_reg__",
7975 &all_regs_rtx[sn], plen, 2);
7976 have_carry = true;
7977 }
7978 while (++sn < s0)
7979 avr_asm_len ("cpc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
7980
7981 avr_asm_len (have_carry ? "sbci %0,128" : "subi %0,129",
7982 &all_regs_rtx[s0], plen, 1);
7983 for (sn = src.regno + src.fbyte; sn <= copied_msb; sn++)
7984 avr_asm_len ("sbci %0,255", &all_regs_rtx[sn], plen, 1);
7985 avr_asm_len ("\n0:", NULL, plen, 0);
7986 frac_rounded = true;
7987 }
7988 else if (use_src && overlap)
7989 {
7990 avr_asm_len ("clr __tmp_reg__" CR_TAB
7991 "sbrc %1,0" CR_TAB
7992 "dec __tmp_reg__", xop, plen, 1);
7993 sn = src.regno;
7994 if (sn < s0)
7995 {
7996 avr_asm_len ("add %0,__tmp_reg__", &all_regs_rtx[sn], plen, 1);
7997 have_carry = true;
7998 }
7999
8000 while (++sn < s0)
8001 avr_asm_len ("adc %0,__tmp_reg__", &all_regs_rtx[sn], plen, 1);
8002
8003 if (have_carry)
8004 avr_asm_len ("clt" CR_TAB
8005 "bld __tmp_reg__,7" CR_TAB
8006 "adc %0,__tmp_reg__",
8007 &all_regs_rtx[s0], plen, 1);
8008 else
8009 avr_asm_len ("lsr __tmp_reg" CR_TAB
8010 "add %0,__tmp_reg__",
8011 &all_regs_rtx[s0], plen, 2);
8012 for (sn = src.regno + src.fbyte; sn <= copied_msb; sn++)
8013 avr_asm_len ("adc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
8014 frac_rounded = true;
8015 }
8016 else if (overlap)
8017 {
8018 bool use_src
8019 = (TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], s0)
8020 && (IN_RANGE (s0, dest.regno, dest.regno_msb)
8021 || reg_unused_after (insn, all_regs_rtx[s0])));
8022 xop[2] = all_regs_rtx[s0];
8023 unsigned sn = src.regno;
8024 if (!use_src || sn == s0)
8025 avr_asm_len ("mov __tmp_reg__,%2", xop, plen, 1);
8026 /* We need to consider to-be-discarded bits
8027 if the value is negative. */
8028 if (sn < s0)
8029 {
8030 avr_asm_len ("tst %0" CR_TAB
8031 "brpl 0f",
8032 &all_regs_rtx[src.regno_msb], plen, 2);
8033 /* Test to-be-discarded bytes for any nozero bits.
8034 ??? Could use OR or SBIW to test two registers at once. */
8035 if (sn < s0)
8036 avr_asm_len ("cp %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
8037
8038 while (++sn < s0)
8039 avr_asm_len ("cpc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
8040 /* Set bit 0 in __tmp_reg__ if any of the lower bits was set. */
8041 if (use_src)
8042 avr_asm_len ("breq 0f" CR_TAB
8043 "ori %2,1"
8044 "\n0:\t" "mov __tmp_reg__,%2",
8045 xop, plen, 3);
8046 else
8047 avr_asm_len ("breq 0f" CR_TAB
8048 "set" CR_TAB
8049 "bld __tmp_reg__,0\n0:",
8050 xop, plen, 3);
8051 }
8052 lsb_in_tmp_reg = true;
8053 }
8054 }
8055
8056 /* Step 1: Clear bytes at the low end and copy payload bits from source
8057 ====== to destination. */
8058
8059 int step = offset < 0 ? 1 : -1;
8060 unsigned d0 = offset < 0 ? dest.regno : dest.regno_msb;
8061
8062 // We cleared at least that number of registers.
8063 int clr_n = 0;
8064
8065 for (; d0 >= dest.regno && d0 <= dest.regno_msb; d0 += step)
8066 {
8067 // Next regno of destination is needed for MOVW
8068 unsigned d1 = d0 + step;
8069
8070 // Current and next regno of source
8071 signed s0 = d0 - offset;
8072 signed s1 = s0 + step;
8073
8074 // Must current resp. next regno be CLRed? This applies to the low
8075 // bytes of the destination that have no associated source bytes.
8076 bool clr0 = s0 < (signed) src.regno;
8077 bool clr1 = s1 < (signed) src.regno && d1 >= dest.regno;
8078
8079 // First gather what code to emit (if any) and additional step to
8080 // apply if a MOVW is in use. xop[2] is destination rtx and xop[3]
8081 // is the source rtx for the current loop iteration.
8082 const char *code = NULL;
8083 int stepw = 0;
8084
8085 if (clr0)
8086 {
8087 if (AVR_HAVE_MOVW && clr1 && clrw)
8088 {
8089 xop[2] = all_regs_rtx[d0 & ~1];
8090 xop[3] = clrw;
8091 code = "movw %2,%3";
8092 stepw = step;
8093 }
8094 else
8095 {
8096 xop[2] = all_regs_rtx[d0];
8097 code = "clr %2";
8098
8099 if (++clr_n >= 2
8100 && !clrw
8101 && d0 % 2 == (step > 0))
8102 {
8103 clrw = all_regs_rtx[d0 & ~1];
8104 }
8105 }
8106 }
8107 else if (offset && s0 <= (signed) src.regno_msb)
8108 {
8109 int movw = AVR_HAVE_MOVW && offset % 2 == 0
8110 && d0 % 2 == (offset > 0)
8111 && d1 <= dest.regno_msb && d1 >= dest.regno
8112 && s1 <= (signed) src.regno_msb && s1 >= (signed) src.regno;
8113
8114 xop[2] = all_regs_rtx[d0 & ~movw];
8115 xop[3] = all_regs_rtx[s0 & ~movw];
8116 code = movw ? "movw %2,%3" : "mov %2,%3";
8117 stepw = step * movw;
8118 }
8119
8120 if (code)
8121 {
8122 if (sign_extend && shift != ASHIFT && !sign_in_carry
8123 && (d0 == src.regno_msb || d0 + stepw == src.regno_msb))
8124 {
8125 /* We are going to override the sign bit. If we sign-extend,
8126 store the sign in the Carry flag. This is not needed if
8127 the destination will be ASHIFT in the remainder because
8128 the ASHIFT will set Carry without extra instruction. */
8129
8130 avr_asm_len ("lsl %0", &all_regs_rtx[src.regno_msb], plen, 1);
8131 sign_in_carry = true;
8132 }
8133
8134 unsigned src_msb = dest.regno_msb - sign_bytes - offset + 1;
8135
8136 if (!sign_extend && shift == ASHIFTRT && !msb_in_carry
8137 && src.ibyte > dest.ibyte
8138 && (d0 == src_msb || d0 + stepw == src_msb))
8139 {
8140 /* We are going to override the MSB. If we shift right,
8141 store the MSB in the Carry flag. This is only needed if
8142 we don't sign-extend becaue with sign-extension the MSB
8143 (the sign) will be produced by the sign extension. */
8144
8145 avr_asm_len ("lsr %0", &all_regs_rtx[src_msb], plen, 1);
8146 msb_in_carry = true;
8147 }
8148
8149 unsigned src_lsb = dest.regno - offset -1;
8150
8151 if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry
8152 && !lsb_in_tmp_reg
8153 && (d0 == src_lsb || d0 + stepw == src_lsb))
8154 {
8155 /* We are going to override the new LSB; store it into carry. */
8156
8157 avr_asm_len ("lsl %0", &all_regs_rtx[src_lsb], plen, 1);
8158 code_ashift = "rol %0";
8159 lsb_in_carry = true;
8160 }
8161
8162 avr_asm_len (code, xop, plen, 1);
8163 d0 += stepw;
8164 }
8165 }
8166
8167 /* Step 2: Shift destination left by 1 bit position. This might be needed
8168 ====== for signed input and unsigned output. */
8169
8170 if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry)
8171 {
8172 unsigned s0 = dest.regno - offset -1;
8173
8174 /* n1169 4.1.4 says:
8175 "Conversions from a fixed-point to an integer type round toward zero."
8176 Hence, converting a fract type to integer only gives a non-zero result
8177 for -1. */
8178 if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
8179 && SCALAR_FRACT_MODE_P (GET_MODE (xop[1]))
8180 && !TARGET_FRACT_CONV_TRUNC)
8181 {
8182 gcc_assert (s0 == src.regno_msb);
8183 /* Check if the input is -1. We do that by checking if negating
8184 the input causes an integer overflow. */
8185 unsigned sn = src.regno;
8186 avr_asm_len ("cp __zero_reg__,%0", &all_regs_rtx[sn++], plen, 1);
8187 while (sn <= s0)
8188 avr_asm_len ("cpc __zero_reg__,%0", &all_regs_rtx[sn++], plen, 1);
8189
8190 /* Overflow goes with set carry. Clear carry otherwise. */
8191 avr_asm_len ("brvs 0f" CR_TAB
8192 "clc\n0:", NULL, plen, 2);
8193 }
8194 /* Likewise, when converting from accumulator types to integer, we
8195 need to round up negative values. */
8196 else if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
8197 && SCALAR_ACCUM_MODE_P (GET_MODE (xop[1]))
8198 && !TARGET_FRACT_CONV_TRUNC
8199 && !frac_rounded)
8200 {
8201 bool have_carry = false;
8202
8203 xop[2] = all_regs_rtx[s0];
8204 if (!lsb_in_tmp_reg && !MAY_CLOBBER (s0))
8205 avr_asm_len ("mov __tmp_reg__,%2", xop, plen, 1);
8206 avr_asm_len ("tst %0" CR_TAB "brpl 0f",
8207 &all_regs_rtx[src.regno_msb], plen, 2);
8208 if (!lsb_in_tmp_reg)
8209 {
8210 unsigned sn = src.regno;
8211 if (sn < s0)
8212 {
8213 avr_asm_len ("cp __zero_reg__,%0", &all_regs_rtx[sn],
8214 plen, 1);
8215 have_carry = true;
8216 }
8217 while (++sn < s0)
8218 avr_asm_len ("cpc __zero_reg__,%0", &all_regs_rtx[sn], plen, 1);
8219 lsb_in_tmp_reg = !MAY_CLOBBER (s0);
8220 }
8221 /* Add in C and the rounding value 127. */
8222 /* If the destination msb is a sign byte, and in LD_REGS,
8223 grab it as a temporary. */
8224 if (sign_bytes
8225 && TEST_HARD_REG_BIT (reg_class_contents[LD_REGS],
8226 dest.regno_msb))
8227 {
8228 xop[3] = all_regs_rtx[dest.regno_msb];
8229 avr_asm_len ("ldi %3,127", xop, plen, 1);
8230 avr_asm_len ((have_carry && lsb_in_tmp_reg ? "adc __tmp_reg__,%3"
8231 : have_carry ? "adc %2,%3"
8232 : lsb_in_tmp_reg ? "add __tmp_reg__,%3"
8233 : "add %2,%3"),
8234 xop, plen, 1);
8235 }
8236 else
8237 {
8238 /* Fall back to use __zero_reg__ as a temporary. */
8239 avr_asm_len ("dec __zero_reg__", NULL, plen, 1);
8240 if (have_carry)
8241 avr_asm_len ("clt" CR_TAB
8242 "bld __zero_reg__,7", NULL, plen, 2);
8243 else
8244 avr_asm_len ("lsr __zero_reg__", NULL, plen, 1);
8245 avr_asm_len (have_carry && lsb_in_tmp_reg
8246 ? "adc __tmp_reg__,__zero_reg__"
8247 : have_carry ? "adc %2,__zero_reg__"
8248 : lsb_in_tmp_reg ? "add __tmp_reg__,__zero_reg__"
8249 : "add %2,__zero_reg__",
8250 xop, plen, 1);
8251 avr_asm_len ("eor __zero_reg__,__zero_reg__", NULL, plen, 1);
8252 }
8253
8254 for (d0 = dest.regno + zero_bytes;
8255 d0 <= dest.regno_msb - sign_bytes; d0++)
8256 avr_asm_len ("adc %0,__zero_reg__", &all_regs_rtx[d0], plen, 1);
8257
8258 avr_asm_len (lsb_in_tmp_reg
8259 ? "\n0:\t" "lsl __tmp_reg__"
8260 : "\n0:\t" "lsl %2",
8261 xop, plen, 1);
8262 }
8263 else if (MAY_CLOBBER (s0))
8264 avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1);
8265 else
8266 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
8267 "lsl __tmp_reg__", &all_regs_rtx[s0], plen, 2);
8268
8269 code_ashift = "rol %0";
8270 lsb_in_carry = true;
8271 }
8272
8273 if (shift == ASHIFT)
8274 {
8275 for (d0 = dest.regno + zero_bytes;
8276 d0 <= dest.regno_msb - sign_bytes; d0++)
8277 {
8278 avr_asm_len (code_ashift, &all_regs_rtx[d0], plen, 1);
8279 code_ashift = "rol %0";
8280 }
8281
8282 lsb_in_carry = false;
8283 sign_in_carry = true;
8284 }
8285
8286 /* Step 4a: Store MSB in carry if we don't already have it or will produce
8287 ======= it in sign-extension below. */
8288
8289 if (!sign_extend && shift == ASHIFTRT && !msb_in_carry
8290 && src.ibyte > dest.ibyte)
8291 {
8292 unsigned s0 = dest.regno_msb - sign_bytes - offset + 1;
8293
8294 if (MAY_CLOBBER (s0))
8295 avr_asm_len ("lsr %0", &all_regs_rtx[s0], plen, 1);
8296 else
8297 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
8298 "lsr __tmp_reg__", &all_regs_rtx[s0], plen, 2);
8299
8300 msb_in_carry = true;
8301 }
8302
8303 /* Step 3: Sign-extend or zero-extend the destination as needed.
8304 ====== */
8305
8306 if (sign_extend && !sign_in_carry)
8307 {
8308 unsigned s0 = src.regno_msb;
8309
8310 if (MAY_CLOBBER (s0))
8311 avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1);
8312 else
8313 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
8314 "lsl __tmp_reg__", &all_regs_rtx[s0], plen, 2);
8315
8316 sign_in_carry = true;
8317 }
8318
8319 gcc_assert (sign_in_carry + msb_in_carry + lsb_in_carry <= 1);
8320
8321 unsigned copies = 0;
8322 rtx movw = sign_extend ? NULL_RTX : clrw;
8323
8324 for (d0 = dest.regno_msb - sign_bytes + 1; d0 <= dest.regno_msb; d0++)
8325 {
8326 if (AVR_HAVE_MOVW && movw
8327 && d0 % 2 == 0 && d0 + 1 <= dest.regno_msb)
8328 {
8329 xop[2] = all_regs_rtx[d0];
8330 xop[3] = movw;
8331 avr_asm_len ("movw %2,%3", xop, plen, 1);
8332 d0++;
8333 }
8334 else
8335 {
8336 avr_asm_len (sign_extend ? "sbc %0,%0" : "clr %0",
8337 &all_regs_rtx[d0], plen, 1);
8338
8339 if (++copies >= 2 && !movw && d0 % 2 == 1)
8340 movw = all_regs_rtx[d0-1];
8341 }
8342 } /* for */
8343
8344
8345 /* Step 4: Right shift the destination. This might be needed for
8346 ====== conversions from unsigned to signed. */
8347
8348 if (shift == ASHIFTRT)
8349 {
8350 const char *code_ashiftrt = "lsr %0";
8351
8352 if (sign_extend || msb_in_carry)
8353 code_ashiftrt = "ror %0";
8354
8355 if (src.sbit && src.ibyte == dest.ibyte)
8356 code_ashiftrt = "asr %0";
8357
8358 for (d0 = dest.regno_msb - sign_bytes;
8359 d0 >= dest.regno + zero_bytes - 1 && d0 >= dest.regno; d0--)
8360 {
8361 avr_asm_len (code_ashiftrt, &all_regs_rtx[d0], plen, 1);
8362 code_ashiftrt = "ror %0";
8363 }
8364 }
8365
8366 #undef MAY_CLOBBER
8367
8368 return "";
8369 }
8370
8371
8372 /* Output fixed-point rounding. XOP[0] = XOP[1] is the operand to round.
8373 XOP[2] is the rounding point, a CONST_INT. The function prints the
8374 instruction sequence if PLEN = NULL and computes the length in words
8375 of the sequence if PLEN != NULL. Most of this function deals with
8376 preparing operands for calls to `avr_out_plus' and `avr_out_bitop'. */
8377
8378 const char*
8379 avr_out_round (rtx_insn *insn ATTRIBUTE_UNUSED, rtx *xop, int *plen)
8380 {
8381 machine_mode mode = GET_MODE (xop[0]);
8382 machine_mode imode = int_mode_for_mode (mode);
8383 // The smallest fractional bit not cleared by the rounding is 2^(-RP).
8384 int fbit = (int) GET_MODE_FBIT (mode);
8385 double_int i_add = double_int_zero.set_bit (fbit-1 - INTVAL (xop[2]));
8386 wide_int wi_add = wi::set_bit_in_zero (fbit-1 - INTVAL (xop[2]),
8387 GET_MODE_PRECISION (imode));
8388 // Lengths of PLUS and AND parts.
8389 int len_add = 0, *plen_add = plen ? &len_add : NULL;
8390 int len_and = 0, *plen_and = plen ? &len_and : NULL;
8391
8392 // Add-Saturate 1/2 * 2^(-RP). Don't print the label "0:" when printing
8393 // the saturated addition so that we can emit the "rjmp 1f" before the
8394 // "0:" below.
8395
8396 rtx xadd = const_fixed_from_double_int (i_add, mode);
8397 rtx xpattern, xsrc, op[4];
8398
8399 xsrc = SIGNED_FIXED_POINT_MODE_P (mode)
8400 ? gen_rtx_SS_PLUS (mode, xop[1], xadd)
8401 : gen_rtx_US_PLUS (mode, xop[1], xadd);
8402 xpattern = gen_rtx_SET (VOIDmode, xop[0], xsrc);
8403
8404 op[0] = xop[0];
8405 op[1] = xop[1];
8406 op[2] = xadd;
8407 avr_out_plus (xpattern, op, plen_add, NULL, false /* Don't print "0:" */);
8408
8409 avr_asm_len ("rjmp 1f" CR_TAB
8410 "0:", NULL, plen_add, 1);
8411
8412 // Keep all bits from RP and higher: ... 2^(-RP)
8413 // Clear all bits from RP+1 and lower: 2^(-RP-1) ...
8414 // Rounding point ^^^^^^^
8415 // Added above ^^^^^^^^^
8416 rtx xreg = simplify_gen_subreg (imode, xop[0], mode, 0);
8417 rtx xmask = immed_wide_int_const (-wi_add - wi_add, imode);
8418
8419 xpattern = gen_rtx_SET (VOIDmode, xreg, gen_rtx_AND (imode, xreg, xmask));
8420
8421 op[0] = xreg;
8422 op[1] = xreg;
8423 op[2] = xmask;
8424 op[3] = gen_rtx_SCRATCH (QImode);
8425 avr_out_bitop (xpattern, op, plen_and);
8426 avr_asm_len ("1:", NULL, plen, 0);
8427
8428 if (plen)
8429 *plen = len_add + len_and;
8430
8431 return "";
8432 }
8433
8434
8435 /* Create RTL split patterns for byte sized rotate expressions. This
8436 produces a series of move instructions and considers overlap situations.
8437 Overlapping non-HImode operands need a scratch register. */
8438
8439 bool
8440 avr_rotate_bytes (rtx operands[])
8441 {
8442 int i, j;
8443 machine_mode mode = GET_MODE (operands[0]);
8444 bool overlapped = reg_overlap_mentioned_p (operands[0], operands[1]);
8445 bool same_reg = rtx_equal_p (operands[0], operands[1]);
8446 int num = INTVAL (operands[2]);
8447 rtx scratch = operands[3];
8448 /* Work out if byte or word move is needed. Odd byte rotates need QImode.
8449 Word move if no scratch is needed, otherwise use size of scratch. */
8450 machine_mode move_mode = QImode;
8451 int move_size, offset, size;
8452
8453 if (num & 0xf)
8454 move_mode = QImode;
8455 else if ((mode == SImode && !same_reg) || !overlapped)
8456 move_mode = HImode;
8457 else
8458 move_mode = GET_MODE (scratch);
8459
8460 /* Force DI rotate to use QI moves since other DI moves are currently split
8461 into QI moves so forward propagation works better. */
8462 if (mode == DImode)
8463 move_mode = QImode;
8464 /* Make scratch smaller if needed. */
8465 if (SCRATCH != GET_CODE (scratch)
8466 && HImode == GET_MODE (scratch)
8467 && QImode == move_mode)
8468 scratch = simplify_gen_subreg (move_mode, scratch, HImode, 0);
8469
8470 move_size = GET_MODE_SIZE (move_mode);
8471 /* Number of bytes/words to rotate. */
8472 offset = (num >> 3) / move_size;
8473 /* Number of moves needed. */
8474 size = GET_MODE_SIZE (mode) / move_size;
8475 /* Himode byte swap is special case to avoid a scratch register. */
8476 if (mode == HImode && same_reg)
8477 {
8478 /* HImode byte swap, using xor. This is as quick as using scratch. */
8479 rtx src, dst;
8480 src = simplify_gen_subreg (move_mode, operands[1], mode, 0);
8481 dst = simplify_gen_subreg (move_mode, operands[0], mode, 1);
8482 if (!rtx_equal_p (dst, src))
8483 {
8484 emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
8485 emit_move_insn (src, gen_rtx_XOR (QImode, src, dst));
8486 emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
8487 }
8488 }
8489 else
8490 {
8491 #define MAX_SIZE 8 /* GET_MODE_SIZE (DImode) / GET_MODE_SIZE (QImode) */
8492 /* Create linked list of moves to determine move order. */
8493 struct {
8494 rtx src, dst;
8495 int links;
8496 } move[MAX_SIZE + 8];
8497 int blocked, moves;
8498
8499 gcc_assert (size <= MAX_SIZE);
8500 /* Generate list of subreg moves. */
8501 for (i = 0; i < size; i++)
8502 {
8503 int from = i;
8504 int to = (from + offset) % size;
8505 move[i].src = simplify_gen_subreg (move_mode, operands[1],
8506 mode, from * move_size);
8507 move[i].dst = simplify_gen_subreg (move_mode, operands[0],
8508 mode, to * move_size);
8509 move[i].links = -1;
8510 }
8511 /* Mark dependence where a dst of one move is the src of another move.
8512 The first move is a conflict as it must wait until second is
8513 performed. We ignore moves to self - we catch this later. */
8514 if (overlapped)
8515 for (i = 0; i < size; i++)
8516 if (reg_overlap_mentioned_p (move[i].dst, operands[1]))
8517 for (j = 0; j < size; j++)
8518 if (j != i && rtx_equal_p (move[j].src, move[i].dst))
8519 {
8520 /* The dst of move i is the src of move j. */
8521 move[i].links = j;
8522 break;
8523 }
8524
8525 blocked = -1;
8526 moves = 0;
8527 /* Go through move list and perform non-conflicting moves. As each
8528 non-overlapping move is made, it may remove other conflicts
8529 so the process is repeated until no conflicts remain. */
8530 do
8531 {
8532 blocked = -1;
8533 moves = 0;
8534 /* Emit move where dst is not also a src or we have used that
8535 src already. */
8536 for (i = 0; i < size; i++)
8537 if (move[i].src != NULL_RTX)
8538 {
8539 if (move[i].links == -1
8540 || move[move[i].links].src == NULL_RTX)
8541 {
8542 moves++;
8543 /* Ignore NOP moves to self. */
8544 if (!rtx_equal_p (move[i].dst, move[i].src))
8545 emit_move_insn (move[i].dst, move[i].src);
8546
8547 /* Remove conflict from list. */
8548 move[i].src = NULL_RTX;
8549 }
8550 else
8551 blocked = i;
8552 }
8553
8554 /* Check for deadlock. This is when no moves occurred and we have
8555 at least one blocked move. */
8556 if (moves == 0 && blocked != -1)
8557 {
8558 /* Need to use scratch register to break deadlock.
8559 Add move to put dst of blocked move into scratch.
8560 When this move occurs, it will break chain deadlock.
8561 The scratch register is substituted for real move. */
8562
8563 gcc_assert (SCRATCH != GET_CODE (scratch));
8564
8565 move[size].src = move[blocked].dst;
8566 move[size].dst = scratch;
8567 /* Scratch move is never blocked. */
8568 move[size].links = -1;
8569 /* Make sure we have valid link. */
8570 gcc_assert (move[blocked].links != -1);
8571 /* Replace src of blocking move with scratch reg. */
8572 move[move[blocked].links].src = scratch;
8573 /* Make dependent on scratch move occurring. */
8574 move[blocked].links = size;
8575 size=size+1;
8576 }
8577 }
8578 while (blocked != -1);
8579 }
8580 return true;
8581 }
8582
8583
8584 /* Worker function for `ADJUST_INSN_LENGTH'. */
8585 /* Modifies the length assigned to instruction INSN
8586 LEN is the initially computed length of the insn. */
8587
8588 int
8589 avr_adjust_insn_length (rtx_insn *insn, int len)
8590 {
8591 rtx *op = recog_data.operand;
8592 enum attr_adjust_len adjust_len;
8593
8594 /* Some complex insns don't need length adjustment and therefore
8595 the length need not/must not be adjusted for these insns.
8596 It is easier to state this in an insn attribute "adjust_len" than
8597 to clutter up code here... */
8598
8599 if (JUMP_TABLE_DATA_P (insn) || recog_memoized (insn) == -1)
8600 {
8601 return len;
8602 }
8603
8604 /* Read from insn attribute "adjust_len" if/how length is to be adjusted. */
8605
8606 adjust_len = get_attr_adjust_len (insn);
8607
8608 if (adjust_len == ADJUST_LEN_NO)
8609 {
8610 /* Nothing to adjust: The length from attribute "length" is fine.
8611 This is the default. */
8612
8613 return len;
8614 }
8615
8616 /* Extract insn's operands. */
8617
8618 extract_constrain_insn_cached (insn);
8619
8620 /* Dispatch to right function. */
8621
8622 switch (adjust_len)
8623 {
8624 case ADJUST_LEN_RELOAD_IN16: output_reload_inhi (op, op[2], &len); break;
8625 case ADJUST_LEN_RELOAD_IN24: avr_out_reload_inpsi (op, op[2], &len); break;
8626 case ADJUST_LEN_RELOAD_IN32: output_reload_insisf (op, op[2], &len); break;
8627
8628 case ADJUST_LEN_OUT_BITOP: avr_out_bitop (insn, op, &len); break;
8629
8630 case ADJUST_LEN_PLUS: avr_out_plus (insn, op, &len); break;
8631 case ADJUST_LEN_ADDTO_SP: avr_out_addto_sp (op, &len); break;
8632
8633 case ADJUST_LEN_MOV8: output_movqi (insn, op, &len); break;
8634 case ADJUST_LEN_MOV16: output_movhi (insn, op, &len); break;
8635 case ADJUST_LEN_MOV24: avr_out_movpsi (insn, op, &len); break;
8636 case ADJUST_LEN_MOV32: output_movsisf (insn, op, &len); break;
8637 case ADJUST_LEN_MOVMEM: avr_out_movmem (insn, op, &len); break;
8638 case ADJUST_LEN_XLOAD: avr_out_xload (insn, op, &len); break;
8639 case ADJUST_LEN_LPM: avr_out_lpm (insn, op, &len); break;
8640 case ADJUST_LEN_SEXT: avr_out_sign_extend (insn, op, &len); break;
8641
8642 case ADJUST_LEN_SFRACT: avr_out_fract (insn, op, true, &len); break;
8643 case ADJUST_LEN_UFRACT: avr_out_fract (insn, op, false, &len); break;
8644 case ADJUST_LEN_ROUND: avr_out_round (insn, op, &len); break;
8645
8646 case ADJUST_LEN_TSTHI: avr_out_tsthi (insn, op, &len); break;
8647 case ADJUST_LEN_TSTPSI: avr_out_tstpsi (insn, op, &len); break;
8648 case ADJUST_LEN_TSTSI: avr_out_tstsi (insn, op, &len); break;
8649 case ADJUST_LEN_COMPARE: avr_out_compare (insn, op, &len); break;
8650 case ADJUST_LEN_COMPARE64: avr_out_compare64 (insn, op, &len); break;
8651
8652 case ADJUST_LEN_LSHRQI: lshrqi3_out (insn, op, &len); break;
8653 case ADJUST_LEN_LSHRHI: lshrhi3_out (insn, op, &len); break;
8654 case ADJUST_LEN_LSHRSI: lshrsi3_out (insn, op, &len); break;
8655
8656 case ADJUST_LEN_ASHRQI: ashrqi3_out (insn, op, &len); break;
8657 case ADJUST_LEN_ASHRHI: ashrhi3_out (insn, op, &len); break;
8658 case ADJUST_LEN_ASHRSI: ashrsi3_out (insn, op, &len); break;
8659
8660 case ADJUST_LEN_ASHLQI: ashlqi3_out (insn, op, &len); break;
8661 case ADJUST_LEN_ASHLHI: ashlhi3_out (insn, op, &len); break;
8662 case ADJUST_LEN_ASHLSI: ashlsi3_out (insn, op, &len); break;
8663
8664 case ADJUST_LEN_ASHLPSI: avr_out_ashlpsi3 (insn, op, &len); break;
8665 case ADJUST_LEN_ASHRPSI: avr_out_ashrpsi3 (insn, op, &len); break;
8666 case ADJUST_LEN_LSHRPSI: avr_out_lshrpsi3 (insn, op, &len); break;
8667
8668 case ADJUST_LEN_CALL: len = AVR_HAVE_JMP_CALL ? 2 : 1; break;
8669
8670 case ADJUST_LEN_INSERT_BITS: avr_out_insert_bits (op, &len); break;
8671
8672 default:
8673 gcc_unreachable();
8674 }
8675
8676 return len;
8677 }
8678
8679 /* Return nonzero if register REG dead after INSN. */
8680
8681 int
8682 reg_unused_after (rtx_insn *insn, rtx reg)
8683 {
8684 return (dead_or_set_p (insn, reg)
8685 || (REG_P(reg) && _reg_unused_after (insn, reg)));
8686 }
8687
8688 /* Return nonzero if REG is not used after INSN.
8689 We assume REG is a reload reg, and therefore does
8690 not live past labels. It may live past calls or jumps though. */
8691
8692 int
8693 _reg_unused_after (rtx_insn *insn, rtx reg)
8694 {
8695 enum rtx_code code;
8696 rtx set;
8697
8698 /* If the reg is set by this instruction, then it is safe for our
8699 case. Disregard the case where this is a store to memory, since
8700 we are checking a register used in the store address. */
8701 set = single_set (insn);
8702 if (set && GET_CODE (SET_DEST (set)) != MEM
8703 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
8704 return 1;
8705
8706 while ((insn = NEXT_INSN (insn)))
8707 {
8708 rtx set;
8709 code = GET_CODE (insn);
8710
8711 #if 0
8712 /* If this is a label that existed before reload, then the register
8713 if dead here. However, if this is a label added by reorg, then
8714 the register may still be live here. We can't tell the difference,
8715 so we just ignore labels completely. */
8716 if (code == CODE_LABEL)
8717 return 1;
8718 /* else */
8719 #endif
8720
8721 if (!INSN_P (insn))
8722 continue;
8723
8724 if (code == JUMP_INSN)
8725 return 0;
8726
8727 /* If this is a sequence, we must handle them all at once.
8728 We could have for instance a call that sets the target register,
8729 and an insn in a delay slot that uses the register. In this case,
8730 we must return 0. */
8731 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
8732 {
8733 rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (insn));
8734 int i;
8735 int retval = 0;
8736
8737 for (i = 0; i < seq->len (); i++)
8738 {
8739 rtx_insn *this_insn = seq->insn (i);
8740 rtx set = single_set (this_insn);
8741
8742 if (CALL_P (this_insn))
8743 code = CALL_INSN;
8744 else if (JUMP_P (this_insn))
8745 {
8746 if (INSN_ANNULLED_BRANCH_P (this_insn))
8747 return 0;
8748 code = JUMP_INSN;
8749 }
8750
8751 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
8752 return 0;
8753 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
8754 {
8755 if (GET_CODE (SET_DEST (set)) != MEM)
8756 retval = 1;
8757 else
8758 return 0;
8759 }
8760 if (set == 0
8761 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
8762 return 0;
8763 }
8764 if (retval == 1)
8765 return 1;
8766 else if (code == JUMP_INSN)
8767 return 0;
8768 }
8769
8770 if (code == CALL_INSN)
8771 {
8772 rtx tem;
8773 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
8774 if (GET_CODE (XEXP (tem, 0)) == USE
8775 && REG_P (XEXP (XEXP (tem, 0), 0))
8776 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
8777 return 0;
8778 if (call_used_regs[REGNO (reg)])
8779 return 1;
8780 }
8781
8782 set = single_set (insn);
8783
8784 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
8785 return 0;
8786 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
8787 return GET_CODE (SET_DEST (set)) != MEM;
8788 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
8789 return 0;
8790 }
8791 return 1;
8792 }
8793
8794
8795 /* Implement `TARGET_ASM_INTEGER'. */
8796 /* Target hook for assembling integer objects. The AVR version needs
8797 special handling for references to certain labels. */
8798
8799 static bool
8800 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
8801 {
8802 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
8803 && text_segment_operand (x, VOIDmode))
8804 {
8805 fputs ("\t.word\tgs(", asm_out_file);
8806 output_addr_const (asm_out_file, x);
8807 fputs (")\n", asm_out_file);
8808
8809 return true;
8810 }
8811 else if (GET_MODE (x) == PSImode)
8812 {
8813 /* This needs binutils 2.23+, see PR binutils/13503 */
8814
8815 fputs ("\t.byte\tlo8(", asm_out_file);
8816 output_addr_const (asm_out_file, x);
8817 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
8818
8819 fputs ("\t.byte\thi8(", asm_out_file);
8820 output_addr_const (asm_out_file, x);
8821 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
8822
8823 fputs ("\t.byte\thh8(", asm_out_file);
8824 output_addr_const (asm_out_file, x);
8825 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
8826
8827 return true;
8828 }
8829 else if (CONST_FIXED_P (x))
8830 {
8831 unsigned n;
8832
8833 /* varasm fails to handle big fixed modes that don't fit in hwi. */
8834
8835 for (n = 0; n < size; n++)
8836 {
8837 rtx xn = simplify_gen_subreg (QImode, x, GET_MODE (x), n);
8838 default_assemble_integer (xn, 1, aligned_p);
8839 }
8840
8841 return true;
8842 }
8843
8844 return default_assemble_integer (x, size, aligned_p);
8845 }
8846
8847
8848 /* Implement `TARGET_CLASS_LIKELY_SPILLED_P'. */
8849 /* Return value is nonzero if pseudos that have been
8850 assigned to registers of class CLASS would likely be spilled
8851 because registers of CLASS are needed for spill registers. */
8852
8853 static bool
8854 avr_class_likely_spilled_p (reg_class_t c)
8855 {
8856 return (c != ALL_REGS &&
8857 (AVR_TINY ? 1 : c != ADDW_REGS));
8858 }
8859
8860
8861 /* Valid attributes:
8862 progmem - Put data to program memory.
8863 signal - Make a function to be hardware interrupt.
8864 After function prologue interrupts remain disabled.
8865 interrupt - Make a function to be hardware interrupt. Before function
8866 prologue interrupts are enabled by means of SEI.
8867 naked - Don't generate function prologue/epilogue and RET
8868 instruction. */
8869
8870 /* Handle a "progmem" attribute; arguments as in
8871 struct attribute_spec.handler. */
8872
8873 static tree
8874 avr_handle_progmem_attribute (tree *node, tree name,
8875 tree args ATTRIBUTE_UNUSED,
8876 int flags ATTRIBUTE_UNUSED,
8877 bool *no_add_attrs)
8878 {
8879 if (DECL_P (*node))
8880 {
8881 if (TREE_CODE (*node) == TYPE_DECL)
8882 {
8883 /* This is really a decl attribute, not a type attribute,
8884 but try to handle it for GCC 3.0 backwards compatibility. */
8885
8886 tree type = TREE_TYPE (*node);
8887 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
8888 tree newtype = build_type_attribute_variant (type, attr);
8889
8890 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
8891 TREE_TYPE (*node) = newtype;
8892 *no_add_attrs = true;
8893 }
8894 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
8895 {
8896 *no_add_attrs = false;
8897 }
8898 else
8899 {
8900 warning (OPT_Wattributes, "%qE attribute ignored",
8901 name);
8902 *no_add_attrs = true;
8903 }
8904 }
8905
8906 return NULL_TREE;
8907 }
8908
8909 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
8910 struct attribute_spec.handler. */
8911
8912 static tree
8913 avr_handle_fndecl_attribute (tree *node, tree name,
8914 tree args ATTRIBUTE_UNUSED,
8915 int flags ATTRIBUTE_UNUSED,
8916 bool *no_add_attrs)
8917 {
8918 if (TREE_CODE (*node) != FUNCTION_DECL)
8919 {
8920 warning (OPT_Wattributes, "%qE attribute only applies to functions",
8921 name);
8922 *no_add_attrs = true;
8923 }
8924
8925 return NULL_TREE;
8926 }
8927
8928 static tree
8929 avr_handle_fntype_attribute (tree *node, tree name,
8930 tree args ATTRIBUTE_UNUSED,
8931 int flags ATTRIBUTE_UNUSED,
8932 bool *no_add_attrs)
8933 {
8934 if (TREE_CODE (*node) != FUNCTION_TYPE)
8935 {
8936 warning (OPT_Wattributes, "%qE attribute only applies to functions",
8937 name);
8938 *no_add_attrs = true;
8939 }
8940
8941 return NULL_TREE;
8942 }
8943
8944 static tree
8945 avr_handle_addr_attribute (tree *node, tree name, tree args,
8946 int flags ATTRIBUTE_UNUSED, bool *no_add)
8947 {
8948 bool io_p = (strncmp (IDENTIFIER_POINTER (name), "io", 2) == 0);
8949 location_t loc = DECL_SOURCE_LOCATION (*node);
8950
8951 if (TREE_CODE (*node) != VAR_DECL)
8952 {
8953 warning_at (loc, 0, "%qE attribute only applies to variables", name);
8954 *no_add = true;
8955 }
8956
8957 if (args != NULL_TREE)
8958 {
8959 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
8960 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
8961 tree arg = TREE_VALUE (args);
8962 if (TREE_CODE (arg) != INTEGER_CST)
8963 {
8964 warning (0, "%qE attribute allows only an integer constant argument",
8965 name);
8966 *no_add = true;
8967 }
8968 else if (io_p
8969 && (!tree_fits_shwi_p (arg)
8970 || !(strcmp (IDENTIFIER_POINTER (name), "io_low") == 0
8971 ? low_io_address_operand : io_address_operand)
8972 (GEN_INT (TREE_INT_CST_LOW (arg)), QImode)))
8973 {
8974 warning_at (loc, 0, "%qE attribute address out of range", name);
8975 *no_add = true;
8976 }
8977 else
8978 {
8979 tree attribs = DECL_ATTRIBUTES (*node);
8980 const char *names[] = { "io", "io_low", "address", NULL } ;
8981 for (const char **p = names; *p; p++)
8982 {
8983 tree other = lookup_attribute (*p, attribs);
8984 if (other && TREE_VALUE (other))
8985 {
8986 warning_at (loc, 0,
8987 "both %s and %qE attribute provide address",
8988 *p, name);
8989 *no_add = true;
8990 break;
8991 }
8992 }
8993 }
8994 }
8995
8996 if (*no_add == false && io_p && !TREE_THIS_VOLATILE (*node))
8997 warning_at (loc, 0, "%qE attribute on non-volatile variable", name);
8998
8999 return NULL_TREE;
9000 }
9001
9002 rtx
9003 avr_eval_addr_attrib (rtx x)
9004 {
9005 if (GET_CODE (x) == SYMBOL_REF
9006 && (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_ADDRESS))
9007 {
9008 tree decl = SYMBOL_REF_DECL (x);
9009 tree attr = NULL_TREE;
9010
9011 if (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_IO)
9012 {
9013 attr = lookup_attribute ("io", DECL_ATTRIBUTES (decl));
9014 gcc_assert (attr);
9015 }
9016 if (!attr || !TREE_VALUE (attr))
9017 attr = lookup_attribute ("address", DECL_ATTRIBUTES (decl));
9018 gcc_assert (attr && TREE_VALUE (attr) && TREE_VALUE (TREE_VALUE (attr)));
9019 return GEN_INT (TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))));
9020 }
9021 return x;
9022 }
9023
9024
9025 /* AVR attributes. */
9026 static const struct attribute_spec
9027 avr_attribute_table[] =
9028 {
9029 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
9030 affects_type_identity } */
9031 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute,
9032 false },
9033 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute,
9034 false },
9035 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute,
9036 false },
9037 { "naked", 0, 0, false, true, true, avr_handle_fntype_attribute,
9038 false },
9039 { "OS_task", 0, 0, false, true, true, avr_handle_fntype_attribute,
9040 false },
9041 { "OS_main", 0, 0, false, true, true, avr_handle_fntype_attribute,
9042 false },
9043 { "io", 0, 1, false, false, false, avr_handle_addr_attribute,
9044 false },
9045 { "io_low", 0, 1, false, false, false, avr_handle_addr_attribute,
9046 false },
9047 { "address", 1, 1, false, false, false, avr_handle_addr_attribute,
9048 false },
9049 { NULL, 0, 0, false, false, false, NULL, false }
9050 };
9051
9052
9053 /* Look if DECL shall be placed in program memory space by
9054 means of attribute `progmem' or some address-space qualifier.
9055 Return non-zero if DECL is data that must end up in Flash and
9056 zero if the data lives in RAM (.bss, .data, .rodata, ...).
9057
9058 Return 2 if DECL is located in 24-bit flash address-space
9059 Return 1 if DECL is located in 16-bit flash address-space
9060 Return -1 if attribute `progmem' occurs in DECL or ATTRIBUTES
9061 Return 0 otherwise */
9062
9063 int
9064 avr_progmem_p (tree decl, tree attributes)
9065 {
9066 tree a;
9067
9068 if (TREE_CODE (decl) != VAR_DECL)
9069 return 0;
9070
9071 if (avr_decl_memx_p (decl))
9072 return 2;
9073
9074 if (avr_decl_flash_p (decl))
9075 return 1;
9076
9077 if (NULL_TREE
9078 != lookup_attribute ("progmem", attributes))
9079 return -1;
9080
9081 a = decl;
9082
9083 do
9084 a = TREE_TYPE(a);
9085 while (TREE_CODE (a) == ARRAY_TYPE);
9086
9087 if (a == error_mark_node)
9088 return 0;
9089
9090 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
9091 return -1;
9092
9093 return 0;
9094 }
9095
9096
9097 /* Scan type TYP for pointer references to address space ASn.
9098 Return ADDR_SPACE_GENERIC (i.e. 0) if all pointers targeting
9099 the AS are also declared to be CONST.
9100 Otherwise, return the respective address space, i.e. a value != 0. */
9101
9102 static addr_space_t
9103 avr_nonconst_pointer_addrspace (tree typ)
9104 {
9105 while (ARRAY_TYPE == TREE_CODE (typ))
9106 typ = TREE_TYPE (typ);
9107
9108 if (POINTER_TYPE_P (typ))
9109 {
9110 addr_space_t as;
9111 tree target = TREE_TYPE (typ);
9112
9113 /* Pointer to function: Test the function's return type. */
9114
9115 if (FUNCTION_TYPE == TREE_CODE (target))
9116 return avr_nonconst_pointer_addrspace (TREE_TYPE (target));
9117
9118 /* "Ordinary" pointers... */
9119
9120 while (TREE_CODE (target) == ARRAY_TYPE)
9121 target = TREE_TYPE (target);
9122
9123 /* Pointers to non-generic address space must be const.
9124 Refuse address spaces outside the device's flash. */
9125
9126 as = TYPE_ADDR_SPACE (target);
9127
9128 if (!ADDR_SPACE_GENERIC_P (as)
9129 && (!TYPE_READONLY (target)
9130 || avr_addrspace[as].segment >= avr_n_flash
9131 /* Also refuse __memx address space if we can't support it. */
9132 || (!AVR_HAVE_LPM && avr_addrspace[as].pointer_size > 2)))
9133 {
9134 return as;
9135 }
9136
9137 /* Scan pointer's target type. */
9138
9139 return avr_nonconst_pointer_addrspace (target);
9140 }
9141
9142 return ADDR_SPACE_GENERIC;
9143 }
9144
9145
9146 /* Sanity check NODE so that all pointers targeting non-generic address spaces
9147 go along with CONST qualifier. Writing to these address spaces should
9148 be detected and complained about as early as possible. */
9149
9150 static bool
9151 avr_pgm_check_var_decl (tree node)
9152 {
9153 const char *reason = NULL;
9154
9155 addr_space_t as = ADDR_SPACE_GENERIC;
9156
9157 gcc_assert (as == 0);
9158
9159 if (avr_log.progmem)
9160 avr_edump ("%?: %t\n", node);
9161
9162 switch (TREE_CODE (node))
9163 {
9164 default:
9165 break;
9166
9167 case VAR_DECL:
9168 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
9169 reason = "variable";
9170 break;
9171
9172 case PARM_DECL:
9173 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
9174 reason = "function parameter";
9175 break;
9176
9177 case FIELD_DECL:
9178 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
9179 reason = "structure field";
9180 break;
9181
9182 case FUNCTION_DECL:
9183 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (TREE_TYPE (node))),
9184 as)
9185 reason = "return type of function";
9186 break;
9187
9188 case POINTER_TYPE:
9189 if (as = avr_nonconst_pointer_addrspace (node), as)
9190 reason = "pointer";
9191 break;
9192 }
9193
9194 if (reason)
9195 {
9196 if (avr_addrspace[as].segment >= avr_n_flash)
9197 {
9198 if (TYPE_P (node))
9199 error ("%qT uses address space %qs beyond flash of %qs",
9200 node, avr_addrspace[as].name, avr_current_device->name);
9201 else
9202 error ("%s %q+D uses address space %qs beyond flash of %qs",
9203 reason, node, avr_addrspace[as].name,
9204 avr_current_device->name);
9205 }
9206 else
9207 {
9208 if (TYPE_P (node))
9209 error ("pointer targeting address space %qs must be const in %qT",
9210 avr_addrspace[as].name, node);
9211 else
9212 error ("pointer targeting address space %qs must be const"
9213 " in %s %q+D",
9214 avr_addrspace[as].name, reason, node);
9215 }
9216 }
9217
9218 return reason == NULL;
9219 }
9220
9221
9222 /* Add the section attribute if the variable is in progmem. */
9223
9224 static void
9225 avr_insert_attributes (tree node, tree *attributes)
9226 {
9227 avr_pgm_check_var_decl (node);
9228
9229 if (TREE_CODE (node) == VAR_DECL
9230 && (TREE_STATIC (node) || DECL_EXTERNAL (node))
9231 && avr_progmem_p (node, *attributes))
9232 {
9233 addr_space_t as;
9234 tree node0 = node;
9235
9236 /* For C++, we have to peel arrays in order to get correct
9237 determination of readonlyness. */
9238
9239 do
9240 node0 = TREE_TYPE (node0);
9241 while (TREE_CODE (node0) == ARRAY_TYPE);
9242
9243 if (error_mark_node == node0)
9244 return;
9245
9246 as = TYPE_ADDR_SPACE (TREE_TYPE (node));
9247
9248 if (avr_addrspace[as].segment >= avr_n_flash)
9249 {
9250 error ("variable %q+D located in address space %qs"
9251 " beyond flash of %qs",
9252 node, avr_addrspace[as].name, avr_current_device->name);
9253 }
9254 else if (!AVR_HAVE_LPM && avr_addrspace[as].pointer_size > 2)
9255 {
9256 error ("variable %q+D located in address space %qs"
9257 " which is not supported by %qs",
9258 node, avr_addrspace[as].name, avr_current_arch->arch_name);
9259 }
9260
9261 if (!TYPE_READONLY (node0)
9262 && !TREE_READONLY (node))
9263 {
9264 const char *reason = "__attribute__((progmem))";
9265
9266 if (!ADDR_SPACE_GENERIC_P (as))
9267 reason = avr_addrspace[as].name;
9268
9269 if (avr_log.progmem)
9270 avr_edump ("\n%?: %t\n%t\n", node, node0);
9271
9272 error ("variable %q+D must be const in order to be put into"
9273 " read-only section by means of %qs", node, reason);
9274 }
9275 }
9276 }
9277
9278
9279 /* Implement `ASM_OUTPUT_ALIGNED_DECL_LOCAL'. */
9280 /* Implement `ASM_OUTPUT_ALIGNED_DECL_COMMON'. */
9281 /* Track need of __do_clear_bss. */
9282
9283 void
9284 avr_asm_output_aligned_decl_common (FILE * stream,
9285 tree decl,
9286 const char *name,
9287 unsigned HOST_WIDE_INT size,
9288 unsigned int align, bool local_p)
9289 {
9290 rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl);
9291 rtx symbol;
9292
9293 if (mem != NULL_RTX && MEM_P (mem)
9294 && GET_CODE ((symbol = XEXP (mem, 0))) == SYMBOL_REF
9295 && (SYMBOL_REF_FLAGS (symbol) & (SYMBOL_FLAG_IO | SYMBOL_FLAG_ADDRESS)))
9296 {
9297
9298 if (!local_p)
9299 {
9300 fprintf (stream, "\t.globl\t");
9301 assemble_name (stream, name);
9302 fprintf (stream, "\n");
9303 }
9304 if (SYMBOL_REF_FLAGS (symbol) & SYMBOL_FLAG_ADDRESS)
9305 {
9306 assemble_name (stream, name);
9307 fprintf (stream, " = %ld\n",
9308 (long) INTVAL (avr_eval_addr_attrib (symbol)));
9309 }
9310 else if (local_p)
9311 error_at (DECL_SOURCE_LOCATION (decl),
9312 "static IO declaration for %q+D needs an address", decl);
9313 return;
9314 }
9315
9316 /* __gnu_lto_v1 etc. are just markers for the linker injected by toplev.c.
9317 There is no need to trigger __do_clear_bss code for them. */
9318
9319 if (!STR_PREFIX_P (name, "__gnu_lto"))
9320 avr_need_clear_bss_p = true;
9321
9322 if (local_p)
9323 ASM_OUTPUT_ALIGNED_LOCAL (stream, name, size, align);
9324 else
9325 ASM_OUTPUT_ALIGNED_COMMON (stream, name, size, align);
9326 }
9327
9328 void
9329 avr_asm_asm_output_aligned_bss (FILE *file, tree decl, const char *name,
9330 unsigned HOST_WIDE_INT size, int align,
9331 void (*default_func)
9332 (FILE *, tree, const char *,
9333 unsigned HOST_WIDE_INT, int))
9334 {
9335 rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl);
9336 rtx symbol;
9337
9338 if (mem != NULL_RTX && MEM_P (mem)
9339 && GET_CODE ((symbol = XEXP (mem, 0))) == SYMBOL_REF
9340 && (SYMBOL_REF_FLAGS (symbol) & (SYMBOL_FLAG_IO | SYMBOL_FLAG_ADDRESS)))
9341 {
9342 if (!(SYMBOL_REF_FLAGS (symbol) & SYMBOL_FLAG_ADDRESS))
9343 error_at (DECL_SOURCE_LOCATION (decl),
9344 "IO definition for %q+D needs an address", decl);
9345 avr_asm_output_aligned_decl_common (file, decl, name, size, align, false);
9346 }
9347 else
9348 default_func (file, decl, name, size, align);
9349 }
9350
9351
9352 /* Unnamed section callback for data_section
9353 to track need of __do_copy_data. */
9354
9355 static void
9356 avr_output_data_section_asm_op (const void *data)
9357 {
9358 avr_need_copy_data_p = true;
9359
9360 /* Dispatch to default. */
9361 output_section_asm_op (data);
9362 }
9363
9364
9365 /* Unnamed section callback for bss_section
9366 to track need of __do_clear_bss. */
9367
9368 static void
9369 avr_output_bss_section_asm_op (const void *data)
9370 {
9371 avr_need_clear_bss_p = true;
9372
9373 /* Dispatch to default. */
9374 output_section_asm_op (data);
9375 }
9376
9377
9378 /* Unnamed section callback for progmem*.data sections. */
9379
9380 static void
9381 avr_output_progmem_section_asm_op (const void *data)
9382 {
9383 fprintf (asm_out_file, "\t.section\t%s,\"a\",@progbits\n",
9384 (const char*) data);
9385 }
9386
9387
9388 /* Implement `TARGET_ASM_INIT_SECTIONS'. */
9389
9390 static void
9391 avr_asm_init_sections (void)
9392 {
9393 /* Set up a section for jump tables. Alignment is handled by
9394 ASM_OUTPUT_BEFORE_CASE_LABEL. */
9395
9396 if (AVR_HAVE_JMP_CALL)
9397 {
9398 progmem_swtable_section
9399 = get_unnamed_section (0, output_section_asm_op,
9400 "\t.section\t.progmem.gcc_sw_table"
9401 ",\"a\",@progbits");
9402 }
9403 else
9404 {
9405 progmem_swtable_section
9406 = get_unnamed_section (SECTION_CODE, output_section_asm_op,
9407 "\t.section\t.progmem.gcc_sw_table"
9408 ",\"ax\",@progbits");
9409 }
9410
9411 /* Override section callbacks to keep track of `avr_need_clear_bss_p'
9412 resp. `avr_need_copy_data_p'. */
9413
9414 readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
9415 data_section->unnamed.callback = avr_output_data_section_asm_op;
9416 bss_section->unnamed.callback = avr_output_bss_section_asm_op;
9417 }
9418
9419
9420 /* Implement `TARGET_ASM_FUNCTION_RODATA_SECTION'. */
9421
9422 static section*
9423 avr_asm_function_rodata_section (tree decl)
9424 {
9425 /* If a function is unused and optimized out by -ffunction-sections
9426 and --gc-sections, ensure that the same will happen for its jump
9427 tables by putting them into individual sections. */
9428
9429 unsigned int flags;
9430 section * frodata;
9431
9432 /* Get the frodata section from the default function in varasm.c
9433 but treat function-associated data-like jump tables as code
9434 rather than as user defined data. AVR has no constant pools. */
9435 {
9436 int fdata = flag_data_sections;
9437
9438 flag_data_sections = flag_function_sections;
9439 frodata = default_function_rodata_section (decl);
9440 flag_data_sections = fdata;
9441 flags = frodata->common.flags;
9442 }
9443
9444 if (frodata != readonly_data_section
9445 && flags & SECTION_NAMED)
9446 {
9447 /* Adjust section flags and replace section name prefix. */
9448
9449 unsigned int i;
9450
9451 static const char* const prefix[] =
9452 {
9453 ".rodata", ".progmem.gcc_sw_table",
9454 ".gnu.linkonce.r.", ".gnu.linkonce.t."
9455 };
9456
9457 for (i = 0; i < sizeof (prefix) / sizeof (*prefix); i += 2)
9458 {
9459 const char * old_prefix = prefix[i];
9460 const char * new_prefix = prefix[i+1];
9461 const char * name = frodata->named.name;
9462
9463 if (STR_PREFIX_P (name, old_prefix))
9464 {
9465 const char *rname = ACONCAT ((new_prefix,
9466 name + strlen (old_prefix), NULL));
9467 flags &= ~SECTION_CODE;
9468 flags |= AVR_HAVE_JMP_CALL ? 0 : SECTION_CODE;
9469
9470 return get_section (rname, flags, frodata->named.decl);
9471 }
9472 }
9473 }
9474
9475 return progmem_swtable_section;
9476 }
9477
9478
9479 /* Implement `TARGET_ASM_NAMED_SECTION'. */
9480 /* Track need of __do_clear_bss, __do_copy_data for named sections. */
9481
9482 static void
9483 avr_asm_named_section (const char *name, unsigned int flags, tree decl)
9484 {
9485 if (flags & AVR_SECTION_PROGMEM)
9486 {
9487 addr_space_t as = (flags & AVR_SECTION_PROGMEM) / SECTION_MACH_DEP;
9488 const char *old_prefix = ".rodata";
9489 const char *new_prefix = avr_addrspace[as].section_name;
9490
9491 if (STR_PREFIX_P (name, old_prefix))
9492 {
9493 const char *sname = ACONCAT ((new_prefix,
9494 name + strlen (old_prefix), NULL));
9495 default_elf_asm_named_section (sname, flags, decl);
9496 return;
9497 }
9498
9499 default_elf_asm_named_section (new_prefix, flags, decl);
9500 return;
9501 }
9502
9503 if (!avr_need_copy_data_p)
9504 avr_need_copy_data_p = (STR_PREFIX_P (name, ".data")
9505 || STR_PREFIX_P (name, ".rodata")
9506 || STR_PREFIX_P (name, ".gnu.linkonce.d"));
9507
9508 if (!avr_need_clear_bss_p)
9509 avr_need_clear_bss_p = STR_PREFIX_P (name, ".bss");
9510
9511 default_elf_asm_named_section (name, flags, decl);
9512 }
9513
9514
9515 /* Implement `TARGET_SECTION_TYPE_FLAGS'. */
9516
9517 static unsigned int
9518 avr_section_type_flags (tree decl, const char *name, int reloc)
9519 {
9520 unsigned int flags = default_section_type_flags (decl, name, reloc);
9521
9522 if (STR_PREFIX_P (name, ".noinit"))
9523 {
9524 if (decl && TREE_CODE (decl) == VAR_DECL
9525 && DECL_INITIAL (decl) == NULL_TREE)
9526 flags |= SECTION_BSS; /* @nobits */
9527 else
9528 warning (0, "only uninitialized variables can be placed in the "
9529 ".noinit section");
9530 }
9531
9532 if (decl && DECL_P (decl)
9533 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
9534 {
9535 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
9536
9537 /* Attribute progmem puts data in generic address space.
9538 Set section flags as if it was in __flash to get the right
9539 section prefix in the remainder. */
9540
9541 if (ADDR_SPACE_GENERIC_P (as))
9542 as = ADDR_SPACE_FLASH;
9543
9544 flags |= as * SECTION_MACH_DEP;
9545 flags &= ~SECTION_WRITE;
9546 flags &= ~SECTION_BSS;
9547 }
9548
9549 return flags;
9550 }
9551
9552
9553 /* Implement `TARGET_ENCODE_SECTION_INFO'. */
9554
9555 static void
9556 avr_encode_section_info (tree decl, rtx rtl, int new_decl_p)
9557 {
9558 /* In avr_handle_progmem_attribute, DECL_INITIAL is not yet
9559 readily available, see PR34734. So we postpone the warning
9560 about uninitialized data in program memory section until here. */
9561
9562 if (new_decl_p
9563 && decl && DECL_P (decl)
9564 && NULL_TREE == DECL_INITIAL (decl)
9565 && !DECL_EXTERNAL (decl)
9566 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
9567 {
9568 warning (OPT_Wuninitialized,
9569 "uninitialized variable %q+D put into "
9570 "program memory area", decl);
9571 }
9572
9573 default_encode_section_info (decl, rtl, new_decl_p);
9574
9575 if (decl && DECL_P (decl)
9576 && TREE_CODE (decl) != FUNCTION_DECL
9577 && MEM_P (rtl)
9578 && SYMBOL_REF == GET_CODE (XEXP (rtl, 0)))
9579 {
9580 rtx sym = XEXP (rtl, 0);
9581 tree type = TREE_TYPE (decl);
9582 tree attr = DECL_ATTRIBUTES (decl);
9583 if (type == error_mark_node)
9584 return;
9585
9586 addr_space_t as = TYPE_ADDR_SPACE (type);
9587
9588 /* PSTR strings are in generic space but located in flash:
9589 patch address space. */
9590
9591 if (-1 == avr_progmem_p (decl, attr))
9592 as = ADDR_SPACE_FLASH;
9593
9594 AVR_SYMBOL_SET_ADDR_SPACE (sym, as);
9595
9596 tree io_low_attr = lookup_attribute ("io_low", attr);
9597 tree io_attr = lookup_attribute ("io", attr);
9598 tree addr_attr;
9599 if (io_low_attr
9600 && TREE_VALUE (io_low_attr) && TREE_VALUE (TREE_VALUE (io_low_attr)))
9601 addr_attr = io_attr;
9602 else if (io_attr
9603 && TREE_VALUE (io_attr) && TREE_VALUE (TREE_VALUE (io_attr)))
9604 addr_attr = io_attr;
9605 else
9606 addr_attr = lookup_attribute ("address", attr);
9607 if (io_low_attr
9608 || (io_attr && addr_attr
9609 && low_io_address_operand
9610 (GEN_INT (TREE_INT_CST_LOW
9611 (TREE_VALUE (TREE_VALUE (addr_attr)))), QImode)))
9612 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_IO_LOW;
9613 if (io_attr || io_low_attr)
9614 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_IO;
9615 /* If we have an (io) address attribute specification, but the variable
9616 is external, treat the address as only a tentative definition
9617 to be used to determine if an io port is in the lower range, but
9618 don't use the exact value for constant propagation. */
9619 if (addr_attr && !DECL_EXTERNAL (decl))
9620 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_ADDRESS;
9621 }
9622 }
9623
9624
9625 /* Implement `TARGET_ASM_SELECT_SECTION' */
9626
9627 static section *
9628 avr_asm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
9629 {
9630 section * sect = default_elf_select_section (decl, reloc, align);
9631
9632 if (decl && DECL_P (decl)
9633 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
9634 {
9635 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
9636
9637 /* __progmem__ goes in generic space but shall be allocated to
9638 .progmem.data */
9639
9640 if (ADDR_SPACE_GENERIC_P (as))
9641 as = ADDR_SPACE_FLASH;
9642
9643 if (sect->common.flags & SECTION_NAMED)
9644 {
9645 const char * name = sect->named.name;
9646 const char * old_prefix = ".rodata";
9647 const char * new_prefix = avr_addrspace[as].section_name;
9648
9649 if (STR_PREFIX_P (name, old_prefix))
9650 {
9651 const char *sname = ACONCAT ((new_prefix,
9652 name + strlen (old_prefix), NULL));
9653 return get_section (sname, sect->common.flags, sect->named.decl);
9654 }
9655 }
9656
9657 if (!progmem_section[as])
9658 {
9659 progmem_section[as]
9660 = get_unnamed_section (0, avr_output_progmem_section_asm_op,
9661 avr_addrspace[as].section_name);
9662 }
9663
9664 return progmem_section[as];
9665 }
9666
9667 return sect;
9668 }
9669
9670 /* Implement `TARGET_ASM_FILE_START'. */
9671 /* Outputs some text at the start of each assembler file. */
9672
9673 static void
9674 avr_file_start (void)
9675 {
9676 int sfr_offset = avr_current_arch->sfr_offset;
9677
9678 if (avr_current_arch->asm_only)
9679 error ("MCU %qs supported for assembler only", avr_current_device->name);
9680
9681 default_file_start ();
9682
9683 /* Print I/O addresses of some SFRs used with IN and OUT. */
9684
9685 if (AVR_HAVE_SPH)
9686 fprintf (asm_out_file, "__SP_H__ = 0x%02x\n", avr_addr.sp_h - sfr_offset);
9687
9688 fprintf (asm_out_file, "__SP_L__ = 0x%02x\n", avr_addr.sp_l - sfr_offset);
9689 fprintf (asm_out_file, "__SREG__ = 0x%02x\n", avr_addr.sreg - sfr_offset);
9690 if (AVR_HAVE_RAMPZ)
9691 fprintf (asm_out_file, "__RAMPZ__ = 0x%02x\n", avr_addr.rampz - sfr_offset);
9692 if (AVR_HAVE_RAMPY)
9693 fprintf (asm_out_file, "__RAMPY__ = 0x%02x\n", avr_addr.rampy - sfr_offset);
9694 if (AVR_HAVE_RAMPX)
9695 fprintf (asm_out_file, "__RAMPX__ = 0x%02x\n", avr_addr.rampx - sfr_offset);
9696 if (AVR_HAVE_RAMPD)
9697 fprintf (asm_out_file, "__RAMPD__ = 0x%02x\n", avr_addr.rampd - sfr_offset);
9698 if (AVR_XMEGA || AVR_TINY)
9699 fprintf (asm_out_file, "__CCP__ = 0x%02x\n", avr_addr.ccp - sfr_offset);
9700 fprintf (asm_out_file, "__tmp_reg__ = %d\n", AVR_TMP_REGNO);
9701 fprintf (asm_out_file, "__zero_reg__ = %d\n", AVR_ZERO_REGNO);
9702 }
9703
9704
9705 /* Implement `TARGET_ASM_FILE_END'. */
9706 /* Outputs to the stdio stream FILE some
9707 appropriate text to go at the end of an assembler file. */
9708
9709 static void
9710 avr_file_end (void)
9711 {
9712 /* Output these only if there is anything in the
9713 .data* / .rodata* / .gnu.linkonce.* resp. .bss* or COMMON
9714 input section(s) - some code size can be saved by not
9715 linking in the initialization code from libgcc if resp.
9716 sections are empty, see PR18145. */
9717
9718 if (avr_need_copy_data_p)
9719 fputs (".global __do_copy_data\n", asm_out_file);
9720
9721 if (avr_need_clear_bss_p)
9722 fputs (".global __do_clear_bss\n", asm_out_file);
9723 }
9724
9725
9726 /* Worker function for `ADJUST_REG_ALLOC_ORDER'. */
9727 /* Choose the order in which to allocate hard registers for
9728 pseudo-registers local to a basic block.
9729
9730 Store the desired register order in the array `reg_alloc_order'.
9731 Element 0 should be the register to allocate first; element 1, the
9732 next register; and so on. */
9733
9734 void
9735 avr_adjust_reg_alloc_order (void)
9736 {
9737 unsigned int i;
9738 static const int order_0[] =
9739 {
9740 24, 25,
9741 18, 19, 20, 21, 22, 23,
9742 30, 31,
9743 26, 27, 28, 29,
9744 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
9745 0, 1,
9746 32, 33, 34, 35
9747 };
9748 static const int tiny_order_0[] = {
9749 20, 21,
9750 22, 23,
9751 24, 25,
9752 30, 31,
9753 26, 27,
9754 28, 29,
9755 19, 18,
9756 16, 17,
9757 32, 33, 34, 35,
9758 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
9759 };
9760 static const int order_1[] =
9761 {
9762 18, 19, 20, 21, 22, 23, 24, 25,
9763 30, 31,
9764 26, 27, 28, 29,
9765 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
9766 0, 1,
9767 32, 33, 34, 35
9768 };
9769 static const int tiny_order_1[] = {
9770 22, 23,
9771 24, 25,
9772 30, 31,
9773 26, 27,
9774 28, 29,
9775 21, 20, 19, 18,
9776 16, 17,
9777 32, 33, 34, 35,
9778 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
9779 };
9780 static const int order_2[] =
9781 {
9782 25, 24, 23, 22, 21, 20, 19, 18,
9783 30, 31,
9784 26, 27, 28, 29,
9785 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
9786 1, 0,
9787 32, 33, 34, 35
9788 };
9789
9790 /* Select specific register allocation order.
9791 Tiny Core (ATtiny4/5/9/10/20/40) devices have only 16 registers,
9792 so different allocation order should be used. */
9793
9794 const int *order = (TARGET_ORDER_1 ? (AVR_TINY ? tiny_order_1 : order_1)
9795 : TARGET_ORDER_2 ? (AVR_TINY ? tiny_order_0 : order_2)
9796 : (AVR_TINY ? tiny_order_0 : order_0));
9797
9798 for (i = 0; i < ARRAY_SIZE (order_0); ++i)
9799 reg_alloc_order[i] = order[i];
9800 }
9801
9802
9803 /* Implement `TARGET_REGISTER_MOVE_COST' */
9804
9805 static int
9806 avr_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
9807 reg_class_t from, reg_class_t to)
9808 {
9809 return (from == STACK_REG ? 6
9810 : to == STACK_REG ? 12
9811 : 2);
9812 }
9813
9814
9815 /* Implement `TARGET_MEMORY_MOVE_COST' */
9816
9817 static int
9818 avr_memory_move_cost (machine_mode mode,
9819 reg_class_t rclass ATTRIBUTE_UNUSED,
9820 bool in ATTRIBUTE_UNUSED)
9821 {
9822 return (mode == QImode ? 2
9823 : mode == HImode ? 4
9824 : mode == SImode ? 8
9825 : mode == SFmode ? 8
9826 : 16);
9827 }
9828
9829
9830 /* Mutually recursive subroutine of avr_rtx_cost for calculating the
9831 cost of an RTX operand given its context. X is the rtx of the
9832 operand, MODE is its mode, and OUTER is the rtx_code of this
9833 operand's parent operator. */
9834
9835 static int
9836 avr_operand_rtx_cost (rtx x, machine_mode mode, enum rtx_code outer,
9837 int opno, bool speed)
9838 {
9839 enum rtx_code code = GET_CODE (x);
9840 int total;
9841
9842 switch (code)
9843 {
9844 case REG:
9845 case SUBREG:
9846 return 0;
9847
9848 case CONST_INT:
9849 case CONST_FIXED:
9850 case CONST_DOUBLE:
9851 return COSTS_N_INSNS (GET_MODE_SIZE (mode));
9852
9853 default:
9854 break;
9855 }
9856
9857 total = 0;
9858 avr_rtx_costs (x, code, outer, opno, &total, speed);
9859 return total;
9860 }
9861
9862 /* Worker function for AVR backend's rtx_cost function.
9863 X is rtx expression whose cost is to be calculated.
9864 Return true if the complete cost has been computed.
9865 Return false if subexpressions should be scanned.
9866 In either case, *TOTAL contains the cost result. */
9867
9868 static bool
9869 avr_rtx_costs_1 (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED,
9870 int opno ATTRIBUTE_UNUSED, int *total, bool speed)
9871 {
9872 enum rtx_code code = (enum rtx_code) codearg;
9873 machine_mode mode = GET_MODE (x);
9874 HOST_WIDE_INT val;
9875
9876 switch (code)
9877 {
9878 case CONST_INT:
9879 case CONST_FIXED:
9880 case CONST_DOUBLE:
9881 case SYMBOL_REF:
9882 case CONST:
9883 case LABEL_REF:
9884 /* Immediate constants are as cheap as registers. */
9885 *total = 0;
9886 return true;
9887
9888 case MEM:
9889 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
9890 return true;
9891
9892 case NEG:
9893 switch (mode)
9894 {
9895 case QImode:
9896 case SFmode:
9897 *total = COSTS_N_INSNS (1);
9898 break;
9899
9900 case HImode:
9901 case PSImode:
9902 case SImode:
9903 *total = COSTS_N_INSNS (2 * GET_MODE_SIZE (mode) - 1);
9904 break;
9905
9906 default:
9907 return false;
9908 }
9909 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9910 return true;
9911
9912 case ABS:
9913 switch (mode)
9914 {
9915 case QImode:
9916 case SFmode:
9917 *total = COSTS_N_INSNS (1);
9918 break;
9919
9920 default:
9921 return false;
9922 }
9923 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9924 return true;
9925
9926 case NOT:
9927 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
9928 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9929 return true;
9930
9931 case ZERO_EXTEND:
9932 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
9933 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
9934 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9935 return true;
9936
9937 case SIGN_EXTEND:
9938 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
9939 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
9940 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9941 return true;
9942
9943 case PLUS:
9944 switch (mode)
9945 {
9946 case QImode:
9947 if (AVR_HAVE_MUL
9948 && MULT == GET_CODE (XEXP (x, 0))
9949 && register_operand (XEXP (x, 1), QImode))
9950 {
9951 /* multiply-add */
9952 *total = COSTS_N_INSNS (speed ? 4 : 3);
9953 /* multiply-add with constant: will be split and load constant. */
9954 if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
9955 *total = COSTS_N_INSNS (1) + *total;
9956 return true;
9957 }
9958 *total = COSTS_N_INSNS (1);
9959 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9960 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
9961 break;
9962
9963 case HImode:
9964 if (AVR_HAVE_MUL
9965 && (MULT == GET_CODE (XEXP (x, 0))
9966 || ASHIFT == GET_CODE (XEXP (x, 0)))
9967 && register_operand (XEXP (x, 1), HImode)
9968 && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))
9969 || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))))
9970 {
9971 /* multiply-add */
9972 *total = COSTS_N_INSNS (speed ? 5 : 4);
9973 /* multiply-add with constant: will be split and load constant. */
9974 if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
9975 *total = COSTS_N_INSNS (1) + *total;
9976 return true;
9977 }
9978 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9979 {
9980 *total = COSTS_N_INSNS (2);
9981 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9982 speed);
9983 }
9984 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
9985 *total = COSTS_N_INSNS (1);
9986 else
9987 *total = COSTS_N_INSNS (2);
9988 break;
9989
9990 case PSImode:
9991 if (!CONST_INT_P (XEXP (x, 1)))
9992 {
9993 *total = COSTS_N_INSNS (3);
9994 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
9995 speed);
9996 }
9997 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
9998 *total = COSTS_N_INSNS (2);
9999 else
10000 *total = COSTS_N_INSNS (3);
10001 break;
10002
10003 case SImode:
10004 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10005 {
10006 *total = COSTS_N_INSNS (4);
10007 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10008 speed);
10009 }
10010 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
10011 *total = COSTS_N_INSNS (1);
10012 else
10013 *total = COSTS_N_INSNS (4);
10014 break;
10015
10016 default:
10017 return false;
10018 }
10019 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10020 return true;
10021
10022 case MINUS:
10023 if (AVR_HAVE_MUL
10024 && QImode == mode
10025 && register_operand (XEXP (x, 0), QImode)
10026 && MULT == GET_CODE (XEXP (x, 1)))
10027 {
10028 /* multiply-sub */
10029 *total = COSTS_N_INSNS (speed ? 4 : 3);
10030 /* multiply-sub with constant: will be split and load constant. */
10031 if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
10032 *total = COSTS_N_INSNS (1) + *total;
10033 return true;
10034 }
10035 if (AVR_HAVE_MUL
10036 && HImode == mode
10037 && register_operand (XEXP (x, 0), HImode)
10038 && (MULT == GET_CODE (XEXP (x, 1))
10039 || ASHIFT == GET_CODE (XEXP (x, 1)))
10040 && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))
10041 || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))))
10042 {
10043 /* multiply-sub */
10044 *total = COSTS_N_INSNS (speed ? 5 : 4);
10045 /* multiply-sub with constant: will be split and load constant. */
10046 if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
10047 *total = COSTS_N_INSNS (1) + *total;
10048 return true;
10049 }
10050 /* FALLTHRU */
10051 case AND:
10052 case IOR:
10053 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
10054 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10055 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10056 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
10057 return true;
10058
10059 case XOR:
10060 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
10061 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10062 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
10063 return true;
10064
10065 case MULT:
10066 switch (mode)
10067 {
10068 case QImode:
10069 if (AVR_HAVE_MUL)
10070 *total = COSTS_N_INSNS (!speed ? 3 : 4);
10071 else if (!speed)
10072 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
10073 else
10074 return false;
10075 break;
10076
10077 case HImode:
10078 if (AVR_HAVE_MUL)
10079 {
10080 rtx op0 = XEXP (x, 0);
10081 rtx op1 = XEXP (x, 1);
10082 enum rtx_code code0 = GET_CODE (op0);
10083 enum rtx_code code1 = GET_CODE (op1);
10084 bool ex0 = SIGN_EXTEND == code0 || ZERO_EXTEND == code0;
10085 bool ex1 = SIGN_EXTEND == code1 || ZERO_EXTEND == code1;
10086
10087 if (ex0
10088 && (u8_operand (op1, HImode)
10089 || s8_operand (op1, HImode)))
10090 {
10091 *total = COSTS_N_INSNS (!speed ? 4 : 6);
10092 return true;
10093 }
10094 if (ex0
10095 && register_operand (op1, HImode))
10096 {
10097 *total = COSTS_N_INSNS (!speed ? 5 : 8);
10098 return true;
10099 }
10100 else if (ex0 || ex1)
10101 {
10102 *total = COSTS_N_INSNS (!speed ? 3 : 5);
10103 return true;
10104 }
10105 else if (register_operand (op0, HImode)
10106 && (u8_operand (op1, HImode)
10107 || s8_operand (op1, HImode)))
10108 {
10109 *total = COSTS_N_INSNS (!speed ? 6 : 9);
10110 return true;
10111 }
10112 else
10113 *total = COSTS_N_INSNS (!speed ? 7 : 10);
10114 }
10115 else if (!speed)
10116 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
10117 else
10118 return false;
10119 break;
10120
10121 case PSImode:
10122 if (!speed)
10123 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
10124 else
10125 *total = 10;
10126 break;
10127
10128 case SImode:
10129 if (AVR_HAVE_MUL)
10130 {
10131 if (!speed)
10132 {
10133 /* Add some additional costs besides CALL like moves etc. */
10134
10135 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
10136 }
10137 else
10138 {
10139 /* Just a rough estimate. Even with -O2 we don't want bulky
10140 code expanded inline. */
10141
10142 *total = COSTS_N_INSNS (25);
10143 }
10144 }
10145 else
10146 {
10147 if (speed)
10148 *total = COSTS_N_INSNS (300);
10149 else
10150 /* Add some additional costs besides CALL like moves etc. */
10151 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
10152 }
10153
10154 return true;
10155
10156 default:
10157 return false;
10158 }
10159 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10160 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
10161 return true;
10162
10163 case DIV:
10164 case MOD:
10165 case UDIV:
10166 case UMOD:
10167 if (!speed)
10168 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
10169 else
10170 *total = COSTS_N_INSNS (15 * GET_MODE_SIZE (mode));
10171 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10172 /* For div/mod with const-int divisor we have at least the cost of
10173 loading the divisor. */
10174 if (CONST_INT_P (XEXP (x, 1)))
10175 *total += COSTS_N_INSNS (GET_MODE_SIZE (mode));
10176 /* Add some overall penaly for clobbering and moving around registers */
10177 *total += COSTS_N_INSNS (2);
10178 return true;
10179
10180 case ROTATE:
10181 switch (mode)
10182 {
10183 case QImode:
10184 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 4)
10185 *total = COSTS_N_INSNS (1);
10186
10187 break;
10188
10189 case HImode:
10190 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 8)
10191 *total = COSTS_N_INSNS (3);
10192
10193 break;
10194
10195 case SImode:
10196 if (CONST_INT_P (XEXP (x, 1)))
10197 switch (INTVAL (XEXP (x, 1)))
10198 {
10199 case 8:
10200 case 24:
10201 *total = COSTS_N_INSNS (5);
10202 break;
10203 case 16:
10204 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 6);
10205 break;
10206 }
10207 break;
10208
10209 default:
10210 return false;
10211 }
10212 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10213 return true;
10214
10215 case ASHIFT:
10216 switch (mode)
10217 {
10218 case QImode:
10219 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10220 {
10221 *total = COSTS_N_INSNS (!speed ? 4 : 17);
10222 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10223 speed);
10224 }
10225 else
10226 {
10227 val = INTVAL (XEXP (x, 1));
10228 if (val == 7)
10229 *total = COSTS_N_INSNS (3);
10230 else if (val >= 0 && val <= 7)
10231 *total = COSTS_N_INSNS (val);
10232 else
10233 *total = COSTS_N_INSNS (1);
10234 }
10235 break;
10236
10237 case HImode:
10238 if (AVR_HAVE_MUL)
10239 {
10240 if (const_2_to_7_operand (XEXP (x, 1), HImode)
10241 && (SIGN_EXTEND == GET_CODE (XEXP (x, 0))
10242 || ZERO_EXTEND == GET_CODE (XEXP (x, 0))))
10243 {
10244 *total = COSTS_N_INSNS (!speed ? 4 : 6);
10245 return true;
10246 }
10247 }
10248
10249 if (const1_rtx == (XEXP (x, 1))
10250 && SIGN_EXTEND == GET_CODE (XEXP (x, 0)))
10251 {
10252 *total = COSTS_N_INSNS (2);
10253 return true;
10254 }
10255
10256 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10257 {
10258 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10259 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10260 speed);
10261 }
10262 else
10263 switch (INTVAL (XEXP (x, 1)))
10264 {
10265 case 0:
10266 *total = 0;
10267 break;
10268 case 1:
10269 case 8:
10270 *total = COSTS_N_INSNS (2);
10271 break;
10272 case 9:
10273 *total = COSTS_N_INSNS (3);
10274 break;
10275 case 2:
10276 case 3:
10277 case 10:
10278 case 15:
10279 *total = COSTS_N_INSNS (4);
10280 break;
10281 case 7:
10282 case 11:
10283 case 12:
10284 *total = COSTS_N_INSNS (5);
10285 break;
10286 case 4:
10287 *total = COSTS_N_INSNS (!speed ? 5 : 8);
10288 break;
10289 case 6:
10290 *total = COSTS_N_INSNS (!speed ? 5 : 9);
10291 break;
10292 case 5:
10293 *total = COSTS_N_INSNS (!speed ? 5 : 10);
10294 break;
10295 default:
10296 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10297 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10298 speed);
10299 }
10300 break;
10301
10302 case PSImode:
10303 if (!CONST_INT_P (XEXP (x, 1)))
10304 {
10305 *total = COSTS_N_INSNS (!speed ? 6 : 73);
10306 }
10307 else
10308 switch (INTVAL (XEXP (x, 1)))
10309 {
10310 case 0:
10311 *total = 0;
10312 break;
10313 case 1:
10314 case 8:
10315 case 16:
10316 *total = COSTS_N_INSNS (3);
10317 break;
10318 case 23:
10319 *total = COSTS_N_INSNS (5);
10320 break;
10321 default:
10322 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
10323 break;
10324 }
10325 break;
10326
10327 case SImode:
10328 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10329 {
10330 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10331 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10332 speed);
10333 }
10334 else
10335 switch (INTVAL (XEXP (x, 1)))
10336 {
10337 case 0:
10338 *total = 0;
10339 break;
10340 case 24:
10341 *total = COSTS_N_INSNS (3);
10342 break;
10343 case 1:
10344 case 8:
10345 case 16:
10346 *total = COSTS_N_INSNS (4);
10347 break;
10348 case 31:
10349 *total = COSTS_N_INSNS (6);
10350 break;
10351 case 2:
10352 *total = COSTS_N_INSNS (!speed ? 7 : 8);
10353 break;
10354 default:
10355 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10356 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10357 speed);
10358 }
10359 break;
10360
10361 default:
10362 return false;
10363 }
10364 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10365 return true;
10366
10367 case ASHIFTRT:
10368 switch (mode)
10369 {
10370 case QImode:
10371 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10372 {
10373 *total = COSTS_N_INSNS (!speed ? 4 : 17);
10374 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10375 speed);
10376 }
10377 else
10378 {
10379 val = INTVAL (XEXP (x, 1));
10380 if (val == 6)
10381 *total = COSTS_N_INSNS (4);
10382 else if (val == 7)
10383 *total = COSTS_N_INSNS (2);
10384 else if (val >= 0 && val <= 7)
10385 *total = COSTS_N_INSNS (val);
10386 else
10387 *total = COSTS_N_INSNS (1);
10388 }
10389 break;
10390
10391 case HImode:
10392 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10393 {
10394 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10395 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10396 speed);
10397 }
10398 else
10399 switch (INTVAL (XEXP (x, 1)))
10400 {
10401 case 0:
10402 *total = 0;
10403 break;
10404 case 1:
10405 *total = COSTS_N_INSNS (2);
10406 break;
10407 case 15:
10408 *total = COSTS_N_INSNS (3);
10409 break;
10410 case 2:
10411 case 7:
10412 case 8:
10413 case 9:
10414 *total = COSTS_N_INSNS (4);
10415 break;
10416 case 10:
10417 case 14:
10418 *total = COSTS_N_INSNS (5);
10419 break;
10420 case 11:
10421 *total = COSTS_N_INSNS (!speed ? 5 : 6);
10422 break;
10423 case 12:
10424 *total = COSTS_N_INSNS (!speed ? 5 : 7);
10425 break;
10426 case 6:
10427 case 13:
10428 *total = COSTS_N_INSNS (!speed ? 5 : 8);
10429 break;
10430 default:
10431 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10432 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10433 speed);
10434 }
10435 break;
10436
10437 case PSImode:
10438 if (!CONST_INT_P (XEXP (x, 1)))
10439 {
10440 *total = COSTS_N_INSNS (!speed ? 6 : 73);
10441 }
10442 else
10443 switch (INTVAL (XEXP (x, 1)))
10444 {
10445 case 0:
10446 *total = 0;
10447 break;
10448 case 1:
10449 *total = COSTS_N_INSNS (3);
10450 break;
10451 case 16:
10452 case 8:
10453 *total = COSTS_N_INSNS (5);
10454 break;
10455 case 23:
10456 *total = COSTS_N_INSNS (4);
10457 break;
10458 default:
10459 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
10460 break;
10461 }
10462 break;
10463
10464 case SImode:
10465 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10466 {
10467 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10468 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10469 speed);
10470 }
10471 else
10472 switch (INTVAL (XEXP (x, 1)))
10473 {
10474 case 0:
10475 *total = 0;
10476 break;
10477 case 1:
10478 *total = COSTS_N_INSNS (4);
10479 break;
10480 case 8:
10481 case 16:
10482 case 24:
10483 *total = COSTS_N_INSNS (6);
10484 break;
10485 case 2:
10486 *total = COSTS_N_INSNS (!speed ? 7 : 8);
10487 break;
10488 case 31:
10489 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 5);
10490 break;
10491 default:
10492 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10493 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10494 speed);
10495 }
10496 break;
10497
10498 default:
10499 return false;
10500 }
10501 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10502 return true;
10503
10504 case LSHIFTRT:
10505 switch (mode)
10506 {
10507 case QImode:
10508 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10509 {
10510 *total = COSTS_N_INSNS (!speed ? 4 : 17);
10511 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10512 speed);
10513 }
10514 else
10515 {
10516 val = INTVAL (XEXP (x, 1));
10517 if (val == 7)
10518 *total = COSTS_N_INSNS (3);
10519 else if (val >= 0 && val <= 7)
10520 *total = COSTS_N_INSNS (val);
10521 else
10522 *total = COSTS_N_INSNS (1);
10523 }
10524 break;
10525
10526 case HImode:
10527 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10528 {
10529 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10530 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10531 speed);
10532 }
10533 else
10534 switch (INTVAL (XEXP (x, 1)))
10535 {
10536 case 0:
10537 *total = 0;
10538 break;
10539 case 1:
10540 case 8:
10541 *total = COSTS_N_INSNS (2);
10542 break;
10543 case 9:
10544 *total = COSTS_N_INSNS (3);
10545 break;
10546 case 2:
10547 case 10:
10548 case 15:
10549 *total = COSTS_N_INSNS (4);
10550 break;
10551 case 7:
10552 case 11:
10553 *total = COSTS_N_INSNS (5);
10554 break;
10555 case 3:
10556 case 12:
10557 case 13:
10558 case 14:
10559 *total = COSTS_N_INSNS (!speed ? 5 : 6);
10560 break;
10561 case 4:
10562 *total = COSTS_N_INSNS (!speed ? 5 : 7);
10563 break;
10564 case 5:
10565 case 6:
10566 *total = COSTS_N_INSNS (!speed ? 5 : 9);
10567 break;
10568 default:
10569 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10570 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10571 speed);
10572 }
10573 break;
10574
10575 case PSImode:
10576 if (!CONST_INT_P (XEXP (x, 1)))
10577 {
10578 *total = COSTS_N_INSNS (!speed ? 6 : 73);
10579 }
10580 else
10581 switch (INTVAL (XEXP (x, 1)))
10582 {
10583 case 0:
10584 *total = 0;
10585 break;
10586 case 1:
10587 case 8:
10588 case 16:
10589 *total = COSTS_N_INSNS (3);
10590 break;
10591 case 23:
10592 *total = COSTS_N_INSNS (5);
10593 break;
10594 default:
10595 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
10596 break;
10597 }
10598 break;
10599
10600 case SImode:
10601 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10602 {
10603 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10604 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10605 speed);
10606 }
10607 else
10608 switch (INTVAL (XEXP (x, 1)))
10609 {
10610 case 0:
10611 *total = 0;
10612 break;
10613 case 1:
10614 *total = COSTS_N_INSNS (4);
10615 break;
10616 case 2:
10617 *total = COSTS_N_INSNS (!speed ? 7 : 8);
10618 break;
10619 case 8:
10620 case 16:
10621 case 24:
10622 *total = COSTS_N_INSNS (4);
10623 break;
10624 case 31:
10625 *total = COSTS_N_INSNS (6);
10626 break;
10627 default:
10628 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10629 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10630 speed);
10631 }
10632 break;
10633
10634 default:
10635 return false;
10636 }
10637 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10638 return true;
10639
10640 case COMPARE:
10641 switch (GET_MODE (XEXP (x, 0)))
10642 {
10643 case QImode:
10644 *total = COSTS_N_INSNS (1);
10645 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10646 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
10647 break;
10648
10649 case HImode:
10650 *total = COSTS_N_INSNS (2);
10651 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10652 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
10653 else if (INTVAL (XEXP (x, 1)) != 0)
10654 *total += COSTS_N_INSNS (1);
10655 break;
10656
10657 case PSImode:
10658 *total = COSTS_N_INSNS (3);
10659 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) != 0)
10660 *total += COSTS_N_INSNS (2);
10661 break;
10662
10663 case SImode:
10664 *total = COSTS_N_INSNS (4);
10665 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10666 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
10667 else if (INTVAL (XEXP (x, 1)) != 0)
10668 *total += COSTS_N_INSNS (3);
10669 break;
10670
10671 default:
10672 return false;
10673 }
10674 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10675 return true;
10676
10677 case TRUNCATE:
10678 if (AVR_HAVE_MUL
10679 && LSHIFTRT == GET_CODE (XEXP (x, 0))
10680 && MULT == GET_CODE (XEXP (XEXP (x, 0), 0))
10681 && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
10682 {
10683 if (QImode == mode || HImode == mode)
10684 {
10685 *total = COSTS_N_INSNS (2);
10686 return true;
10687 }
10688 }
10689 break;
10690
10691 default:
10692 break;
10693 }
10694 return false;
10695 }
10696
10697
10698 /* Implement `TARGET_RTX_COSTS'. */
10699
10700 static bool
10701 avr_rtx_costs (rtx x, int codearg, int outer_code,
10702 int opno, int *total, bool speed)
10703 {
10704 bool done = avr_rtx_costs_1 (x, codearg, outer_code,
10705 opno, total, speed);
10706
10707 if (avr_log.rtx_costs)
10708 {
10709 avr_edump ("\n%?=%b (%s) total=%d, outer=%C:\n%r\n",
10710 done, speed ? "speed" : "size", *total, outer_code, x);
10711 }
10712
10713 return done;
10714 }
10715
10716
10717 /* Implement `TARGET_ADDRESS_COST'. */
10718
10719 static int
10720 avr_address_cost (rtx x, machine_mode mode ATTRIBUTE_UNUSED,
10721 addr_space_t as ATTRIBUTE_UNUSED,
10722 bool speed ATTRIBUTE_UNUSED)
10723 {
10724 int cost = 4;
10725
10726 if (GET_CODE (x) == PLUS
10727 && CONST_INT_P (XEXP (x, 1))
10728 && (REG_P (XEXP (x, 0))
10729 || GET_CODE (XEXP (x, 0)) == SUBREG))
10730 {
10731 if (INTVAL (XEXP (x, 1)) >= 61)
10732 cost = 18;
10733 }
10734 else if (CONSTANT_ADDRESS_P (x))
10735 {
10736 if (optimize > 0
10737 && io_address_operand (x, QImode))
10738 cost = 2;
10739 }
10740
10741 if (avr_log.address_cost)
10742 avr_edump ("\n%?: %d = %r\n", cost, x);
10743
10744 return cost;
10745 }
10746
10747 /* Test for extra memory constraint 'Q'.
10748 It's a memory address based on Y or Z pointer with valid displacement. */
10749
10750 int
10751 extra_constraint_Q (rtx x)
10752 {
10753 int ok = 0;
10754
10755 if (GET_CODE (XEXP (x,0)) == PLUS
10756 && REG_P (XEXP (XEXP (x,0), 0))
10757 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
10758 && (INTVAL (XEXP (XEXP (x,0), 1))
10759 <= MAX_LD_OFFSET (GET_MODE (x))))
10760 {
10761 rtx xx = XEXP (XEXP (x,0), 0);
10762 int regno = REGNO (xx);
10763
10764 ok = (/* allocate pseudos */
10765 regno >= FIRST_PSEUDO_REGISTER
10766 /* strictly check */
10767 || regno == REG_Z || regno == REG_Y
10768 /* XXX frame & arg pointer checks */
10769 || xx == frame_pointer_rtx
10770 || xx == arg_pointer_rtx);
10771
10772 if (avr_log.constraints)
10773 avr_edump ("\n%?=%d reload_completed=%d reload_in_progress=%d\n %r\n",
10774 ok, reload_completed, reload_in_progress, x);
10775 }
10776
10777 return ok;
10778 }
10779
10780 /* Convert condition code CONDITION to the valid AVR condition code. */
10781
10782 RTX_CODE
10783 avr_normalize_condition (RTX_CODE condition)
10784 {
10785 switch (condition)
10786 {
10787 case GT:
10788 return GE;
10789 case GTU:
10790 return GEU;
10791 case LE:
10792 return LT;
10793 case LEU:
10794 return LTU;
10795 default:
10796 gcc_unreachable ();
10797 }
10798 }
10799
10800 /* Helper function for `avr_reorg'. */
10801
10802 static rtx
10803 avr_compare_pattern (rtx_insn *insn)
10804 {
10805 rtx pattern = single_set (insn);
10806
10807 if (pattern
10808 && NONJUMP_INSN_P (insn)
10809 && SET_DEST (pattern) == cc0_rtx
10810 && GET_CODE (SET_SRC (pattern)) == COMPARE)
10811 {
10812 machine_mode mode0 = GET_MODE (XEXP (SET_SRC (pattern), 0));
10813 machine_mode mode1 = GET_MODE (XEXP (SET_SRC (pattern), 1));
10814
10815 /* The 64-bit comparisons have fixed operands ACC_A and ACC_B.
10816 They must not be swapped, thus skip them. */
10817
10818 if ((mode0 == VOIDmode || GET_MODE_SIZE (mode0) <= 4)
10819 && (mode1 == VOIDmode || GET_MODE_SIZE (mode1) <= 4))
10820 return pattern;
10821 }
10822
10823 return NULL_RTX;
10824 }
10825
10826 /* Helper function for `avr_reorg'. */
10827
10828 /* Expansion of switch/case decision trees leads to code like
10829
10830 cc0 = compare (Reg, Num)
10831 if (cc0 == 0)
10832 goto L1
10833
10834 cc0 = compare (Reg, Num)
10835 if (cc0 > 0)
10836 goto L2
10837
10838 The second comparison is superfluous and can be deleted.
10839 The second jump condition can be transformed from a
10840 "difficult" one to a "simple" one because "cc0 > 0" and
10841 "cc0 >= 0" will have the same effect here.
10842
10843 This function relies on the way switch/case is being expaned
10844 as binary decision tree. For example code see PR 49903.
10845
10846 Return TRUE if optimization performed.
10847 Return FALSE if nothing changed.
10848
10849 INSN1 is a comparison, i.e. avr_compare_pattern != 0.
10850
10851 We don't want to do this in text peephole because it is
10852 tedious to work out jump offsets there and the second comparison
10853 might have been transormed by `avr_reorg'.
10854
10855 RTL peephole won't do because peephole2 does not scan across
10856 basic blocks. */
10857
10858 static bool
10859 avr_reorg_remove_redundant_compare (rtx_insn *insn1)
10860 {
10861 rtx comp1, ifelse1, xcond1;
10862 rtx_insn *branch1;
10863 rtx comp2, ifelse2, xcond2;
10864 rtx_insn *branch2, *insn2;
10865 enum rtx_code code;
10866 rtx_insn *jump;
10867 rtx target, cond;
10868
10869 /* Look out for: compare1 - branch1 - compare2 - branch2 */
10870
10871 branch1 = next_nonnote_nondebug_insn (insn1);
10872 if (!branch1 || !JUMP_P (branch1))
10873 return false;
10874
10875 insn2 = next_nonnote_nondebug_insn (branch1);
10876 if (!insn2 || !avr_compare_pattern (insn2))
10877 return false;
10878
10879 branch2 = next_nonnote_nondebug_insn (insn2);
10880 if (!branch2 || !JUMP_P (branch2))
10881 return false;
10882
10883 comp1 = avr_compare_pattern (insn1);
10884 comp2 = avr_compare_pattern (insn2);
10885 xcond1 = single_set (branch1);
10886 xcond2 = single_set (branch2);
10887
10888 if (!comp1 || !comp2
10889 || !rtx_equal_p (comp1, comp2)
10890 || !xcond1 || SET_DEST (xcond1) != pc_rtx
10891 || !xcond2 || SET_DEST (xcond2) != pc_rtx
10892 || IF_THEN_ELSE != GET_CODE (SET_SRC (xcond1))
10893 || IF_THEN_ELSE != GET_CODE (SET_SRC (xcond2)))
10894 {
10895 return false;
10896 }
10897
10898 comp1 = SET_SRC (comp1);
10899 ifelse1 = SET_SRC (xcond1);
10900 ifelse2 = SET_SRC (xcond2);
10901
10902 /* comp<n> is COMPARE now and ifelse<n> is IF_THEN_ELSE. */
10903
10904 if (EQ != GET_CODE (XEXP (ifelse1, 0))
10905 || !REG_P (XEXP (comp1, 0))
10906 || !CONST_INT_P (XEXP (comp1, 1))
10907 || XEXP (ifelse1, 2) != pc_rtx
10908 || XEXP (ifelse2, 2) != pc_rtx
10909 || LABEL_REF != GET_CODE (XEXP (ifelse1, 1))
10910 || LABEL_REF != GET_CODE (XEXP (ifelse2, 1))
10911 || !COMPARISON_P (XEXP (ifelse2, 0))
10912 || cc0_rtx != XEXP (XEXP (ifelse1, 0), 0)
10913 || cc0_rtx != XEXP (XEXP (ifelse2, 0), 0)
10914 || const0_rtx != XEXP (XEXP (ifelse1, 0), 1)
10915 || const0_rtx != XEXP (XEXP (ifelse2, 0), 1))
10916 {
10917 return false;
10918 }
10919
10920 /* We filtered the insn sequence to look like
10921
10922 (set (cc0)
10923 (compare (reg:M N)
10924 (const_int VAL)))
10925 (set (pc)
10926 (if_then_else (eq (cc0)
10927 (const_int 0))
10928 (label_ref L1)
10929 (pc)))
10930
10931 (set (cc0)
10932 (compare (reg:M N)
10933 (const_int VAL)))
10934 (set (pc)
10935 (if_then_else (CODE (cc0)
10936 (const_int 0))
10937 (label_ref L2)
10938 (pc)))
10939 */
10940
10941 code = GET_CODE (XEXP (ifelse2, 0));
10942
10943 /* Map GT/GTU to GE/GEU which is easier for AVR.
10944 The first two instructions compare/branch on EQ
10945 so we may replace the difficult
10946
10947 if (x == VAL) goto L1;
10948 if (x > VAL) goto L2;
10949
10950 with easy
10951
10952 if (x == VAL) goto L1;
10953 if (x >= VAL) goto L2;
10954
10955 Similarly, replace LE/LEU by LT/LTU. */
10956
10957 switch (code)
10958 {
10959 case EQ:
10960 case LT: case LTU:
10961 case GE: case GEU:
10962 break;
10963
10964 case LE: case LEU:
10965 case GT: case GTU:
10966 code = avr_normalize_condition (code);
10967 break;
10968
10969 default:
10970 return false;
10971 }
10972
10973 /* Wrap the branches into UNSPECs so they won't be changed or
10974 optimized in the remainder. */
10975
10976 target = XEXP (XEXP (ifelse1, 1), 0);
10977 cond = XEXP (ifelse1, 0);
10978 jump = emit_jump_insn_after (gen_branch_unspec (target, cond), insn1);
10979
10980 JUMP_LABEL (jump) = JUMP_LABEL (branch1);
10981
10982 target = XEXP (XEXP (ifelse2, 1), 0);
10983 cond = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
10984 jump = emit_jump_insn_after (gen_branch_unspec (target, cond), insn2);
10985
10986 JUMP_LABEL (jump) = JUMP_LABEL (branch2);
10987
10988 /* The comparisons in insn1 and insn2 are exactly the same;
10989 insn2 is superfluous so delete it. */
10990
10991 delete_insn (insn2);
10992 delete_insn (branch1);
10993 delete_insn (branch2);
10994
10995 return true;
10996 }
10997
10998
10999 /* Implement `TARGET_MACHINE_DEPENDENT_REORG'. */
11000 /* Optimize conditional jumps. */
11001
11002 static void
11003 avr_reorg (void)
11004 {
11005 rtx_insn *insn = get_insns();
11006
11007 for (insn = next_real_insn (insn); insn; insn = next_real_insn (insn))
11008 {
11009 rtx pattern = avr_compare_pattern (insn);
11010
11011 if (!pattern)
11012 continue;
11013
11014 if (optimize
11015 && avr_reorg_remove_redundant_compare (insn))
11016 {
11017 continue;
11018 }
11019
11020 if (compare_diff_p (insn))
11021 {
11022 /* Now we work under compare insn with difficult branch. */
11023
11024 rtx next = next_real_insn (insn);
11025 rtx pat = PATTERN (next);
11026
11027 pattern = SET_SRC (pattern);
11028
11029 if (true_regnum (XEXP (pattern, 0)) >= 0
11030 && true_regnum (XEXP (pattern, 1)) >= 0)
11031 {
11032 rtx x = XEXP (pattern, 0);
11033 rtx src = SET_SRC (pat);
11034 rtx t = XEXP (src,0);
11035 PUT_CODE (t, swap_condition (GET_CODE (t)));
11036 XEXP (pattern, 0) = XEXP (pattern, 1);
11037 XEXP (pattern, 1) = x;
11038 INSN_CODE (next) = -1;
11039 }
11040 else if (true_regnum (XEXP (pattern, 0)) >= 0
11041 && XEXP (pattern, 1) == const0_rtx)
11042 {
11043 /* This is a tst insn, we can reverse it. */
11044 rtx src = SET_SRC (pat);
11045 rtx t = XEXP (src,0);
11046
11047 PUT_CODE (t, swap_condition (GET_CODE (t)));
11048 XEXP (pattern, 1) = XEXP (pattern, 0);
11049 XEXP (pattern, 0) = const0_rtx;
11050 INSN_CODE (next) = -1;
11051 INSN_CODE (insn) = -1;
11052 }
11053 else if (true_regnum (XEXP (pattern, 0)) >= 0
11054 && CONST_INT_P (XEXP (pattern, 1)))
11055 {
11056 rtx x = XEXP (pattern, 1);
11057 rtx src = SET_SRC (pat);
11058 rtx t = XEXP (src,0);
11059 machine_mode mode = GET_MODE (XEXP (pattern, 0));
11060
11061 if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
11062 {
11063 XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
11064 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
11065 INSN_CODE (next) = -1;
11066 INSN_CODE (insn) = -1;
11067 }
11068 }
11069 }
11070 }
11071 }
11072
11073 /* Returns register number for function return value.*/
11074
11075 static inline unsigned int
11076 avr_ret_register (void)
11077 {
11078 return 24;
11079 }
11080
11081
11082 /* Implement `TARGET_FUNCTION_VALUE_REGNO_P'. */
11083
11084 static bool
11085 avr_function_value_regno_p (const unsigned int regno)
11086 {
11087 return (regno == avr_ret_register ());
11088 }
11089
11090
11091 /* Implement `TARGET_LIBCALL_VALUE'. */
11092 /* Create an RTX representing the place where a
11093 library function returns a value of mode MODE. */
11094
11095 static rtx
11096 avr_libcall_value (machine_mode mode,
11097 const_rtx func ATTRIBUTE_UNUSED)
11098 {
11099 int offs = GET_MODE_SIZE (mode);
11100
11101 if (offs <= 4)
11102 offs = (offs + 1) & ~1;
11103
11104 return gen_rtx_REG (mode, avr_ret_register () + 2 - offs);
11105 }
11106
11107
11108 /* Implement `TARGET_FUNCTION_VALUE'. */
11109 /* Create an RTX representing the place where a
11110 function returns a value of data type VALTYPE. */
11111
11112 static rtx
11113 avr_function_value (const_tree type,
11114 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
11115 bool outgoing ATTRIBUTE_UNUSED)
11116 {
11117 unsigned int offs;
11118
11119 if (TYPE_MODE (type) != BLKmode)
11120 return avr_libcall_value (TYPE_MODE (type), NULL_RTX);
11121
11122 offs = int_size_in_bytes (type);
11123 if (offs < 2)
11124 offs = 2;
11125 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
11126 offs = GET_MODE_SIZE (SImode);
11127 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
11128 offs = GET_MODE_SIZE (DImode);
11129
11130 return gen_rtx_REG (BLKmode, avr_ret_register () + 2 - offs);
11131 }
11132
11133 int
11134 test_hard_reg_class (enum reg_class rclass, rtx x)
11135 {
11136 int regno = true_regnum (x);
11137 if (regno < 0)
11138 return 0;
11139
11140 if (TEST_HARD_REG_CLASS (rclass, regno))
11141 return 1;
11142
11143 return 0;
11144 }
11145
11146
11147 /* Helper for jump_over_one_insn_p: Test if INSN is a 2-word instruction
11148 and thus is suitable to be skipped by CPSE, SBRC, etc. */
11149
11150 static bool
11151 avr_2word_insn_p (rtx_insn *insn)
11152 {
11153 if (TARGET_SKIP_BUG
11154 || !insn
11155 || 2 != get_attr_length (insn))
11156 {
11157 return false;
11158 }
11159
11160 switch (INSN_CODE (insn))
11161 {
11162 default:
11163 return false;
11164
11165 case CODE_FOR_movqi_insn:
11166 case CODE_FOR_movuqq_insn:
11167 case CODE_FOR_movqq_insn:
11168 {
11169 rtx set = single_set (insn);
11170 rtx src = SET_SRC (set);
11171 rtx dest = SET_DEST (set);
11172
11173 /* Factor out LDS and STS from movqi_insn. */
11174
11175 if (MEM_P (dest)
11176 && (REG_P (src) || src == CONST0_RTX (GET_MODE (dest))))
11177 {
11178 return CONSTANT_ADDRESS_P (XEXP (dest, 0));
11179 }
11180 else if (REG_P (dest)
11181 && MEM_P (src))
11182 {
11183 return CONSTANT_ADDRESS_P (XEXP (src, 0));
11184 }
11185
11186 return false;
11187 }
11188
11189 case CODE_FOR_call_insn:
11190 case CODE_FOR_call_value_insn:
11191 return true;
11192 }
11193 }
11194
11195
11196 int
11197 jump_over_one_insn_p (rtx_insn *insn, rtx dest)
11198 {
11199 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
11200 ? XEXP (dest, 0)
11201 : dest);
11202 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
11203 int dest_addr = INSN_ADDRESSES (uid);
11204 int jump_offset = dest_addr - jump_addr - get_attr_length (insn);
11205
11206 return (jump_offset == 1
11207 || (jump_offset == 2
11208 && avr_2word_insn_p (next_active_insn (insn))));
11209 }
11210
11211
11212 /* Worker function for `HARD_REGNO_MODE_OK'. */
11213 /* Returns 1 if a value of mode MODE can be stored starting with hard
11214 register number REGNO. On the enhanced core, anything larger than
11215 1 byte must start in even numbered register for "movw" to work
11216 (this way we don't have to check for odd registers everywhere). */
11217
11218 int
11219 avr_hard_regno_mode_ok (int regno, machine_mode mode)
11220 {
11221 /* NOTE: 8-bit values must not be disallowed for R28 or R29.
11222 Disallowing QI et al. in these regs might lead to code like
11223 (set (subreg:QI (reg:HI 28) n) ...)
11224 which will result in wrong code because reload does not
11225 handle SUBREGs of hard regsisters like this.
11226 This could be fixed in reload. However, it appears
11227 that fixing reload is not wanted by reload people. */
11228
11229 /* Any GENERAL_REGS register can hold 8-bit values. */
11230
11231 if (GET_MODE_SIZE (mode) == 1)
11232 return 1;
11233
11234 /* FIXME: Ideally, the following test is not needed.
11235 However, it turned out that it can reduce the number
11236 of spill fails. AVR and it's poor endowment with
11237 address registers is extreme stress test for reload. */
11238
11239 if (GET_MODE_SIZE (mode) >= 4
11240 && regno >= REG_X)
11241 return 0;
11242
11243 /* All modes larger than 8 bits should start in an even register. */
11244
11245 return !(regno & 1);
11246 }
11247
11248
11249 /* Implement `HARD_REGNO_CALL_PART_CLOBBERED'. */
11250
11251 int
11252 avr_hard_regno_call_part_clobbered (unsigned regno, machine_mode mode)
11253 {
11254 /* FIXME: This hook gets called with MODE:REGNO combinations that don't
11255 represent valid hard registers like, e.g. HI:29. Returning TRUE
11256 for such registers can lead to performance degradation as mentioned
11257 in PR53595. Thus, report invalid hard registers as FALSE. */
11258
11259 if (!avr_hard_regno_mode_ok (regno, mode))
11260 return 0;
11261
11262 /* Return true if any of the following boundaries is crossed:
11263 17/18, 27/28 and 29/30. */
11264
11265 return ((regno < 18 && regno + GET_MODE_SIZE (mode) > 18)
11266 || (regno < REG_Y && regno + GET_MODE_SIZE (mode) > REG_Y)
11267 || (regno < REG_Z && regno + GET_MODE_SIZE (mode) > REG_Z));
11268 }
11269
11270
11271 /* Implement `MODE_CODE_BASE_REG_CLASS'. */
11272
11273 enum reg_class
11274 avr_mode_code_base_reg_class (machine_mode mode ATTRIBUTE_UNUSED,
11275 addr_space_t as, RTX_CODE outer_code,
11276 RTX_CODE index_code ATTRIBUTE_UNUSED)
11277 {
11278 if (!ADDR_SPACE_GENERIC_P (as))
11279 {
11280 return POINTER_Z_REGS;
11281 }
11282
11283 if (!avr_strict_X)
11284 return reload_completed ? BASE_POINTER_REGS : POINTER_REGS;
11285
11286 return PLUS == outer_code ? BASE_POINTER_REGS : POINTER_REGS;
11287 }
11288
11289
11290 /* Implement `REGNO_MODE_CODE_OK_FOR_BASE_P'. */
11291
11292 bool
11293 avr_regno_mode_code_ok_for_base_p (int regno,
11294 machine_mode mode ATTRIBUTE_UNUSED,
11295 addr_space_t as ATTRIBUTE_UNUSED,
11296 RTX_CODE outer_code,
11297 RTX_CODE index_code ATTRIBUTE_UNUSED)
11298 {
11299 bool ok = false;
11300
11301 if (!ADDR_SPACE_GENERIC_P (as))
11302 {
11303 if (regno < FIRST_PSEUDO_REGISTER
11304 && regno == REG_Z)
11305 {
11306 return true;
11307 }
11308
11309 if (reg_renumber)
11310 {
11311 regno = reg_renumber[regno];
11312
11313 if (regno == REG_Z)
11314 {
11315 return true;
11316 }
11317 }
11318
11319 return false;
11320 }
11321
11322 if (regno < FIRST_PSEUDO_REGISTER
11323 && (regno == REG_X
11324 || regno == REG_Y
11325 || regno == REG_Z
11326 || regno == ARG_POINTER_REGNUM))
11327 {
11328 ok = true;
11329 }
11330 else if (reg_renumber)
11331 {
11332 regno = reg_renumber[regno];
11333
11334 if (regno == REG_X
11335 || regno == REG_Y
11336 || regno == REG_Z
11337 || regno == ARG_POINTER_REGNUM)
11338 {
11339 ok = true;
11340 }
11341 }
11342
11343 if (avr_strict_X
11344 && PLUS == outer_code
11345 && regno == REG_X)
11346 {
11347 ok = false;
11348 }
11349
11350 return ok;
11351 }
11352
11353
11354 /* A helper for `output_reload_insisf' and `output_reload_inhi'. */
11355 /* Set 32-bit register OP[0] to compile-time constant OP[1].
11356 CLOBBER_REG is a QI clobber register or NULL_RTX.
11357 LEN == NULL: output instructions.
11358 LEN != NULL: set *LEN to the length of the instruction sequence
11359 (in words) printed with LEN = NULL.
11360 If CLEAR_P is true, OP[0] had been cleard to Zero already.
11361 If CLEAR_P is false, nothing is known about OP[0].
11362
11363 The effect on cc0 is as follows:
11364
11365 Load 0 to any register except ZERO_REG : NONE
11366 Load ld register with any value : NONE
11367 Anything else: : CLOBBER */
11368
11369 static void
11370 output_reload_in_const (rtx *op, rtx clobber_reg, int *len, bool clear_p)
11371 {
11372 rtx src = op[1];
11373 rtx dest = op[0];
11374 rtx xval, xdest[4];
11375 int ival[4];
11376 int clobber_val = 1234;
11377 bool cooked_clobber_p = false;
11378 bool set_p = false;
11379 machine_mode mode = GET_MODE (dest);
11380 int n, n_bytes = GET_MODE_SIZE (mode);
11381
11382 gcc_assert (REG_P (dest)
11383 && CONSTANT_P (src));
11384
11385 if (len)
11386 *len = 0;
11387
11388 /* (REG:SI 14) is special: It's neither in LD_REGS nor in NO_LD_REGS
11389 but has some subregs that are in LD_REGS. Use the MSB (REG:QI 17). */
11390
11391 if (REGNO (dest) < 16
11392 && REGNO (dest) + GET_MODE_SIZE (mode) > 16)
11393 {
11394 clobber_reg = all_regs_rtx[REGNO (dest) + n_bytes - 1];
11395 }
11396
11397 /* We might need a clobber reg but don't have one. Look at the value to
11398 be loaded more closely. A clobber is only needed if it is a symbol
11399 or contains a byte that is neither 0, -1 or a power of 2. */
11400
11401 if (NULL_RTX == clobber_reg
11402 && !test_hard_reg_class (LD_REGS, dest)
11403 && (! (CONST_INT_P (src) || CONST_FIXED_P (src) || CONST_DOUBLE_P (src))
11404 || !avr_popcount_each_byte (src, n_bytes,
11405 (1 << 0) | (1 << 1) | (1 << 8))))
11406 {
11407 /* We have no clobber register but need one. Cook one up.
11408 That's cheaper than loading from constant pool. */
11409
11410 cooked_clobber_p = true;
11411 clobber_reg = all_regs_rtx[REG_Z + 1];
11412 avr_asm_len ("mov __tmp_reg__,%0", &clobber_reg, len, 1);
11413 }
11414
11415 /* Now start filling DEST from LSB to MSB. */
11416
11417 for (n = 0; n < n_bytes; n++)
11418 {
11419 int ldreg_p;
11420 bool done_byte = false;
11421 int j;
11422 rtx xop[3];
11423
11424 /* Crop the n-th destination byte. */
11425
11426 xdest[n] = simplify_gen_subreg (QImode, dest, mode, n);
11427 ldreg_p = test_hard_reg_class (LD_REGS, xdest[n]);
11428
11429 if (!CONST_INT_P (src)
11430 && !CONST_FIXED_P (src)
11431 && !CONST_DOUBLE_P (src))
11432 {
11433 static const char* const asm_code[][2] =
11434 {
11435 { "ldi %2,lo8(%1)" CR_TAB "mov %0,%2", "ldi %0,lo8(%1)" },
11436 { "ldi %2,hi8(%1)" CR_TAB "mov %0,%2", "ldi %0,hi8(%1)" },
11437 { "ldi %2,hlo8(%1)" CR_TAB "mov %0,%2", "ldi %0,hlo8(%1)" },
11438 { "ldi %2,hhi8(%1)" CR_TAB "mov %0,%2", "ldi %0,hhi8(%1)" }
11439 };
11440
11441 xop[0] = xdest[n];
11442 xop[1] = src;
11443 xop[2] = clobber_reg;
11444
11445 avr_asm_len (asm_code[n][ldreg_p], xop, len, ldreg_p ? 1 : 2);
11446
11447 continue;
11448 }
11449
11450 /* Crop the n-th source byte. */
11451
11452 xval = simplify_gen_subreg (QImode, src, mode, n);
11453 ival[n] = INTVAL (xval);
11454
11455 /* Look if we can reuse the low word by means of MOVW. */
11456
11457 if (n == 2
11458 && n_bytes >= 4
11459 && AVR_HAVE_MOVW)
11460 {
11461 rtx lo16 = simplify_gen_subreg (HImode, src, mode, 0);
11462 rtx hi16 = simplify_gen_subreg (HImode, src, mode, 2);
11463
11464 if (INTVAL (lo16) == INTVAL (hi16))
11465 {
11466 if (0 != INTVAL (lo16)
11467 || !clear_p)
11468 {
11469 avr_asm_len ("movw %C0,%A0", &op[0], len, 1);
11470 }
11471
11472 break;
11473 }
11474 }
11475
11476 /* Don't use CLR so that cc0 is set as expected. */
11477
11478 if (ival[n] == 0)
11479 {
11480 if (!clear_p)
11481 avr_asm_len (ldreg_p ? "ldi %0,0"
11482 : AVR_ZERO_REGNO == REGNO (xdest[n]) ? "clr %0"
11483 : "mov %0,__zero_reg__",
11484 &xdest[n], len, 1);
11485 continue;
11486 }
11487
11488 if (clobber_val == ival[n]
11489 && REGNO (clobber_reg) == REGNO (xdest[n]))
11490 {
11491 continue;
11492 }
11493
11494 /* LD_REGS can use LDI to move a constant value */
11495
11496 if (ldreg_p)
11497 {
11498 xop[0] = xdest[n];
11499 xop[1] = xval;
11500 avr_asm_len ("ldi %0,lo8(%1)", xop, len, 1);
11501 continue;
11502 }
11503
11504 /* Try to reuse value already loaded in some lower byte. */
11505
11506 for (j = 0; j < n; j++)
11507 if (ival[j] == ival[n])
11508 {
11509 xop[0] = xdest[n];
11510 xop[1] = xdest[j];
11511
11512 avr_asm_len ("mov %0,%1", xop, len, 1);
11513 done_byte = true;
11514 break;
11515 }
11516
11517 if (done_byte)
11518 continue;
11519
11520 /* Need no clobber reg for -1: Use CLR/DEC */
11521
11522 if (-1 == ival[n])
11523 {
11524 if (!clear_p)
11525 avr_asm_len ("clr %0", &xdest[n], len, 1);
11526
11527 avr_asm_len ("dec %0", &xdest[n], len, 1);
11528 continue;
11529 }
11530 else if (1 == ival[n])
11531 {
11532 if (!clear_p)
11533 avr_asm_len ("clr %0", &xdest[n], len, 1);
11534
11535 avr_asm_len ("inc %0", &xdest[n], len, 1);
11536 continue;
11537 }
11538
11539 /* Use T flag or INC to manage powers of 2 if we have
11540 no clobber reg. */
11541
11542 if (NULL_RTX == clobber_reg
11543 && single_one_operand (xval, QImode))
11544 {
11545 xop[0] = xdest[n];
11546 xop[1] = GEN_INT (exact_log2 (ival[n] & GET_MODE_MASK (QImode)));
11547
11548 gcc_assert (constm1_rtx != xop[1]);
11549
11550 if (!set_p)
11551 {
11552 set_p = true;
11553 avr_asm_len ("set", xop, len, 1);
11554 }
11555
11556 if (!clear_p)
11557 avr_asm_len ("clr %0", xop, len, 1);
11558
11559 avr_asm_len ("bld %0,%1", xop, len, 1);
11560 continue;
11561 }
11562
11563 /* We actually need the LD_REGS clobber reg. */
11564
11565 gcc_assert (NULL_RTX != clobber_reg);
11566
11567 xop[0] = xdest[n];
11568 xop[1] = xval;
11569 xop[2] = clobber_reg;
11570 clobber_val = ival[n];
11571
11572 avr_asm_len ("ldi %2,lo8(%1)" CR_TAB
11573 "mov %0,%2", xop, len, 2);
11574 }
11575
11576 /* If we cooked up a clobber reg above, restore it. */
11577
11578 if (cooked_clobber_p)
11579 {
11580 avr_asm_len ("mov %0,__tmp_reg__", &clobber_reg, len, 1);
11581 }
11582 }
11583
11584
11585 /* Reload the constant OP[1] into the HI register OP[0].
11586 CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
11587 into a NO_LD_REGS register. If CLOBBER_REG is NULL_RTX we either don't
11588 need a clobber reg or have to cook one up.
11589
11590 PLEN == NULL: Output instructions.
11591 PLEN != NULL: Output nothing. Set *PLEN to number of words occupied
11592 by the insns printed.
11593
11594 Return "". */
11595
11596 const char*
11597 output_reload_inhi (rtx *op, rtx clobber_reg, int *plen)
11598 {
11599 output_reload_in_const (op, clobber_reg, plen, false);
11600 return "";
11601 }
11602
11603
11604 /* Reload a SI or SF compile time constant OP[1] into the register OP[0].
11605 CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
11606 into a NO_LD_REGS register. If CLOBBER_REG is NULL_RTX we either don't
11607 need a clobber reg or have to cook one up.
11608
11609 LEN == NULL: Output instructions.
11610
11611 LEN != NULL: Output nothing. Set *LEN to number of words occupied
11612 by the insns printed.
11613
11614 Return "". */
11615
11616 const char *
11617 output_reload_insisf (rtx *op, rtx clobber_reg, int *len)
11618 {
11619 if (AVR_HAVE_MOVW
11620 && !test_hard_reg_class (LD_REGS, op[0])
11621 && (CONST_INT_P (op[1])
11622 || CONST_FIXED_P (op[1])
11623 || CONST_DOUBLE_P (op[1])))
11624 {
11625 int len_clr, len_noclr;
11626
11627 /* In some cases it is better to clear the destination beforehand, e.g.
11628
11629 CLR R2 CLR R3 MOVW R4,R2 INC R2
11630
11631 is shorther than
11632
11633 CLR R2 INC R2 CLR R3 CLR R4 CLR R5
11634
11635 We find it too tedious to work that out in the print function.
11636 Instead, we call the print function twice to get the lengths of
11637 both methods and use the shortest one. */
11638
11639 output_reload_in_const (op, clobber_reg, &len_clr, true);
11640 output_reload_in_const (op, clobber_reg, &len_noclr, false);
11641
11642 if (len_noclr - len_clr == 4)
11643 {
11644 /* Default needs 4 CLR instructions: clear register beforehand. */
11645
11646 avr_asm_len ("mov %A0,__zero_reg__" CR_TAB
11647 "mov %B0,__zero_reg__" CR_TAB
11648 "movw %C0,%A0", &op[0], len, 3);
11649
11650 output_reload_in_const (op, clobber_reg, len, true);
11651
11652 if (len)
11653 *len += 3;
11654
11655 return "";
11656 }
11657 }
11658
11659 /* Default: destination not pre-cleared. */
11660
11661 output_reload_in_const (op, clobber_reg, len, false);
11662 return "";
11663 }
11664
11665 const char*
11666 avr_out_reload_inpsi (rtx *op, rtx clobber_reg, int *len)
11667 {
11668 output_reload_in_const (op, clobber_reg, len, false);
11669 return "";
11670 }
11671
11672
11673 /* Worker function for `ASM_OUTPUT_ADDR_VEC_ELT'. */
11674
11675 void
11676 avr_output_addr_vec_elt (FILE *stream, int value)
11677 {
11678 if (AVR_HAVE_JMP_CALL)
11679 fprintf (stream, "\t.word gs(.L%d)\n", value);
11680 else
11681 fprintf (stream, "\trjmp .L%d\n", value);
11682 }
11683
11684 static void
11685 avr_conditional_register_usage(void)
11686 {
11687 if (AVR_TINY)
11688 {
11689 unsigned int i;
11690
11691 const int tiny_reg_alloc_order[] = {
11692 24, 25,
11693 22, 23,
11694 30, 31,
11695 26, 27,
11696 28, 29,
11697 21, 20, 19, 18,
11698 16, 17,
11699 32, 33, 34, 35,
11700 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
11701 };
11702
11703 /* Set R0-R17 as fixed registers. Reset R0-R17 in call used register list
11704 - R0-R15 are not available in Tiny Core devices
11705 - R16 and R17 are fixed registers. */
11706
11707 for (i = 0; i <= 17; i++)
11708 {
11709 fixed_regs[i] = 1;
11710 call_used_regs[i] = 1;
11711 }
11712
11713 /* Set R18 to R21 as callee saved registers
11714 - R18, R19, R20 and R21 are the callee saved registers in
11715 Tiny Core devices */
11716
11717 for (i = 18; i <= LAST_CALLEE_SAVED_REG; i++)
11718 {
11719 call_used_regs[i] = 0;
11720 }
11721
11722 /* Update register allocation order for Tiny Core devices */
11723
11724 for (i = 0; i < ARRAY_SIZE (tiny_reg_alloc_order); i++)
11725 {
11726 reg_alloc_order[i] = tiny_reg_alloc_order[i];
11727 }
11728
11729 CLEAR_HARD_REG_SET (reg_class_contents[(int) ADDW_REGS]);
11730 CLEAR_HARD_REG_SET (reg_class_contents[(int) NO_LD_REGS]);
11731 }
11732 }
11733
11734 /* Implement `TARGET_HARD_REGNO_SCRATCH_OK'. */
11735 /* Returns true if SCRATCH are safe to be allocated as a scratch
11736 registers (for a define_peephole2) in the current function. */
11737
11738 static bool
11739 avr_hard_regno_scratch_ok (unsigned int regno)
11740 {
11741 /* Interrupt functions can only use registers that have already been saved
11742 by the prologue, even if they would normally be call-clobbered. */
11743
11744 if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
11745 && !df_regs_ever_live_p (regno))
11746 return false;
11747
11748 /* Don't allow hard registers that might be part of the frame pointer.
11749 Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
11750 and don't care for a frame pointer that spans more than one register. */
11751
11752 if ((!reload_completed || frame_pointer_needed)
11753 && (regno == REG_Y || regno == REG_Y + 1))
11754 {
11755 return false;
11756 }
11757
11758 return true;
11759 }
11760
11761
11762 /* Worker function for `HARD_REGNO_RENAME_OK'. */
11763 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
11764
11765 int
11766 avr_hard_regno_rename_ok (unsigned int old_reg,
11767 unsigned int new_reg)
11768 {
11769 /* Interrupt functions can only use registers that have already been
11770 saved by the prologue, even if they would normally be
11771 call-clobbered. */
11772
11773 if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
11774 && !df_regs_ever_live_p (new_reg))
11775 return 0;
11776
11777 /* Don't allow hard registers that might be part of the frame pointer.
11778 Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
11779 and don't care for a frame pointer that spans more than one register. */
11780
11781 if ((!reload_completed || frame_pointer_needed)
11782 && (old_reg == REG_Y || old_reg == REG_Y + 1
11783 || new_reg == REG_Y || new_reg == REG_Y + 1))
11784 {
11785 return 0;
11786 }
11787
11788 return 1;
11789 }
11790
11791 /* Output a branch that tests a single bit of a register (QI, HI, SI or DImode)
11792 or memory location in the I/O space (QImode only).
11793
11794 Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
11795 Operand 1: register operand to test, or CONST_INT memory address.
11796 Operand 2: bit number.
11797 Operand 3: label to jump to if the test is true. */
11798
11799 const char*
11800 avr_out_sbxx_branch (rtx_insn *insn, rtx operands[])
11801 {
11802 enum rtx_code comp = GET_CODE (operands[0]);
11803 bool long_jump = get_attr_length (insn) >= 4;
11804 bool reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
11805
11806 if (comp == GE)
11807 comp = EQ;
11808 else if (comp == LT)
11809 comp = NE;
11810
11811 if (reverse)
11812 comp = reverse_condition (comp);
11813
11814 switch (GET_CODE (operands[1]))
11815 {
11816 default:
11817 gcc_unreachable();
11818
11819 case CONST_INT:
11820 case CONST:
11821 case SYMBOL_REF:
11822
11823 if (low_io_address_operand (operands[1], QImode))
11824 {
11825 if (comp == EQ)
11826 output_asm_insn ("sbis %i1,%2", operands);
11827 else
11828 output_asm_insn ("sbic %i1,%2", operands);
11829 }
11830 else
11831 {
11832 gcc_assert (io_address_operand (operands[1], QImode));
11833 output_asm_insn ("in __tmp_reg__,%i1", operands);
11834 if (comp == EQ)
11835 output_asm_insn ("sbrs __tmp_reg__,%2", operands);
11836 else
11837 output_asm_insn ("sbrc __tmp_reg__,%2", operands);
11838 }
11839
11840 break; /* CONST_INT */
11841
11842 case REG:
11843
11844 if (comp == EQ)
11845 output_asm_insn ("sbrs %T1%T2", operands);
11846 else
11847 output_asm_insn ("sbrc %T1%T2", operands);
11848
11849 break; /* REG */
11850 } /* switch */
11851
11852 if (long_jump)
11853 return ("rjmp .+4" CR_TAB
11854 "jmp %x3");
11855
11856 if (!reverse)
11857 return "rjmp %x3";
11858
11859 return "";
11860 }
11861
11862 /* Worker function for `TARGET_ASM_CONSTRUCTOR'. */
11863
11864 static void
11865 avr_asm_out_ctor (rtx symbol, int priority)
11866 {
11867 fputs ("\t.global __do_global_ctors\n", asm_out_file);
11868 default_ctor_section_asm_out_constructor (symbol, priority);
11869 }
11870
11871
11872 /* Worker function for `TARGET_ASM_DESTRUCTOR'. */
11873
11874 static void
11875 avr_asm_out_dtor (rtx symbol, int priority)
11876 {
11877 fputs ("\t.global __do_global_dtors\n", asm_out_file);
11878 default_dtor_section_asm_out_destructor (symbol, priority);
11879 }
11880
11881
11882 /* Worker function for `TARGET_RETURN_IN_MEMORY'. */
11883
11884 static bool
11885 avr_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
11886 {
11887 HOST_WIDE_INT size = int_size_in_bytes (type);
11888 HOST_WIDE_INT ret_size_limit = AVR_TINY ? 4 : 8;
11889
11890 /* In avr, there are 8 return registers. But, for Tiny Core
11891 (ATtiny4/5/9/10/20/40) devices, only 4 registers are available.
11892 Return true if size is unknown or greater than the limit. */
11893
11894 if (size == -1 || size > ret_size_limit)
11895 {
11896 return true;
11897 }
11898 else
11899 {
11900 return false;
11901 }
11902 }
11903
11904
11905 /* Implement `CASE_VALUES_THRESHOLD'. */
11906 /* Supply the default for --param case-values-threshold=0 */
11907
11908 static unsigned int
11909 avr_case_values_threshold (void)
11910 {
11911 /* The exact break-even point between a jump table and an if-else tree
11912 depends on several factors not available here like, e.g. if 8-bit
11913 comparisons can be used in the if-else tree or not, on the
11914 range of the case values, if the case value can be reused, on the
11915 register allocation, etc. '7' appears to be a good choice. */
11916
11917 return 7;
11918 }
11919
11920
11921 /* Implement `TARGET_ADDR_SPACE_ADDRESS_MODE'. */
11922
11923 static machine_mode
11924 avr_addr_space_address_mode (addr_space_t as)
11925 {
11926 return avr_addrspace[as].pointer_size == 3 ? PSImode : HImode;
11927 }
11928
11929
11930 /* Implement `TARGET_ADDR_SPACE_POINTER_MODE'. */
11931
11932 static machine_mode
11933 avr_addr_space_pointer_mode (addr_space_t as)
11934 {
11935 return avr_addr_space_address_mode (as);
11936 }
11937
11938
11939 /* Helper for following function. */
11940
11941 static bool
11942 avr_reg_ok_for_pgm_addr (rtx reg, bool strict)
11943 {
11944 gcc_assert (REG_P (reg));
11945
11946 if (strict)
11947 {
11948 return REGNO (reg) == REG_Z;
11949 }
11950
11951 /* Avoid combine to propagate hard regs. */
11952
11953 if (can_create_pseudo_p()
11954 && REGNO (reg) < REG_Z)
11955 {
11956 return false;
11957 }
11958
11959 return true;
11960 }
11961
11962
11963 /* Implement `TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P'. */
11964
11965 static bool
11966 avr_addr_space_legitimate_address_p (machine_mode mode, rtx x,
11967 bool strict, addr_space_t as)
11968 {
11969 bool ok = false;
11970
11971 switch (as)
11972 {
11973 default:
11974 gcc_unreachable();
11975
11976 case ADDR_SPACE_GENERIC:
11977 return avr_legitimate_address_p (mode, x, strict);
11978
11979 case ADDR_SPACE_FLASH:
11980 case ADDR_SPACE_FLASH1:
11981 case ADDR_SPACE_FLASH2:
11982 case ADDR_SPACE_FLASH3:
11983 case ADDR_SPACE_FLASH4:
11984 case ADDR_SPACE_FLASH5:
11985
11986 switch (GET_CODE (x))
11987 {
11988 case REG:
11989 ok = avr_reg_ok_for_pgm_addr (x, strict);
11990 break;
11991
11992 case POST_INC:
11993 ok = avr_reg_ok_for_pgm_addr (XEXP (x, 0), strict);
11994 break;
11995
11996 default:
11997 break;
11998 }
11999
12000 break; /* FLASH */
12001
12002 case ADDR_SPACE_MEMX:
12003 if (REG_P (x))
12004 ok = (!strict
12005 && can_create_pseudo_p());
12006
12007 if (LO_SUM == GET_CODE (x))
12008 {
12009 rtx hi = XEXP (x, 0);
12010 rtx lo = XEXP (x, 1);
12011
12012 ok = (REG_P (hi)
12013 && (!strict || REGNO (hi) < FIRST_PSEUDO_REGISTER)
12014 && REG_P (lo)
12015 && REGNO (lo) == REG_Z);
12016 }
12017
12018 break; /* MEMX */
12019 }
12020
12021 if (avr_log.legitimate_address_p)
12022 {
12023 avr_edump ("\n%?: ret=%b, mode=%m strict=%d "
12024 "reload_completed=%d reload_in_progress=%d %s:",
12025 ok, mode, strict, reload_completed, reload_in_progress,
12026 reg_renumber ? "(reg_renumber)" : "");
12027
12028 if (GET_CODE (x) == PLUS
12029 && REG_P (XEXP (x, 0))
12030 && CONST_INT_P (XEXP (x, 1))
12031 && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
12032 && reg_renumber)
12033 {
12034 avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
12035 true_regnum (XEXP (x, 0)));
12036 }
12037
12038 avr_edump ("\n%r\n", x);
12039 }
12040
12041 return ok;
12042 }
12043
12044
12045 /* Implement `TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS'. */
12046
12047 static rtx
12048 avr_addr_space_legitimize_address (rtx x, rtx old_x,
12049 machine_mode mode, addr_space_t as)
12050 {
12051 if (ADDR_SPACE_GENERIC_P (as))
12052 return avr_legitimize_address (x, old_x, mode);
12053
12054 if (avr_log.legitimize_address)
12055 {
12056 avr_edump ("\n%?: mode=%m\n %r\n", mode, old_x);
12057 }
12058
12059 return old_x;
12060 }
12061
12062
12063 /* Implement `TARGET_ADDR_SPACE_CONVERT'. */
12064
12065 static rtx
12066 avr_addr_space_convert (rtx src, tree type_from, tree type_to)
12067 {
12068 addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (type_from));
12069 addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type_to));
12070
12071 if (avr_log.progmem)
12072 avr_edump ("\n%!: op = %r\nfrom = %t\nto = %t\n",
12073 src, type_from, type_to);
12074
12075 /* Up-casting from 16-bit to 24-bit pointer. */
12076
12077 if (as_from != ADDR_SPACE_MEMX
12078 && as_to == ADDR_SPACE_MEMX)
12079 {
12080 int msb;
12081 rtx sym = src;
12082 rtx reg = gen_reg_rtx (PSImode);
12083
12084 while (CONST == GET_CODE (sym) || PLUS == GET_CODE (sym))
12085 sym = XEXP (sym, 0);
12086
12087 /* Look at symbol flags: avr_encode_section_info set the flags
12088 also if attribute progmem was seen so that we get the right
12089 promotion for, e.g. PSTR-like strings that reside in generic space
12090 but are located in flash. In that case we patch the incoming
12091 address space. */
12092
12093 if (SYMBOL_REF == GET_CODE (sym)
12094 && ADDR_SPACE_FLASH == AVR_SYMBOL_GET_ADDR_SPACE (sym))
12095 {
12096 as_from = ADDR_SPACE_FLASH;
12097 }
12098
12099 /* Linearize memory: RAM has bit 23 set. */
12100
12101 msb = ADDR_SPACE_GENERIC_P (as_from)
12102 ? 0x80
12103 : avr_addrspace[as_from].segment;
12104
12105 src = force_reg (Pmode, src);
12106
12107 emit_insn (msb == 0
12108 ? gen_zero_extendhipsi2 (reg, src)
12109 : gen_n_extendhipsi2 (reg, gen_int_mode (msb, QImode), src));
12110
12111 return reg;
12112 }
12113
12114 /* Down-casting from 24-bit to 16-bit throws away the high byte. */
12115
12116 if (as_from == ADDR_SPACE_MEMX
12117 && as_to != ADDR_SPACE_MEMX)
12118 {
12119 rtx new_src = gen_reg_rtx (Pmode);
12120
12121 src = force_reg (PSImode, src);
12122
12123 emit_move_insn (new_src,
12124 simplify_gen_subreg (Pmode, src, PSImode, 0));
12125 return new_src;
12126 }
12127
12128 return src;
12129 }
12130
12131
12132 /* Implement `TARGET_ADDR_SPACE_SUBSET_P'. */
12133
12134 static bool
12135 avr_addr_space_subset_p (addr_space_t subset ATTRIBUTE_UNUSED,
12136 addr_space_t superset ATTRIBUTE_UNUSED)
12137 {
12138 /* Allow any kind of pointer mess. */
12139
12140 return true;
12141 }
12142
12143
12144 /* Implement `TARGET_CONVERT_TO_TYPE'. */
12145
12146 static tree
12147 avr_convert_to_type (tree type, tree expr)
12148 {
12149 /* Print a diagnose for pointer conversion that changes the address
12150 space of the pointer target to a non-enclosing address space,
12151 provided -Waddr-space-convert is on.
12152
12153 FIXME: Filter out cases where the target object is known to
12154 be located in the right memory, like in
12155
12156 (const __flash*) PSTR ("text")
12157
12158 Also try to distinguish between explicit casts requested by
12159 the user and implicit casts like
12160
12161 void f (const __flash char*);
12162
12163 void g (const char *p)
12164 {
12165 f ((const __flash*) p);
12166 }
12167
12168 under the assumption that an explicit casts means that the user
12169 knows what he is doing, e.g. interface with PSTR or old style
12170 code with progmem and pgm_read_xxx.
12171 */
12172
12173 if (avr_warn_addr_space_convert
12174 && expr != error_mark_node
12175 && POINTER_TYPE_P (type)
12176 && POINTER_TYPE_P (TREE_TYPE (expr)))
12177 {
12178 addr_space_t as_old = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
12179 addr_space_t as_new = TYPE_ADDR_SPACE (TREE_TYPE (type));
12180
12181 if (avr_log.progmem)
12182 avr_edump ("%?: type = %t\nexpr = %t\n\n", type, expr);
12183
12184 if (as_new != ADDR_SPACE_MEMX
12185 && as_new != as_old)
12186 {
12187 location_t loc = EXPR_LOCATION (expr);
12188 const char *name_old = avr_addrspace[as_old].name;
12189 const char *name_new = avr_addrspace[as_new].name;
12190
12191 warning (OPT_Waddr_space_convert,
12192 "conversion from address space %qs to address space %qs",
12193 ADDR_SPACE_GENERIC_P (as_old) ? "generic" : name_old,
12194 ADDR_SPACE_GENERIC_P (as_new) ? "generic" : name_new);
12195
12196 return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, expr);
12197 }
12198 }
12199
12200 return NULL_TREE;
12201 }
12202
12203
12204 /* Worker function for movmemhi expander.
12205 XOP[0] Destination as MEM:BLK
12206 XOP[1] Source " "
12207 XOP[2] # Bytes to copy
12208
12209 Return TRUE if the expansion is accomplished.
12210 Return FALSE if the operand compination is not supported. */
12211
12212 bool
12213 avr_emit_movmemhi (rtx *xop)
12214 {
12215 HOST_WIDE_INT count;
12216 machine_mode loop_mode;
12217 addr_space_t as = MEM_ADDR_SPACE (xop[1]);
12218 rtx loop_reg, addr1, a_src, a_dest, insn, xas;
12219 rtx a_hi8 = NULL_RTX;
12220
12221 if (avr_mem_flash_p (xop[0]))
12222 return false;
12223
12224 if (!CONST_INT_P (xop[2]))
12225 return false;
12226
12227 count = INTVAL (xop[2]);
12228 if (count <= 0)
12229 return false;
12230
12231 a_src = XEXP (xop[1], 0);
12232 a_dest = XEXP (xop[0], 0);
12233
12234 if (PSImode == GET_MODE (a_src))
12235 {
12236 gcc_assert (as == ADDR_SPACE_MEMX);
12237
12238 loop_mode = (count < 0x100) ? QImode : HImode;
12239 loop_reg = gen_rtx_REG (loop_mode, 24);
12240 emit_move_insn (loop_reg, gen_int_mode (count, loop_mode));
12241
12242 addr1 = simplify_gen_subreg (HImode, a_src, PSImode, 0);
12243 a_hi8 = simplify_gen_subreg (QImode, a_src, PSImode, 2);
12244 }
12245 else
12246 {
12247 int segment = avr_addrspace[as].segment;
12248
12249 if (segment
12250 && avr_n_flash > 1)
12251 {
12252 a_hi8 = GEN_INT (segment);
12253 emit_move_insn (rampz_rtx, a_hi8 = copy_to_mode_reg (QImode, a_hi8));
12254 }
12255 else if (!ADDR_SPACE_GENERIC_P (as))
12256 {
12257 as = ADDR_SPACE_FLASH;
12258 }
12259
12260 addr1 = a_src;
12261
12262 loop_mode = (count <= 0x100) ? QImode : HImode;
12263 loop_reg = copy_to_mode_reg (loop_mode, gen_int_mode (count, loop_mode));
12264 }
12265
12266 xas = GEN_INT (as);
12267
12268 /* FIXME: Register allocator might come up with spill fails if it is left
12269 on its own. Thus, we allocate the pointer registers by hand:
12270 Z = source address
12271 X = destination address */
12272
12273 emit_move_insn (lpm_addr_reg_rtx, addr1);
12274 emit_move_insn (gen_rtx_REG (HImode, REG_X), a_dest);
12275
12276 /* FIXME: Register allocator does a bad job and might spill address
12277 register(s) inside the loop leading to additional move instruction
12278 to/from stack which could clobber tmp_reg. Thus, do *not* emit
12279 load and store as separate insns. Instead, we perform the copy
12280 by means of one monolithic insn. */
12281
12282 gcc_assert (TMP_REGNO == LPM_REGNO);
12283
12284 if (as != ADDR_SPACE_MEMX)
12285 {
12286 /* Load instruction ([E]LPM or LD) is known at compile time:
12287 Do the copy-loop inline. */
12288
12289 rtx (*fun) (rtx, rtx, rtx)
12290 = QImode == loop_mode ? gen_movmem_qi : gen_movmem_hi;
12291
12292 insn = fun (xas, loop_reg, loop_reg);
12293 }
12294 else
12295 {
12296 rtx (*fun) (rtx, rtx)
12297 = QImode == loop_mode ? gen_movmemx_qi : gen_movmemx_hi;
12298
12299 emit_move_insn (gen_rtx_REG (QImode, 23), a_hi8);
12300
12301 insn = fun (xas, GEN_INT (avr_addr.rampz));
12302 }
12303
12304 set_mem_addr_space (SET_SRC (XVECEXP (insn, 0, 0)), as);
12305 emit_insn (insn);
12306
12307 return true;
12308 }
12309
12310
12311 /* Print assembler for movmem_qi, movmem_hi insns...
12312 $0 : Address Space
12313 $1, $2 : Loop register
12314 Z : Source address
12315 X : Destination address
12316 */
12317
12318 const char*
12319 avr_out_movmem (rtx_insn *insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
12320 {
12321 addr_space_t as = (addr_space_t) INTVAL (op[0]);
12322 machine_mode loop_mode = GET_MODE (op[1]);
12323 bool sbiw_p = test_hard_reg_class (ADDW_REGS, op[1]);
12324 rtx xop[3];
12325
12326 if (plen)
12327 *plen = 0;
12328
12329 xop[0] = op[0];
12330 xop[1] = op[1];
12331 xop[2] = tmp_reg_rtx;
12332
12333 /* Loop label */
12334
12335 avr_asm_len ("0:", xop, plen, 0);
12336
12337 /* Load with post-increment */
12338
12339 switch (as)
12340 {
12341 default:
12342 gcc_unreachable();
12343
12344 case ADDR_SPACE_GENERIC:
12345
12346 avr_asm_len ("ld %2,Z+", xop, plen, 1);
12347 break;
12348
12349 case ADDR_SPACE_FLASH:
12350
12351 if (AVR_HAVE_LPMX)
12352 avr_asm_len ("lpm %2,Z+", xop, plen, 1);
12353 else
12354 avr_asm_len ("lpm" CR_TAB
12355 "adiw r30,1", xop, plen, 2);
12356 break;
12357
12358 case ADDR_SPACE_FLASH1:
12359 case ADDR_SPACE_FLASH2:
12360 case ADDR_SPACE_FLASH3:
12361 case ADDR_SPACE_FLASH4:
12362 case ADDR_SPACE_FLASH5:
12363
12364 if (AVR_HAVE_ELPMX)
12365 avr_asm_len ("elpm %2,Z+", xop, plen, 1);
12366 else
12367 avr_asm_len ("elpm" CR_TAB
12368 "adiw r30,1", xop, plen, 2);
12369 break;
12370 }
12371
12372 /* Store with post-increment */
12373
12374 avr_asm_len ("st X+,%2", xop, plen, 1);
12375
12376 /* Decrement loop-counter and set Z-flag */
12377
12378 if (QImode == loop_mode)
12379 {
12380 avr_asm_len ("dec %1", xop, plen, 1);
12381 }
12382 else if (sbiw_p)
12383 {
12384 avr_asm_len ("sbiw %1,1", xop, plen, 1);
12385 }
12386 else
12387 {
12388 avr_asm_len ("subi %A1,1" CR_TAB
12389 "sbci %B1,0", xop, plen, 2);
12390 }
12391
12392 /* Loop until zero */
12393
12394 return avr_asm_len ("brne 0b", xop, plen, 1);
12395 }
12396
12397
12398 \f
12399 /* Helper for __builtin_avr_delay_cycles */
12400
12401 static rtx
12402 avr_mem_clobber (void)
12403 {
12404 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12405 MEM_VOLATILE_P (mem) = 1;
12406 return mem;
12407 }
12408
12409 static void
12410 avr_expand_delay_cycles (rtx operands0)
12411 {
12412 unsigned HOST_WIDE_INT cycles = UINTVAL (operands0) & GET_MODE_MASK (SImode);
12413 unsigned HOST_WIDE_INT cycles_used;
12414 unsigned HOST_WIDE_INT loop_count;
12415
12416 if (IN_RANGE (cycles, 83886082, 0xFFFFFFFF))
12417 {
12418 loop_count = ((cycles - 9) / 6) + 1;
12419 cycles_used = ((loop_count - 1) * 6) + 9;
12420 emit_insn (gen_delay_cycles_4 (gen_int_mode (loop_count, SImode),
12421 avr_mem_clobber()));
12422 cycles -= cycles_used;
12423 }
12424
12425 if (IN_RANGE (cycles, 262145, 83886081))
12426 {
12427 loop_count = ((cycles - 7) / 5) + 1;
12428 if (loop_count > 0xFFFFFF)
12429 loop_count = 0xFFFFFF;
12430 cycles_used = ((loop_count - 1) * 5) + 7;
12431 emit_insn (gen_delay_cycles_3 (gen_int_mode (loop_count, SImode),
12432 avr_mem_clobber()));
12433 cycles -= cycles_used;
12434 }
12435
12436 if (IN_RANGE (cycles, 768, 262144))
12437 {
12438 loop_count = ((cycles - 5) / 4) + 1;
12439 if (loop_count > 0xFFFF)
12440 loop_count = 0xFFFF;
12441 cycles_used = ((loop_count - 1) * 4) + 5;
12442 emit_insn (gen_delay_cycles_2 (gen_int_mode (loop_count, HImode),
12443 avr_mem_clobber()));
12444 cycles -= cycles_used;
12445 }
12446
12447 if (IN_RANGE (cycles, 6, 767))
12448 {
12449 loop_count = cycles / 3;
12450 if (loop_count > 255)
12451 loop_count = 255;
12452 cycles_used = loop_count * 3;
12453 emit_insn (gen_delay_cycles_1 (gen_int_mode (loop_count, QImode),
12454 avr_mem_clobber()));
12455 cycles -= cycles_used;
12456 }
12457
12458 while (cycles >= 2)
12459 {
12460 emit_insn (gen_nopv (GEN_INT(2)));
12461 cycles -= 2;
12462 }
12463
12464 if (cycles == 1)
12465 {
12466 emit_insn (gen_nopv (GEN_INT(1)));
12467 cycles--;
12468 }
12469 }
12470
12471
12472 /* Compute the image of x under f, i.e. perform x --> f(x) */
12473
12474 static int
12475 avr_map (unsigned int f, int x)
12476 {
12477 return x < 8 ? (f >> (4 * x)) & 0xf : 0;
12478 }
12479
12480
12481 /* Return some metrics of map A. */
12482
12483 enum
12484 {
12485 /* Number of fixed points in { 0 ... 7 } */
12486 MAP_FIXED_0_7,
12487
12488 /* Size of preimage of non-fixed points in { 0 ... 7 } */
12489 MAP_NONFIXED_0_7,
12490
12491 /* Mask representing the fixed points in { 0 ... 7 } */
12492 MAP_MASK_FIXED_0_7,
12493
12494 /* Size of the preimage of { 0 ... 7 } */
12495 MAP_PREIMAGE_0_7,
12496
12497 /* Mask that represents the preimage of { f } */
12498 MAP_MASK_PREIMAGE_F
12499 };
12500
12501 static unsigned
12502 avr_map_metric (unsigned int a, int mode)
12503 {
12504 unsigned i, metric = 0;
12505
12506 for (i = 0; i < 8; i++)
12507 {
12508 unsigned ai = avr_map (a, i);
12509
12510 if (mode == MAP_FIXED_0_7)
12511 metric += ai == i;
12512 else if (mode == MAP_NONFIXED_0_7)
12513 metric += ai < 8 && ai != i;
12514 else if (mode == MAP_MASK_FIXED_0_7)
12515 metric |= ((unsigned) (ai == i)) << i;
12516 else if (mode == MAP_PREIMAGE_0_7)
12517 metric += ai < 8;
12518 else if (mode == MAP_MASK_PREIMAGE_F)
12519 metric |= ((unsigned) (ai == 0xf)) << i;
12520 else
12521 gcc_unreachable();
12522 }
12523
12524 return metric;
12525 }
12526
12527
12528 /* Return true if IVAL has a 0xf in its hexadecimal representation
12529 and false, otherwise. Only nibbles 0..7 are taken into account.
12530 Used as constraint helper for C0f and Cxf. */
12531
12532 bool
12533 avr_has_nibble_0xf (rtx ival)
12534 {
12535 unsigned int map = UINTVAL (ival) & GET_MODE_MASK (SImode);
12536 return 0 != avr_map_metric (map, MAP_MASK_PREIMAGE_F);
12537 }
12538
12539
12540 /* We have a set of bits that are mapped by a function F.
12541 Try to decompose F by means of a second function G so that
12542
12543 F = F o G^-1 o G
12544
12545 and
12546
12547 cost (F o G^-1) + cost (G) < cost (F)
12548
12549 Example: Suppose builtin insert_bits supplies us with the map
12550 F = 0x3210ffff. Instead of doing 4 bit insertions to get the high
12551 nibble of the result, we can just as well rotate the bits before inserting
12552 them and use the map 0x7654ffff which is cheaper than the original map.
12553 For this example G = G^-1 = 0x32107654 and F o G^-1 = 0x7654ffff. */
12554
12555 typedef struct
12556 {
12557 /* tree code of binary function G */
12558 enum tree_code code;
12559
12560 /* The constant second argument of G */
12561 int arg;
12562
12563 /* G^-1, the inverse of G (*, arg) */
12564 unsigned ginv;
12565
12566 /* The cost of appplying G (*, arg) */
12567 int cost;
12568
12569 /* The composition F o G^-1 (*, arg) for some function F */
12570 unsigned int map;
12571
12572 /* For debug purpose only */
12573 const char *str;
12574 } avr_map_op_t;
12575
12576 static const avr_map_op_t avr_map_op[] =
12577 {
12578 { LROTATE_EXPR, 0, 0x76543210, 0, 0, "id" },
12579 { LROTATE_EXPR, 1, 0x07654321, 2, 0, "<<<" },
12580 { LROTATE_EXPR, 2, 0x10765432, 4, 0, "<<<" },
12581 { LROTATE_EXPR, 3, 0x21076543, 4, 0, "<<<" },
12582 { LROTATE_EXPR, 4, 0x32107654, 1, 0, "<<<" },
12583 { LROTATE_EXPR, 5, 0x43210765, 3, 0, "<<<" },
12584 { LROTATE_EXPR, 6, 0x54321076, 5, 0, "<<<" },
12585 { LROTATE_EXPR, 7, 0x65432107, 3, 0, "<<<" },
12586 { RSHIFT_EXPR, 1, 0x6543210c, 1, 0, ">>" },
12587 { RSHIFT_EXPR, 1, 0x7543210c, 1, 0, ">>" },
12588 { RSHIFT_EXPR, 2, 0x543210cc, 2, 0, ">>" },
12589 { RSHIFT_EXPR, 2, 0x643210cc, 2, 0, ">>" },
12590 { RSHIFT_EXPR, 2, 0x743210cc, 2, 0, ">>" },
12591 { LSHIFT_EXPR, 1, 0xc7654321, 1, 0, "<<" },
12592 { LSHIFT_EXPR, 2, 0xcc765432, 2, 0, "<<" }
12593 };
12594
12595
12596 /* Try to decompose F as F = (F o G^-1) o G as described above.
12597 The result is a struct representing F o G^-1 and G.
12598 If result.cost < 0 then such a decomposition does not exist. */
12599
12600 static avr_map_op_t
12601 avr_map_decompose (unsigned int f, const avr_map_op_t *g, bool val_const_p)
12602 {
12603 int i;
12604 bool val_used_p = 0 != avr_map_metric (f, MAP_MASK_PREIMAGE_F);
12605 avr_map_op_t f_ginv = *g;
12606 unsigned int ginv = g->ginv;
12607
12608 f_ginv.cost = -1;
12609
12610 /* Step 1: Computing F o G^-1 */
12611
12612 for (i = 7; i >= 0; i--)
12613 {
12614 int x = avr_map (f, i);
12615
12616 if (x <= 7)
12617 {
12618 x = avr_map (ginv, x);
12619
12620 /* The bit is no element of the image of G: no avail (cost = -1) */
12621
12622 if (x > 7)
12623 return f_ginv;
12624 }
12625
12626 f_ginv.map = (f_ginv.map << 4) + x;
12627 }
12628
12629 /* Step 2: Compute the cost of the operations.
12630 The overall cost of doing an operation prior to the insertion is
12631 the cost of the insertion plus the cost of the operation. */
12632
12633 /* Step 2a: Compute cost of F o G^-1 */
12634
12635 if (0 == avr_map_metric (f_ginv.map, MAP_NONFIXED_0_7))
12636 {
12637 /* The mapping consists only of fixed points and can be folded
12638 to AND/OR logic in the remainder. Reasonable cost is 3. */
12639
12640 f_ginv.cost = 2 + (val_used_p && !val_const_p);
12641 }
12642 else
12643 {
12644 rtx xop[4];
12645
12646 /* Get the cost of the insn by calling the output worker with some
12647 fake values. Mimic effect of reloading xop[3]: Unused operands
12648 are mapped to 0 and used operands are reloaded to xop[0]. */
12649
12650 xop[0] = all_regs_rtx[24];
12651 xop[1] = gen_int_mode (f_ginv.map, SImode);
12652 xop[2] = all_regs_rtx[25];
12653 xop[3] = val_used_p ? xop[0] : const0_rtx;
12654
12655 avr_out_insert_bits (xop, &f_ginv.cost);
12656
12657 f_ginv.cost += val_const_p && val_used_p ? 1 : 0;
12658 }
12659
12660 /* Step 2b: Add cost of G */
12661
12662 f_ginv.cost += g->cost;
12663
12664 if (avr_log.builtin)
12665 avr_edump (" %s%d=%d", g->str, g->arg, f_ginv.cost);
12666
12667 return f_ginv;
12668 }
12669
12670
12671 /* Insert bits from XOP[1] into XOP[0] according to MAP.
12672 XOP[0] and XOP[1] don't overlap.
12673 If FIXP_P = true: Move all bits according to MAP using BLD/BST sequences.
12674 If FIXP_P = false: Just move the bit if its position in the destination
12675 is different to its source position. */
12676
12677 static void
12678 avr_move_bits (rtx *xop, unsigned int map, bool fixp_p, int *plen)
12679 {
12680 int bit_dest, b;
12681
12682 /* T-flag contains this bit of the source, i.e. of XOP[1] */
12683 int t_bit_src = -1;
12684
12685 /* We order the operations according to the requested source bit b. */
12686
12687 for (b = 0; b < 8; b++)
12688 for (bit_dest = 0; bit_dest < 8; bit_dest++)
12689 {
12690 int bit_src = avr_map (map, bit_dest);
12691
12692 if (b != bit_src
12693 || bit_src >= 8
12694 /* Same position: No need to copy as requested by FIXP_P. */
12695 || (bit_dest == bit_src && !fixp_p))
12696 continue;
12697
12698 if (t_bit_src != bit_src)
12699 {
12700 /* Source bit is not yet in T: Store it to T. */
12701
12702 t_bit_src = bit_src;
12703
12704 xop[3] = GEN_INT (bit_src);
12705 avr_asm_len ("bst %T1%T3", xop, plen, 1);
12706 }
12707
12708 /* Load destination bit with T. */
12709
12710 xop[3] = GEN_INT (bit_dest);
12711 avr_asm_len ("bld %T0%T3", xop, plen, 1);
12712 }
12713 }
12714
12715
12716 /* PLEN == 0: Print assembler code for `insert_bits'.
12717 PLEN != 0: Compute code length in bytes.
12718
12719 OP[0]: Result
12720 OP[1]: The mapping composed of nibbles. If nibble no. N is
12721 0: Bit N of result is copied from bit OP[2].0
12722 ... ...
12723 7: Bit N of result is copied from bit OP[2].7
12724 0xf: Bit N of result is copied from bit OP[3].N
12725 OP[2]: Bits to be inserted
12726 OP[3]: Target value */
12727
12728 const char*
12729 avr_out_insert_bits (rtx *op, int *plen)
12730 {
12731 unsigned int map = UINTVAL (op[1]) & GET_MODE_MASK (SImode);
12732 unsigned mask_fixed;
12733 bool fixp_p = true;
12734 rtx xop[4];
12735
12736 xop[0] = op[0];
12737 xop[1] = op[2];
12738 xop[2] = op[3];
12739
12740 gcc_assert (REG_P (xop[2]) || CONST_INT_P (xop[2]));
12741
12742 if (plen)
12743 *plen = 0;
12744 else if (flag_print_asm_name)
12745 fprintf (asm_out_file, ASM_COMMENT_START "map = 0x%08x\n", map);
12746
12747 /* If MAP has fixed points it might be better to initialize the result
12748 with the bits to be inserted instead of moving all bits by hand. */
12749
12750 mask_fixed = avr_map_metric (map, MAP_MASK_FIXED_0_7);
12751
12752 if (REGNO (xop[0]) == REGNO (xop[1]))
12753 {
12754 /* Avoid early-clobber conflicts */
12755
12756 avr_asm_len ("mov __tmp_reg__,%1", xop, plen, 1);
12757 xop[1] = tmp_reg_rtx;
12758 fixp_p = false;
12759 }
12760
12761 if (avr_map_metric (map, MAP_MASK_PREIMAGE_F))
12762 {
12763 /* XOP[2] is used and reloaded to XOP[0] already */
12764
12765 int n_fix = 0, n_nofix = 0;
12766
12767 gcc_assert (REG_P (xop[2]));
12768
12769 /* Get the code size of the bit insertions; once with all bits
12770 moved and once with fixed points omitted. */
12771
12772 avr_move_bits (xop, map, true, &n_fix);
12773 avr_move_bits (xop, map, false, &n_nofix);
12774
12775 if (fixp_p && n_fix - n_nofix > 3)
12776 {
12777 xop[3] = gen_int_mode (~mask_fixed, QImode);
12778
12779 avr_asm_len ("eor %0,%1" CR_TAB
12780 "andi %0,%3" CR_TAB
12781 "eor %0,%1", xop, plen, 3);
12782 fixp_p = false;
12783 }
12784 }
12785 else
12786 {
12787 /* XOP[2] is unused */
12788
12789 if (fixp_p && mask_fixed)
12790 {
12791 avr_asm_len ("mov %0,%1", xop, plen, 1);
12792 fixp_p = false;
12793 }
12794 }
12795
12796 /* Move/insert remaining bits. */
12797
12798 avr_move_bits (xop, map, fixp_p, plen);
12799
12800 return "";
12801 }
12802
12803
12804 /* IDs for all the AVR builtins. */
12805
12806 enum avr_builtin_id
12807 {
12808 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME) \
12809 AVR_BUILTIN_ ## NAME,
12810 #include "builtins.def"
12811 #undef DEF_BUILTIN
12812
12813 AVR_BUILTIN_COUNT
12814 };
12815
12816 struct GTY(()) avr_builtin_description
12817 {
12818 enum insn_code icode;
12819 int n_args;
12820 tree fndecl;
12821 };
12822
12823
12824 /* Notice that avr_bdesc[] and avr_builtin_id are initialized in such a way
12825 that a built-in's ID can be used to access the built-in by means of
12826 avr_bdesc[ID] */
12827
12828 static GTY(()) struct avr_builtin_description
12829 avr_bdesc[AVR_BUILTIN_COUNT] =
12830 {
12831 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, LIBNAME) \
12832 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
12833 #include "builtins.def"
12834 #undef DEF_BUILTIN
12835 };
12836
12837
12838 /* Implement `TARGET_BUILTIN_DECL'. */
12839
12840 static tree
12841 avr_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED)
12842 {
12843 if (id < AVR_BUILTIN_COUNT)
12844 return avr_bdesc[id].fndecl;
12845
12846 return error_mark_node;
12847 }
12848
12849
12850 static void
12851 avr_init_builtin_int24 (void)
12852 {
12853 tree int24_type = make_signed_type (GET_MODE_BITSIZE (PSImode));
12854 tree uint24_type = make_unsigned_type (GET_MODE_BITSIZE (PSImode));
12855
12856 lang_hooks.types.register_builtin_type (int24_type, "__int24");
12857 lang_hooks.types.register_builtin_type (uint24_type, "__uint24");
12858 }
12859
12860
12861 /* Implement `TARGET_INIT_BUILTINS' */
12862 /* Set up all builtin functions for this target. */
12863
12864 static void
12865 avr_init_builtins (void)
12866 {
12867 tree void_ftype_void
12868 = build_function_type_list (void_type_node, NULL_TREE);
12869 tree uchar_ftype_uchar
12870 = build_function_type_list (unsigned_char_type_node,
12871 unsigned_char_type_node,
12872 NULL_TREE);
12873 tree uint_ftype_uchar_uchar
12874 = build_function_type_list (unsigned_type_node,
12875 unsigned_char_type_node,
12876 unsigned_char_type_node,
12877 NULL_TREE);
12878 tree int_ftype_char_char
12879 = build_function_type_list (integer_type_node,
12880 char_type_node,
12881 char_type_node,
12882 NULL_TREE);
12883 tree int_ftype_char_uchar
12884 = build_function_type_list (integer_type_node,
12885 char_type_node,
12886 unsigned_char_type_node,
12887 NULL_TREE);
12888 tree void_ftype_ulong
12889 = build_function_type_list (void_type_node,
12890 long_unsigned_type_node,
12891 NULL_TREE);
12892
12893 tree uchar_ftype_ulong_uchar_uchar
12894 = build_function_type_list (unsigned_char_type_node,
12895 long_unsigned_type_node,
12896 unsigned_char_type_node,
12897 unsigned_char_type_node,
12898 NULL_TREE);
12899
12900 tree const_memx_void_node
12901 = build_qualified_type (void_type_node,
12902 TYPE_QUAL_CONST
12903 | ENCODE_QUAL_ADDR_SPACE (ADDR_SPACE_MEMX));
12904
12905 tree const_memx_ptr_type_node
12906 = build_pointer_type_for_mode (const_memx_void_node, PSImode, false);
12907
12908 tree char_ftype_const_memx_ptr
12909 = build_function_type_list (char_type_node,
12910 const_memx_ptr_type_node,
12911 NULL);
12912
12913 #define ITYP(T) \
12914 lang_hooks.types.type_for_size (TYPE_PRECISION (T), TYPE_UNSIGNED (T))
12915
12916 #define FX_FTYPE_FX(fx) \
12917 tree fx##r_ftype_##fx##r \
12918 = build_function_type_list (node_##fx##r, node_##fx##r, NULL); \
12919 tree fx##k_ftype_##fx##k \
12920 = build_function_type_list (node_##fx##k, node_##fx##k, NULL)
12921
12922 #define FX_FTYPE_FX_INT(fx) \
12923 tree fx##r_ftype_##fx##r_int \
12924 = build_function_type_list (node_##fx##r, node_##fx##r, \
12925 integer_type_node, NULL); \
12926 tree fx##k_ftype_##fx##k_int \
12927 = build_function_type_list (node_##fx##k, node_##fx##k, \
12928 integer_type_node, NULL)
12929
12930 #define INT_FTYPE_FX(fx) \
12931 tree int_ftype_##fx##r \
12932 = build_function_type_list (integer_type_node, node_##fx##r, NULL); \
12933 tree int_ftype_##fx##k \
12934 = build_function_type_list (integer_type_node, node_##fx##k, NULL)
12935
12936 #define INTX_FTYPE_FX(fx) \
12937 tree int##fx##r_ftype_##fx##r \
12938 = build_function_type_list (ITYP (node_##fx##r), node_##fx##r, NULL); \
12939 tree int##fx##k_ftype_##fx##k \
12940 = build_function_type_list (ITYP (node_##fx##k), node_##fx##k, NULL)
12941
12942 #define FX_FTYPE_INTX(fx) \
12943 tree fx##r_ftype_int##fx##r \
12944 = build_function_type_list (node_##fx##r, ITYP (node_##fx##r), NULL); \
12945 tree fx##k_ftype_int##fx##k \
12946 = build_function_type_list (node_##fx##k, ITYP (node_##fx##k), NULL)
12947
12948 tree node_hr = short_fract_type_node;
12949 tree node_nr = fract_type_node;
12950 tree node_lr = long_fract_type_node;
12951 tree node_llr = long_long_fract_type_node;
12952
12953 tree node_uhr = unsigned_short_fract_type_node;
12954 tree node_unr = unsigned_fract_type_node;
12955 tree node_ulr = unsigned_long_fract_type_node;
12956 tree node_ullr = unsigned_long_long_fract_type_node;
12957
12958 tree node_hk = short_accum_type_node;
12959 tree node_nk = accum_type_node;
12960 tree node_lk = long_accum_type_node;
12961 tree node_llk = long_long_accum_type_node;
12962
12963 tree node_uhk = unsigned_short_accum_type_node;
12964 tree node_unk = unsigned_accum_type_node;
12965 tree node_ulk = unsigned_long_accum_type_node;
12966 tree node_ullk = unsigned_long_long_accum_type_node;
12967
12968
12969 /* For absfx builtins. */
12970
12971 FX_FTYPE_FX (h);
12972 FX_FTYPE_FX (n);
12973 FX_FTYPE_FX (l);
12974 FX_FTYPE_FX (ll);
12975
12976 /* For roundfx builtins. */
12977
12978 FX_FTYPE_FX_INT (h);
12979 FX_FTYPE_FX_INT (n);
12980 FX_FTYPE_FX_INT (l);
12981 FX_FTYPE_FX_INT (ll);
12982
12983 FX_FTYPE_FX_INT (uh);
12984 FX_FTYPE_FX_INT (un);
12985 FX_FTYPE_FX_INT (ul);
12986 FX_FTYPE_FX_INT (ull);
12987
12988 /* For countlsfx builtins. */
12989
12990 INT_FTYPE_FX (h);
12991 INT_FTYPE_FX (n);
12992 INT_FTYPE_FX (l);
12993 INT_FTYPE_FX (ll);
12994
12995 INT_FTYPE_FX (uh);
12996 INT_FTYPE_FX (un);
12997 INT_FTYPE_FX (ul);
12998 INT_FTYPE_FX (ull);
12999
13000 /* For bitsfx builtins. */
13001
13002 INTX_FTYPE_FX (h);
13003 INTX_FTYPE_FX (n);
13004 INTX_FTYPE_FX (l);
13005 INTX_FTYPE_FX (ll);
13006
13007 INTX_FTYPE_FX (uh);
13008 INTX_FTYPE_FX (un);
13009 INTX_FTYPE_FX (ul);
13010 INTX_FTYPE_FX (ull);
13011
13012 /* For fxbits builtins. */
13013
13014 FX_FTYPE_INTX (h);
13015 FX_FTYPE_INTX (n);
13016 FX_FTYPE_INTX (l);
13017 FX_FTYPE_INTX (ll);
13018
13019 FX_FTYPE_INTX (uh);
13020 FX_FTYPE_INTX (un);
13021 FX_FTYPE_INTX (ul);
13022 FX_FTYPE_INTX (ull);
13023
13024
13025 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME) \
13026 { \
13027 int id = AVR_BUILTIN_ ## NAME; \
13028 const char *Name = "__builtin_avr_" #NAME; \
13029 char *name = (char*) alloca (1 + strlen (Name)); \
13030 \
13031 gcc_assert (id < AVR_BUILTIN_COUNT); \
13032 avr_bdesc[id].fndecl \
13033 = add_builtin_function (avr_tolower (name, Name), TYPE, id, \
13034 BUILT_IN_MD, LIBNAME, NULL_TREE); \
13035 }
13036 #include "builtins.def"
13037 #undef DEF_BUILTIN
13038
13039 avr_init_builtin_int24 ();
13040 }
13041
13042
13043 /* Subroutine of avr_expand_builtin to expand vanilla builtins
13044 with non-void result and 1 ... 3 arguments. */
13045
13046 static rtx
13047 avr_default_expand_builtin (enum insn_code icode, tree exp, rtx target)
13048 {
13049 rtx pat, xop[3];
13050 int n, n_args = call_expr_nargs (exp);
13051 machine_mode tmode = insn_data[icode].operand[0].mode;
13052
13053 gcc_assert (n_args >= 1 && n_args <= 3);
13054
13055 if (target == NULL_RTX
13056 || GET_MODE (target) != tmode
13057 || !insn_data[icode].operand[0].predicate (target, tmode))
13058 {
13059 target = gen_reg_rtx (tmode);
13060 }
13061
13062 for (n = 0; n < n_args; n++)
13063 {
13064 tree arg = CALL_EXPR_ARG (exp, n);
13065 rtx op = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
13066 machine_mode opmode = GET_MODE (op);
13067 machine_mode mode = insn_data[icode].operand[n+1].mode;
13068
13069 if ((opmode == SImode || opmode == VOIDmode) && mode == HImode)
13070 {
13071 opmode = HImode;
13072 op = gen_lowpart (HImode, op);
13073 }
13074
13075 /* In case the insn wants input operands in modes different from
13076 the result, abort. */
13077
13078 gcc_assert (opmode == mode || opmode == VOIDmode);
13079
13080 if (!insn_data[icode].operand[n+1].predicate (op, mode))
13081 op = copy_to_mode_reg (mode, op);
13082
13083 xop[n] = op;
13084 }
13085
13086 switch (n_args)
13087 {
13088 case 1: pat = GEN_FCN (icode) (target, xop[0]); break;
13089 case 2: pat = GEN_FCN (icode) (target, xop[0], xop[1]); break;
13090 case 3: pat = GEN_FCN (icode) (target, xop[0], xop[1], xop[2]); break;
13091
13092 default:
13093 gcc_unreachable();
13094 }
13095
13096 if (pat == NULL_RTX)
13097 return NULL_RTX;
13098
13099 emit_insn (pat);
13100
13101 return target;
13102 }
13103
13104
13105 /* Implement `TARGET_EXPAND_BUILTIN'. */
13106 /* Expand an expression EXP that calls a built-in function,
13107 with result going to TARGET if that's convenient
13108 (and in mode MODE if that's convenient).
13109 SUBTARGET may be used as the target for computing one of EXP's operands.
13110 IGNORE is nonzero if the value is to be ignored. */
13111
13112 static rtx
13113 avr_expand_builtin (tree exp, rtx target,
13114 rtx subtarget ATTRIBUTE_UNUSED,
13115 machine_mode mode ATTRIBUTE_UNUSED,
13116 int ignore)
13117 {
13118 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
13119 const char *bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
13120 unsigned int id = DECL_FUNCTION_CODE (fndecl);
13121 const struct avr_builtin_description *d = &avr_bdesc[id];
13122 tree arg0;
13123 rtx op0;
13124
13125 gcc_assert (id < AVR_BUILTIN_COUNT);
13126
13127 switch (id)
13128 {
13129 case AVR_BUILTIN_NOP:
13130 emit_insn (gen_nopv (GEN_INT(1)));
13131 return 0;
13132
13133 case AVR_BUILTIN_DELAY_CYCLES:
13134 {
13135 arg0 = CALL_EXPR_ARG (exp, 0);
13136 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
13137
13138 if (!CONST_INT_P (op0))
13139 error ("%s expects a compile time integer constant", bname);
13140 else
13141 avr_expand_delay_cycles (op0);
13142
13143 return NULL_RTX;
13144 }
13145
13146 case AVR_BUILTIN_INSERT_BITS:
13147 {
13148 arg0 = CALL_EXPR_ARG (exp, 0);
13149 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
13150
13151 if (!CONST_INT_P (op0))
13152 {
13153 error ("%s expects a compile time long integer constant"
13154 " as first argument", bname);
13155 return target;
13156 }
13157
13158 break;
13159 }
13160
13161 case AVR_BUILTIN_ROUNDHR: case AVR_BUILTIN_ROUNDUHR:
13162 case AVR_BUILTIN_ROUNDR: case AVR_BUILTIN_ROUNDUR:
13163 case AVR_BUILTIN_ROUNDLR: case AVR_BUILTIN_ROUNDULR:
13164 case AVR_BUILTIN_ROUNDLLR: case AVR_BUILTIN_ROUNDULLR:
13165
13166 case AVR_BUILTIN_ROUNDHK: case AVR_BUILTIN_ROUNDUHK:
13167 case AVR_BUILTIN_ROUNDK: case AVR_BUILTIN_ROUNDUK:
13168 case AVR_BUILTIN_ROUNDLK: case AVR_BUILTIN_ROUNDULK:
13169 case AVR_BUILTIN_ROUNDLLK: case AVR_BUILTIN_ROUNDULLK:
13170
13171 /* Warn about odd rounding. Rounding points >= FBIT will have
13172 no effect. */
13173
13174 if (TREE_CODE (CALL_EXPR_ARG (exp, 1)) != INTEGER_CST)
13175 break;
13176
13177 int rbit = (int) TREE_INT_CST_LOW (CALL_EXPR_ARG (exp, 1));
13178
13179 if (rbit >= (int) GET_MODE_FBIT (mode))
13180 {
13181 warning (OPT_Wextra, "rounding to %d bits has no effect for "
13182 "fixed-point value with %d fractional bits",
13183 rbit, GET_MODE_FBIT (mode));
13184
13185 return expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX, mode,
13186 EXPAND_NORMAL);
13187 }
13188 else if (rbit <= - (int) GET_MODE_IBIT (mode))
13189 {
13190 warning (0, "rounding result will always be 0");
13191 return CONST0_RTX (mode);
13192 }
13193
13194 /* The rounding points RP satisfies now: -IBIT < RP < FBIT.
13195
13196 TR 18037 only specifies results for RP > 0. However, the
13197 remaining cases of -IBIT < RP <= 0 can easily be supported
13198 without any additional overhead. */
13199
13200 break; /* round */
13201 }
13202
13203 /* No fold found and no insn: Call support function from libgcc. */
13204
13205 if (d->icode == CODE_FOR_nothing
13206 && DECL_ASSEMBLER_NAME (get_callee_fndecl (exp)) != NULL_TREE)
13207 {
13208 return expand_call (exp, target, ignore);
13209 }
13210
13211 /* No special treatment needed: vanilla expand. */
13212
13213 gcc_assert (d->icode != CODE_FOR_nothing);
13214 gcc_assert (d->n_args == call_expr_nargs (exp));
13215
13216 if (d->n_args == 0)
13217 {
13218 emit_insn ((GEN_FCN (d->icode)) (target));
13219 return NULL_RTX;
13220 }
13221
13222 return avr_default_expand_builtin (d->icode, exp, target);
13223 }
13224
13225
13226 /* Helper for `avr_fold_builtin' that folds absfx (FIXED_CST). */
13227
13228 static tree
13229 avr_fold_absfx (tree tval)
13230 {
13231 if (FIXED_CST != TREE_CODE (tval))
13232 return NULL_TREE;
13233
13234 /* Our fixed-points have no padding: Use double_int payload directly. */
13235
13236 FIXED_VALUE_TYPE fval = TREE_FIXED_CST (tval);
13237 unsigned int bits = GET_MODE_BITSIZE (fval.mode);
13238 double_int ival = fval.data.sext (bits);
13239
13240 if (!ival.is_negative())
13241 return tval;
13242
13243 /* ISO/IEC TR 18037, 7.18a.6.2: The absfx functions are saturating. */
13244
13245 fval.data = (ival == double_int::min_value (bits, false).sext (bits))
13246 ? double_int::max_value (bits, false)
13247 : -ival;
13248
13249 return build_fixed (TREE_TYPE (tval), fval);
13250 }
13251
13252
13253 /* Implement `TARGET_FOLD_BUILTIN'. */
13254
13255 static tree
13256 avr_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg,
13257 bool ignore ATTRIBUTE_UNUSED)
13258 {
13259 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
13260 tree val_type = TREE_TYPE (TREE_TYPE (fndecl));
13261
13262 if (!optimize)
13263 return NULL_TREE;
13264
13265 switch (fcode)
13266 {
13267 default:
13268 break;
13269
13270 case AVR_BUILTIN_SWAP:
13271 {
13272 return fold_build2 (LROTATE_EXPR, val_type, arg[0],
13273 build_int_cst (val_type, 4));
13274 }
13275
13276 case AVR_BUILTIN_ABSHR:
13277 case AVR_BUILTIN_ABSR:
13278 case AVR_BUILTIN_ABSLR:
13279 case AVR_BUILTIN_ABSLLR:
13280
13281 case AVR_BUILTIN_ABSHK:
13282 case AVR_BUILTIN_ABSK:
13283 case AVR_BUILTIN_ABSLK:
13284 case AVR_BUILTIN_ABSLLK:
13285 /* GCC is not good with folding ABS for fixed-point. Do it by hand. */
13286
13287 return avr_fold_absfx (arg[0]);
13288
13289 case AVR_BUILTIN_BITSHR: case AVR_BUILTIN_HRBITS:
13290 case AVR_BUILTIN_BITSHK: case AVR_BUILTIN_HKBITS:
13291 case AVR_BUILTIN_BITSUHR: case AVR_BUILTIN_UHRBITS:
13292 case AVR_BUILTIN_BITSUHK: case AVR_BUILTIN_UHKBITS:
13293
13294 case AVR_BUILTIN_BITSR: case AVR_BUILTIN_RBITS:
13295 case AVR_BUILTIN_BITSK: case AVR_BUILTIN_KBITS:
13296 case AVR_BUILTIN_BITSUR: case AVR_BUILTIN_URBITS:
13297 case AVR_BUILTIN_BITSUK: case AVR_BUILTIN_UKBITS:
13298
13299 case AVR_BUILTIN_BITSLR: case AVR_BUILTIN_LRBITS:
13300 case AVR_BUILTIN_BITSLK: case AVR_BUILTIN_LKBITS:
13301 case AVR_BUILTIN_BITSULR: case AVR_BUILTIN_ULRBITS:
13302 case AVR_BUILTIN_BITSULK: case AVR_BUILTIN_ULKBITS:
13303
13304 case AVR_BUILTIN_BITSLLR: case AVR_BUILTIN_LLRBITS:
13305 case AVR_BUILTIN_BITSLLK: case AVR_BUILTIN_LLKBITS:
13306 case AVR_BUILTIN_BITSULLR: case AVR_BUILTIN_ULLRBITS:
13307 case AVR_BUILTIN_BITSULLK: case AVR_BUILTIN_ULLKBITS:
13308
13309 gcc_assert (TYPE_PRECISION (val_type)
13310 == TYPE_PRECISION (TREE_TYPE (arg[0])));
13311
13312 return build1 (VIEW_CONVERT_EXPR, val_type, arg[0]);
13313
13314 case AVR_BUILTIN_INSERT_BITS:
13315 {
13316 tree tbits = arg[1];
13317 tree tval = arg[2];
13318 tree tmap;
13319 tree map_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
13320 unsigned int map;
13321 bool changed = false;
13322 unsigned i;
13323 avr_map_op_t best_g;
13324
13325 if (TREE_CODE (arg[0]) != INTEGER_CST)
13326 {
13327 /* No constant as first argument: Don't fold this and run into
13328 error in avr_expand_builtin. */
13329
13330 break;
13331 }
13332
13333 tmap = wide_int_to_tree (map_type, arg[0]);
13334 map = TREE_INT_CST_LOW (tmap);
13335
13336 if (TREE_CODE (tval) != INTEGER_CST
13337 && 0 == avr_map_metric (map, MAP_MASK_PREIMAGE_F))
13338 {
13339 /* There are no F in the map, i.e. 3rd operand is unused.
13340 Replace that argument with some constant to render
13341 respective input unused. */
13342
13343 tval = build_int_cst (val_type, 0);
13344 changed = true;
13345 }
13346
13347 if (TREE_CODE (tbits) != INTEGER_CST
13348 && 0 == avr_map_metric (map, MAP_PREIMAGE_0_7))
13349 {
13350 /* Similar for the bits to be inserted. If they are unused,
13351 we can just as well pass 0. */
13352
13353 tbits = build_int_cst (val_type, 0);
13354 }
13355
13356 if (TREE_CODE (tbits) == INTEGER_CST)
13357 {
13358 /* Inserting bits known at compile time is easy and can be
13359 performed by AND and OR with appropriate masks. */
13360
13361 int bits = TREE_INT_CST_LOW (tbits);
13362 int mask_ior = 0, mask_and = 0xff;
13363
13364 for (i = 0; i < 8; i++)
13365 {
13366 int mi = avr_map (map, i);
13367
13368 if (mi < 8)
13369 {
13370 if (bits & (1 << mi)) mask_ior |= (1 << i);
13371 else mask_and &= ~(1 << i);
13372 }
13373 }
13374
13375 tval = fold_build2 (BIT_IOR_EXPR, val_type, tval,
13376 build_int_cst (val_type, mask_ior));
13377 return fold_build2 (BIT_AND_EXPR, val_type, tval,
13378 build_int_cst (val_type, mask_and));
13379 }
13380
13381 if (changed)
13382 return build_call_expr (fndecl, 3, tmap, tbits, tval);
13383
13384 /* If bits don't change their position we can use vanilla logic
13385 to merge the two arguments. */
13386
13387 if (0 == avr_map_metric (map, MAP_NONFIXED_0_7))
13388 {
13389 int mask_f = avr_map_metric (map, MAP_MASK_PREIMAGE_F);
13390 tree tres, tmask = build_int_cst (val_type, mask_f ^ 0xff);
13391
13392 tres = fold_build2 (BIT_XOR_EXPR, val_type, tbits, tval);
13393 tres = fold_build2 (BIT_AND_EXPR, val_type, tres, tmask);
13394 return fold_build2 (BIT_XOR_EXPR, val_type, tres, tval);
13395 }
13396
13397 /* Try to decomposing map to reduce overall cost. */
13398
13399 if (avr_log.builtin)
13400 avr_edump ("\n%?: %x\n%?: ROL cost: ", map);
13401
13402 best_g = avr_map_op[0];
13403 best_g.cost = 1000;
13404
13405 for (i = 0; i < sizeof (avr_map_op) / sizeof (*avr_map_op); i++)
13406 {
13407 avr_map_op_t g
13408 = avr_map_decompose (map, avr_map_op + i,
13409 TREE_CODE (tval) == INTEGER_CST);
13410
13411 if (g.cost >= 0 && g.cost < best_g.cost)
13412 best_g = g;
13413 }
13414
13415 if (avr_log.builtin)
13416 avr_edump ("\n");
13417
13418 if (best_g.arg == 0)
13419 /* No optimization found */
13420 break;
13421
13422 /* Apply operation G to the 2nd argument. */
13423
13424 if (avr_log.builtin)
13425 avr_edump ("%?: using OP(%s%d, %x) cost %d\n",
13426 best_g.str, best_g.arg, best_g.map, best_g.cost);
13427
13428 /* Do right-shifts arithmetically: They copy the MSB instead of
13429 shifting in a non-usable value (0) as with logic right-shift. */
13430
13431 tbits = fold_convert (signed_char_type_node, tbits);
13432 tbits = fold_build2 (best_g.code, signed_char_type_node, tbits,
13433 build_int_cst (val_type, best_g.arg));
13434 tbits = fold_convert (val_type, tbits);
13435
13436 /* Use map o G^-1 instead of original map to undo the effect of G. */
13437
13438 tmap = wide_int_to_tree (map_type, best_g.map);
13439
13440 return build_call_expr (fndecl, 3, tmap, tbits, tval);
13441 } /* AVR_BUILTIN_INSERT_BITS */
13442 }
13443
13444 return NULL_TREE;
13445 }
13446
13447 \f
13448
13449 /* Initialize the GCC target structure. */
13450
13451 #undef TARGET_ASM_ALIGNED_HI_OP
13452 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
13453 #undef TARGET_ASM_ALIGNED_SI_OP
13454 #define TARGET_ASM_ALIGNED_SI_OP "\t.long\t"
13455 #undef TARGET_ASM_UNALIGNED_HI_OP
13456 #define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
13457 #undef TARGET_ASM_UNALIGNED_SI_OP
13458 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
13459 #undef TARGET_ASM_INTEGER
13460 #define TARGET_ASM_INTEGER avr_assemble_integer
13461 #undef TARGET_ASM_FILE_START
13462 #define TARGET_ASM_FILE_START avr_file_start
13463 #undef TARGET_ASM_FILE_END
13464 #define TARGET_ASM_FILE_END avr_file_end
13465
13466 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
13467 #define TARGET_ASM_FUNCTION_END_PROLOGUE avr_asm_function_end_prologue
13468 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
13469 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE avr_asm_function_begin_epilogue
13470
13471 #undef TARGET_FUNCTION_VALUE
13472 #define TARGET_FUNCTION_VALUE avr_function_value
13473 #undef TARGET_LIBCALL_VALUE
13474 #define TARGET_LIBCALL_VALUE avr_libcall_value
13475 #undef TARGET_FUNCTION_VALUE_REGNO_P
13476 #define TARGET_FUNCTION_VALUE_REGNO_P avr_function_value_regno_p
13477
13478 #undef TARGET_ATTRIBUTE_TABLE
13479 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
13480 #undef TARGET_INSERT_ATTRIBUTES
13481 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
13482 #undef TARGET_SECTION_TYPE_FLAGS
13483 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
13484
13485 #undef TARGET_ASM_NAMED_SECTION
13486 #define TARGET_ASM_NAMED_SECTION avr_asm_named_section
13487 #undef TARGET_ASM_INIT_SECTIONS
13488 #define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections
13489 #undef TARGET_ENCODE_SECTION_INFO
13490 #define TARGET_ENCODE_SECTION_INFO avr_encode_section_info
13491 #undef TARGET_ASM_SELECT_SECTION
13492 #define TARGET_ASM_SELECT_SECTION avr_asm_select_section
13493
13494 #undef TARGET_REGISTER_MOVE_COST
13495 #define TARGET_REGISTER_MOVE_COST avr_register_move_cost
13496 #undef TARGET_MEMORY_MOVE_COST
13497 #define TARGET_MEMORY_MOVE_COST avr_memory_move_cost
13498 #undef TARGET_RTX_COSTS
13499 #define TARGET_RTX_COSTS avr_rtx_costs
13500 #undef TARGET_ADDRESS_COST
13501 #define TARGET_ADDRESS_COST avr_address_cost
13502 #undef TARGET_MACHINE_DEPENDENT_REORG
13503 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
13504 #undef TARGET_FUNCTION_ARG
13505 #define TARGET_FUNCTION_ARG avr_function_arg
13506 #undef TARGET_FUNCTION_ARG_ADVANCE
13507 #define TARGET_FUNCTION_ARG_ADVANCE avr_function_arg_advance
13508
13509 #undef TARGET_SET_CURRENT_FUNCTION
13510 #define TARGET_SET_CURRENT_FUNCTION avr_set_current_function
13511
13512 #undef TARGET_RETURN_IN_MEMORY
13513 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
13514
13515 #undef TARGET_STRICT_ARGUMENT_NAMING
13516 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
13517
13518 #undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
13519 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE avr_builtin_setjmp_frame_value
13520
13521 #undef TARGET_CONDITIONAL_REGISTER_USAGE
13522 #define TARGET_CONDITIONAL_REGISTER_USAGE avr_conditional_register_usage
13523
13524 #undef TARGET_HARD_REGNO_SCRATCH_OK
13525 #define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok
13526 #undef TARGET_CASE_VALUES_THRESHOLD
13527 #define TARGET_CASE_VALUES_THRESHOLD avr_case_values_threshold
13528
13529 #undef TARGET_FRAME_POINTER_REQUIRED
13530 #define TARGET_FRAME_POINTER_REQUIRED avr_frame_pointer_required_p
13531 #undef TARGET_CAN_ELIMINATE
13532 #define TARGET_CAN_ELIMINATE avr_can_eliminate
13533
13534 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
13535 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS avr_allocate_stack_slots_for_args
13536
13537 #undef TARGET_WARN_FUNC_RETURN
13538 #define TARGET_WARN_FUNC_RETURN avr_warn_func_return
13539
13540 #undef TARGET_CLASS_LIKELY_SPILLED_P
13541 #define TARGET_CLASS_LIKELY_SPILLED_P avr_class_likely_spilled_p
13542
13543 #undef TARGET_OPTION_OVERRIDE
13544 #define TARGET_OPTION_OVERRIDE avr_option_override
13545
13546 #undef TARGET_CANNOT_MODIFY_JUMPS_P
13547 #define TARGET_CANNOT_MODIFY_JUMPS_P avr_cannot_modify_jumps_p
13548
13549 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
13550 #define TARGET_FUNCTION_OK_FOR_SIBCALL avr_function_ok_for_sibcall
13551
13552 #undef TARGET_INIT_BUILTINS
13553 #define TARGET_INIT_BUILTINS avr_init_builtins
13554
13555 #undef TARGET_BUILTIN_DECL
13556 #define TARGET_BUILTIN_DECL avr_builtin_decl
13557
13558 #undef TARGET_EXPAND_BUILTIN
13559 #define TARGET_EXPAND_BUILTIN avr_expand_builtin
13560
13561 #undef TARGET_FOLD_BUILTIN
13562 #define TARGET_FOLD_BUILTIN avr_fold_builtin
13563
13564 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
13565 #define TARGET_ASM_FUNCTION_RODATA_SECTION avr_asm_function_rodata_section
13566
13567 #undef TARGET_SCALAR_MODE_SUPPORTED_P
13568 #define TARGET_SCALAR_MODE_SUPPORTED_P avr_scalar_mode_supported_p
13569
13570 #undef TARGET_BUILD_BUILTIN_VA_LIST
13571 #define TARGET_BUILD_BUILTIN_VA_LIST avr_build_builtin_va_list
13572
13573 #undef TARGET_FIXED_POINT_SUPPORTED_P
13574 #define TARGET_FIXED_POINT_SUPPORTED_P hook_bool_void_true
13575
13576 #undef TARGET_CONVERT_TO_TYPE
13577 #define TARGET_CONVERT_TO_TYPE avr_convert_to_type
13578
13579 #undef TARGET_ADDR_SPACE_SUBSET_P
13580 #define TARGET_ADDR_SPACE_SUBSET_P avr_addr_space_subset_p
13581
13582 #undef TARGET_ADDR_SPACE_CONVERT
13583 #define TARGET_ADDR_SPACE_CONVERT avr_addr_space_convert
13584
13585 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
13586 #define TARGET_ADDR_SPACE_ADDRESS_MODE avr_addr_space_address_mode
13587
13588 #undef TARGET_ADDR_SPACE_POINTER_MODE
13589 #define TARGET_ADDR_SPACE_POINTER_MODE avr_addr_space_pointer_mode
13590
13591 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
13592 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
13593 avr_addr_space_legitimate_address_p
13594
13595 #undef TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS
13596 #define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS avr_addr_space_legitimize_address
13597
13598 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
13599 #define TARGET_MODE_DEPENDENT_ADDRESS_P avr_mode_dependent_address_p
13600
13601 #undef TARGET_SECONDARY_RELOAD
13602 #define TARGET_SECONDARY_RELOAD avr_secondary_reload
13603
13604 #undef TARGET_PRINT_OPERAND
13605 #define TARGET_PRINT_OPERAND avr_print_operand
13606 #undef TARGET_PRINT_OPERAND_ADDRESS
13607 #define TARGET_PRINT_OPERAND_ADDRESS avr_print_operand_address
13608 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
13609 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P avr_print_operand_punct_valid_p
13610
13611 struct gcc_target targetm = TARGET_INITIALIZER;
13612
13613 \f
13614 #include "gt-avr.h"