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