include/:
[official-gcc.git] / gcc / config / avr / avr.c
blob1e79644fc2e05f593bc21b10b76496a45939d990
1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008,
3 2009 Free Software Foundation, Inc.
4 Contributed by Denis Chertykov (chertykov@gmail.com)
6 This file is part of GCC.
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 3, or (at your option)
11 any later version.
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.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "rtl.h"
27 #include "regs.h"
28 #include "hard-reg-set.h"
29 #include "real.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-attr.h"
33 #include "flags.h"
34 #include "reload.h"
35 #include "tree.h"
36 #include "output.h"
37 #include "expr.h"
38 #include "toplev.h"
39 #include "obstack.h"
40 #include "function.h"
41 #include "recog.h"
42 #include "ggc.h"
43 #include "tm_p.h"
44 #include "target.h"
45 #include "target-def.h"
46 #include "params.h"
47 #include "df.h"
49 /* Maximal allowed offset for an address in the LD command */
50 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
52 static int avr_naked_function_p (tree);
53 static int interrupt_function_p (tree);
54 static int signal_function_p (tree);
55 static int avr_OS_task_function_p (tree);
56 static int avr_OS_main_function_p (tree);
57 static int avr_regs_to_save (HARD_REG_SET *);
58 static int get_sequence_length (rtx insns);
59 static int sequent_regs_live (void);
60 static const char *ptrreg_to_str (int);
61 static const char *cond_string (enum rtx_code);
62 static int avr_num_arg_regs (enum machine_mode, tree);
64 static RTX_CODE compare_condition (rtx insn);
65 static rtx avr_legitimize_address (rtx, rtx, enum machine_mode);
66 static int compare_sign_p (rtx insn);
67 static tree avr_handle_progmem_attribute (tree *, tree, tree, int, bool *);
68 static tree avr_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
69 static tree avr_handle_fntype_attribute (tree *, tree, tree, int, bool *);
70 EXPORTED_CONST struct attribute_spec avr_attribute_table[];
71 static bool avr_assemble_integer (rtx, unsigned int, int);
72 static void avr_file_start (void);
73 static void avr_file_end (void);
74 static bool avr_legitimate_address_p (enum machine_mode, rtx, bool);
75 static void avr_asm_function_end_prologue (FILE *);
76 static void avr_asm_function_begin_epilogue (FILE *);
77 static rtx avr_function_value (const_tree, const_tree, bool);
78 static void avr_insert_attributes (tree, tree *);
79 static void avr_asm_init_sections (void);
80 static unsigned int avr_section_type_flags (tree, const char *, int);
82 static void avr_reorg (void);
83 static void avr_asm_out_ctor (rtx, int);
84 static void avr_asm_out_dtor (rtx, int);
85 static int avr_operand_rtx_cost (rtx, enum machine_mode, enum rtx_code, bool);
86 static bool avr_rtx_costs (rtx, int, int, int *, bool);
87 static int avr_address_cost (rtx, bool);
88 static bool avr_return_in_memory (const_tree, const_tree);
89 static struct machine_function * avr_init_machine_status (void);
90 static rtx avr_builtin_setjmp_frame_value (void);
91 static bool avr_hard_regno_scratch_ok (unsigned int);
92 static unsigned int avr_case_values_threshold (void);
94 /* Allocate registers from r25 to r8 for parameters for function calls. */
95 #define FIRST_CUM_REG 26
97 /* Temporary register RTX (gen_rtx_REG (QImode, TMP_REGNO)) */
98 static GTY(()) rtx tmp_reg_rtx;
100 /* Zeroed register RTX (gen_rtx_REG (QImode, ZERO_REGNO)) */
101 static GTY(()) rtx zero_reg_rtx;
103 /* AVR register names {"r0", "r1", ..., "r31"} */
104 static const char *const avr_regnames[] = REGISTER_NAMES;
106 /* This holds the last insn address. */
107 static int last_insn_address = 0;
109 /* Preprocessor macros to define depending on MCU type. */
110 const char *avr_extra_arch_macro;
112 /* Current architecture. */
113 const struct base_arch_s *avr_current_arch;
115 section *progmem_section;
117 static const struct base_arch_s avr_arch_types[] = {
118 { 1, 0, 0, 0, 0, 0, 0, 0, NULL }, /* unknown device specified */
119 { 1, 0, 0, 0, 0, 0, 0, 0, "__AVR_ARCH__=1" },
120 { 0, 0, 0, 0, 0, 0, 0, 0, "__AVR_ARCH__=2" },
121 { 0, 0, 0, 1, 0, 0, 0, 0, "__AVR_ARCH__=25" },
122 { 0, 0, 1, 0, 0, 0, 0, 0, "__AVR_ARCH__=3" },
123 { 0, 0, 1, 0, 1, 0, 0, 0, "__AVR_ARCH__=31" },
124 { 0, 0, 1, 1, 0, 0, 0, 0, "__AVR_ARCH__=35" },
125 { 0, 1, 0, 1, 0, 0, 0, 0, "__AVR_ARCH__=4" },
126 { 0, 1, 1, 1, 0, 0, 0, 0, "__AVR_ARCH__=5" },
127 { 0, 1, 1, 1, 1, 1, 0, 0, "__AVR_ARCH__=51" },
128 { 0, 1, 1, 1, 1, 1, 1, 0, "__AVR_ARCH__=6" }
131 /* These names are used as the index into the avr_arch_types[] table
132 above. */
134 enum avr_arch
136 ARCH_UNKNOWN,
137 ARCH_AVR1,
138 ARCH_AVR2,
139 ARCH_AVR25,
140 ARCH_AVR3,
141 ARCH_AVR31,
142 ARCH_AVR35,
143 ARCH_AVR4,
144 ARCH_AVR5,
145 ARCH_AVR51,
146 ARCH_AVR6
149 struct mcu_type_s {
150 const char *const name;
151 int arch; /* index in avr_arch_types[] */
152 /* Must lie outside user's namespace. NULL == no macro. */
153 const char *const macro;
156 /* List of all known AVR MCU types - if updated, it has to be kept
157 in sync in several places (FIXME: is there a better way?):
158 - here
159 - avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
160 - t-avr (MULTILIB_MATCHES)
161 - gas/config/tc-avr.c
162 - avr-libc */
164 static const struct mcu_type_s avr_mcu_types[] = {
165 /* Classic, <= 8K. */
166 { "avr2", ARCH_AVR2, NULL },
167 { "at90s2313", ARCH_AVR2, "__AVR_AT90S2313__" },
168 { "at90s2323", ARCH_AVR2, "__AVR_AT90S2323__" },
169 { "at90s2333", ARCH_AVR2, "__AVR_AT90S2333__" },
170 { "at90s2343", ARCH_AVR2, "__AVR_AT90S2343__" },
171 { "attiny22", ARCH_AVR2, "__AVR_ATtiny22__" },
172 { "attiny26", ARCH_AVR2, "__AVR_ATtiny26__" },
173 { "at90s4414", ARCH_AVR2, "__AVR_AT90S4414__" },
174 { "at90s4433", ARCH_AVR2, "__AVR_AT90S4433__" },
175 { "at90s4434", ARCH_AVR2, "__AVR_AT90S4434__" },
176 { "at90s8515", ARCH_AVR2, "__AVR_AT90S8515__" },
177 { "at90c8534", ARCH_AVR2, "__AVR_AT90C8534__" },
178 { "at90s8535", ARCH_AVR2, "__AVR_AT90S8535__" },
179 /* Classic + MOVW, <= 8K. */
180 { "avr25", ARCH_AVR25, NULL },
181 { "ata6289", ARCH_AVR25, "__AVR_ATA6289__" },
182 { "attiny13", ARCH_AVR25, "__AVR_ATtiny13__" },
183 { "attiny13a", ARCH_AVR25, "__AVR_ATtiny13A__" },
184 { "attiny2313", ARCH_AVR25, "__AVR_ATtiny2313__" },
185 { "attiny24", ARCH_AVR25, "__AVR_ATtiny24__" },
186 { "attiny44", ARCH_AVR25, "__AVR_ATtiny44__" },
187 { "attiny84", ARCH_AVR25, "__AVR_ATtiny84__" },
188 { "attiny25", ARCH_AVR25, "__AVR_ATtiny25__" },
189 { "attiny45", ARCH_AVR25, "__AVR_ATtiny45__" },
190 { "attiny85", ARCH_AVR25, "__AVR_ATtiny85__" },
191 { "attiny261", ARCH_AVR25, "__AVR_ATtiny261__" },
192 { "attiny461", ARCH_AVR25, "__AVR_ATtiny461__" },
193 { "attiny861", ARCH_AVR25, "__AVR_ATtiny861__" },
194 { "attiny43u", ARCH_AVR25, "__AVR_ATtiny43U__" },
195 { "attiny87", ARCH_AVR25, "__AVR_ATtiny87__" },
196 { "attiny48", ARCH_AVR25, "__AVR_ATtiny48__" },
197 { "attiny88", ARCH_AVR25, "__AVR_ATtiny88__" },
198 { "at86rf401", ARCH_AVR25, "__AVR_AT86RF401__" },
199 /* Classic, > 8K, <= 64K. */
200 { "avr3", ARCH_AVR3, NULL },
201 { "at43usb355", ARCH_AVR3, "__AVR_AT43USB355__" },
202 { "at76c711", ARCH_AVR3, "__AVR_AT76C711__" },
203 /* Classic, == 128K. */
204 { "avr31", ARCH_AVR31, NULL },
205 { "atmega103", ARCH_AVR31, "__AVR_ATmega103__" },
206 { "at43usb320", ARCH_AVR31, "__AVR_AT43USB320__" },
207 /* Classic + MOVW + JMP/CALL. */
208 { "avr35", ARCH_AVR35, NULL },
209 { "at90usb82", ARCH_AVR35, "__AVR_AT90USB82__" },
210 { "at90usb162", ARCH_AVR35, "__AVR_AT90USB162__" },
211 { "attiny167", ARCH_AVR35, "__AVR_ATtiny167__" },
212 { "attiny327", ARCH_AVR35, "__AVR_ATtiny327__" },
213 /* Enhanced, <= 8K. */
214 { "avr4", ARCH_AVR4, NULL },
215 { "atmega8", ARCH_AVR4, "__AVR_ATmega8__" },
216 { "atmega48", ARCH_AVR4, "__AVR_ATmega48__" },
217 { "atmega48p", ARCH_AVR4, "__AVR_ATmega48P__" },
218 { "atmega88", ARCH_AVR4, "__AVR_ATmega88__" },
219 { "atmega88p", ARCH_AVR4, "__AVR_ATmega88P__" },
220 { "atmega8515", ARCH_AVR4, "__AVR_ATmega8515__" },
221 { "atmega8535", ARCH_AVR4, "__AVR_ATmega8535__" },
222 { "atmega8hva", ARCH_AVR4, "__AVR_ATmega8HVA__" },
223 { "atmega4hvd", ARCH_AVR4, "__AVR_ATmega4HVD__" },
224 { "atmega8hvd", ARCH_AVR4, "__AVR_ATmega8HVD__" },
225 { "atmega8c1", ARCH_AVR4, "__AVR_ATmega8C1__" },
226 { "atmega8m1", ARCH_AVR4, "__AVR_ATmega8M1__" },
227 { "at90pwm1", ARCH_AVR4, "__AVR_AT90PWM1__" },
228 { "at90pwm2", ARCH_AVR4, "__AVR_AT90PWM2__" },
229 { "at90pwm2b", ARCH_AVR4, "__AVR_AT90PWM2B__" },
230 { "at90pwm3", ARCH_AVR4, "__AVR_AT90PWM3__" },
231 { "at90pwm3b", ARCH_AVR4, "__AVR_AT90PWM3B__" },
232 { "at90pwm81", ARCH_AVR4, "__AVR_AT90PWM81__" },
233 /* Enhanced, > 8K, <= 64K. */
234 { "avr5", ARCH_AVR5, NULL },
235 { "atmega16", ARCH_AVR5, "__AVR_ATmega16__" },
236 { "atmega161", ARCH_AVR5, "__AVR_ATmega161__" },
237 { "atmega162", ARCH_AVR5, "__AVR_ATmega162__" },
238 { "atmega163", ARCH_AVR5, "__AVR_ATmega163__" },
239 { "atmega164p", ARCH_AVR5, "__AVR_ATmega164P__" },
240 { "atmega165", ARCH_AVR5, "__AVR_ATmega165__" },
241 { "atmega165p", ARCH_AVR5, "__AVR_ATmega165P__" },
242 { "atmega168", ARCH_AVR5, "__AVR_ATmega168__" },
243 { "atmega168p", ARCH_AVR5, "__AVR_ATmega168P__" },
244 { "atmega169", ARCH_AVR5, "__AVR_ATmega169__" },
245 { "atmega169p", ARCH_AVR5, "__AVR_ATmega169P__" },
246 { "atmega32", ARCH_AVR5, "__AVR_ATmega32__" },
247 { "atmega323", ARCH_AVR5, "__AVR_ATmega323__" },
248 { "atmega324p", ARCH_AVR5, "__AVR_ATmega324P__" },
249 { "atmega325", ARCH_AVR5, "__AVR_ATmega325__" },
250 { "atmega325p", ARCH_AVR5, "__AVR_ATmega325P__" },
251 { "atmega3250", ARCH_AVR5, "__AVR_ATmega3250__" },
252 { "atmega3250p", ARCH_AVR5, "__AVR_ATmega3250P__" },
253 { "atmega328p", ARCH_AVR5, "__AVR_ATmega328P__" },
254 { "atmega329", ARCH_AVR5, "__AVR_ATmega329__" },
255 { "atmega329p", ARCH_AVR5, "__AVR_ATmega329P__" },
256 { "atmega3290", ARCH_AVR5, "__AVR_ATmega3290__" },
257 { "atmega3290p", ARCH_AVR5, "__AVR_ATmega3290P__" },
258 { "atmega406", ARCH_AVR5, "__AVR_ATmega406__" },
259 { "atmega64", ARCH_AVR5, "__AVR_ATmega64__" },
260 { "atmega640", ARCH_AVR5, "__AVR_ATmega640__" },
261 { "atmega644", ARCH_AVR5, "__AVR_ATmega644__" },
262 { "atmega644p", ARCH_AVR5, "__AVR_ATmega644P__" },
263 { "atmega645", ARCH_AVR5, "__AVR_ATmega645__" },
264 { "atmega6450", ARCH_AVR5, "__AVR_ATmega6450__" },
265 { "atmega649", ARCH_AVR5, "__AVR_ATmega649__" },
266 { "atmega6490", ARCH_AVR5, "__AVR_ATmega6490__" },
267 { "atmega16hva", ARCH_AVR5, "__AVR_ATmega16HVA__" },
268 { "atmega16hvb", ARCH_AVR5, "__AVR_ATmega16HVB__" },
269 { "atmega32hvb", ARCH_AVR5, "__AVR_ATmega32HVB__" },
270 { "at90can32", ARCH_AVR5, "__AVR_AT90CAN32__" },
271 { "at90can64", ARCH_AVR5, "__AVR_AT90CAN64__" },
272 { "at90pwm216", ARCH_AVR5, "__AVR_AT90PWM216__" },
273 { "at90pwm316", ARCH_AVR5, "__AVR_AT90PWM316__" },
274 { "atmega16c1", ARCH_AVR5, "__AVR_ATmega16C1__" },
275 { "atmega32c1", ARCH_AVR5, "__AVR_ATmega32C1__" },
276 { "atmega64c1", ARCH_AVR5, "__AVR_ATmega64C1__" },
277 { "atmega16m1", ARCH_AVR5, "__AVR_ATmega16M1__" },
278 { "atmega32m1", ARCH_AVR5, "__AVR_ATmega32M1__" },
279 { "atmega64m1", ARCH_AVR5, "__AVR_ATmega64M1__" },
280 { "atmega16u4", ARCH_AVR5, "__AVR_ATmega16U4__" },
281 { "atmega32u4", ARCH_AVR5, "__AVR_ATmega32U4__" },
282 { "atmega32u6", ARCH_AVR5, "__AVR_ATmega32U6__" },
283 { "at90scr100", ARCH_AVR5, "__AVR_AT90SCR100__" },
284 { "at90usb646", ARCH_AVR5, "__AVR_AT90USB646__" },
285 { "at90usb647", ARCH_AVR5, "__AVR_AT90USB647__" },
286 { "at94k", ARCH_AVR5, "__AVR_AT94K__" },
287 /* Enhanced, == 128K. */
288 { "avr51", ARCH_AVR51, NULL },
289 { "atmega128", ARCH_AVR51, "__AVR_ATmega128__" },
290 { "atmega1280", ARCH_AVR51, "__AVR_ATmega1280__" },
291 { "atmega1281", ARCH_AVR51, "__AVR_ATmega1281__" },
292 { "atmega1284p", ARCH_AVR51, "__AVR_ATmega1284P__" },
293 { "atmega128rfa1", ARCH_AVR51, "__AVR_ATmega128RFA1__" },
294 { "at90can128", ARCH_AVR51, "__AVR_AT90CAN128__" },
295 { "at90usb1286", ARCH_AVR51, "__AVR_AT90USB1286__" },
296 { "at90usb1287", ARCH_AVR51, "__AVR_AT90USB1287__" },
297 { "m3000f", ARCH_AVR51, "__AVR_M3000F__" },
298 { "m3000s", ARCH_AVR51, "__AVR_M3000S__" },
299 { "m3001b", ARCH_AVR51, "__AVR_M3001B__" },
300 /* 3-Byte PC. */
301 { "avr6", ARCH_AVR6, NULL },
302 { "atmega2560", ARCH_AVR6, "__AVR_ATmega2560__" },
303 { "atmega2561", ARCH_AVR6, "__AVR_ATmega2561__" },
304 /* Assembler only. */
305 { "avr1", ARCH_AVR1, NULL },
306 { "at90s1200", ARCH_AVR1, "__AVR_AT90S1200__" },
307 { "attiny11", ARCH_AVR1, "__AVR_ATtiny11__" },
308 { "attiny12", ARCH_AVR1, "__AVR_ATtiny12__" },
309 { "attiny15", ARCH_AVR1, "__AVR_ATtiny15__" },
310 { "attiny28", ARCH_AVR1, "__AVR_ATtiny28__" },
311 { NULL, ARCH_UNKNOWN, NULL }
315 /* Initialize the GCC target structure. */
316 #undef TARGET_ASM_ALIGNED_HI_OP
317 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
318 #undef TARGET_ASM_ALIGNED_SI_OP
319 #define TARGET_ASM_ALIGNED_SI_OP "\t.long\t"
320 #undef TARGET_ASM_UNALIGNED_HI_OP
321 #define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
322 #undef TARGET_ASM_UNALIGNED_SI_OP
323 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
324 #undef TARGET_ASM_INTEGER
325 #define TARGET_ASM_INTEGER avr_assemble_integer
326 #undef TARGET_ASM_FILE_START
327 #define TARGET_ASM_FILE_START avr_file_start
328 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
329 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
330 #undef TARGET_ASM_FILE_END
331 #define TARGET_ASM_FILE_END avr_file_end
333 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
334 #define TARGET_ASM_FUNCTION_END_PROLOGUE avr_asm_function_end_prologue
335 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
336 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE avr_asm_function_begin_epilogue
337 #undef TARGET_FUNCTION_VALUE
338 #define TARGET_FUNCTION_VALUE avr_function_value
339 #undef TARGET_ATTRIBUTE_TABLE
340 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
341 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
342 #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
343 #undef TARGET_INSERT_ATTRIBUTES
344 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
345 #undef TARGET_SECTION_TYPE_FLAGS
346 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
347 #undef TARGET_RTX_COSTS
348 #define TARGET_RTX_COSTS avr_rtx_costs
349 #undef TARGET_ADDRESS_COST
350 #define TARGET_ADDRESS_COST avr_address_cost
351 #undef TARGET_MACHINE_DEPENDENT_REORG
352 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
354 #undef TARGET_LEGITIMIZE_ADDRESS
355 #define TARGET_LEGITIMIZE_ADDRESS avr_legitimize_address
357 #undef TARGET_RETURN_IN_MEMORY
358 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
360 #undef TARGET_STRICT_ARGUMENT_NAMING
361 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
363 #undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
364 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE avr_builtin_setjmp_frame_value
366 #undef TARGET_HARD_REGNO_SCRATCH_OK
367 #define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok
368 #undef TARGET_CASE_VALUES_THRESHOLD
369 #define TARGET_CASE_VALUES_THRESHOLD avr_case_values_threshold
371 #undef TARGET_LEGITIMATE_ADDRESS_P
372 #define TARGET_LEGITIMATE_ADDRESS_P avr_legitimate_address_p
374 struct gcc_target targetm = TARGET_INITIALIZER;
376 void
377 avr_override_options (void)
379 const struct mcu_type_s *t;
381 flag_delete_null_pointer_checks = 0;
383 if (!PARAM_SET_P (PARAM_INLINE_CALL_COST))
384 set_param_value ("inline-call-cost", 5);
386 for (t = avr_mcu_types; t->name; t++)
387 if (strcmp (t->name, avr_mcu_name) == 0)
388 break;
390 if (!t->name)
392 fprintf (stderr, "unknown MCU '%s' specified\nKnown MCU names:\n",
393 avr_mcu_name);
394 for (t = avr_mcu_types; t->name; t++)
395 fprintf (stderr," %s\n", t->name);
398 avr_current_arch = &avr_arch_types[t->arch];
399 avr_extra_arch_macro = t->macro;
401 tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO);
402 zero_reg_rtx = gen_rtx_REG (QImode, ZERO_REGNO);
404 init_machine_status = avr_init_machine_status;
407 /* return register class from register number. */
409 static const int reg_class_tab[]={
410 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
411 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
412 GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
413 GENERAL_REGS, /* r0 - r15 */
414 LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
415 LD_REGS, /* r16 - 23 */
416 ADDW_REGS,ADDW_REGS, /* r24,r25 */
417 POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
418 POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
419 POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
420 STACK_REG,STACK_REG /* SPL,SPH */
423 /* Function to set up the backend function structure. */
425 static struct machine_function *
426 avr_init_machine_status (void)
428 return ((struct machine_function *)
429 ggc_alloc_cleared (sizeof (struct machine_function)));
432 /* Return register class for register R. */
434 enum reg_class
435 avr_regno_reg_class (int r)
437 if (r <= 33)
438 return reg_class_tab[r];
439 return ALL_REGS;
442 /* Return nonzero if FUNC is a naked function. */
444 static int
445 avr_naked_function_p (tree func)
447 tree a;
449 gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
451 a = lookup_attribute ("naked", TYPE_ATTRIBUTES (TREE_TYPE (func)));
452 return a != NULL_TREE;
455 /* Return nonzero if FUNC is an interrupt function as specified
456 by the "interrupt" attribute. */
458 static int
459 interrupt_function_p (tree func)
461 tree a;
463 if (TREE_CODE (func) != FUNCTION_DECL)
464 return 0;
466 a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
467 return a != NULL_TREE;
470 /* Return nonzero if FUNC is a signal function as specified
471 by the "signal" attribute. */
473 static int
474 signal_function_p (tree func)
476 tree a;
478 if (TREE_CODE (func) != FUNCTION_DECL)
479 return 0;
481 a = lookup_attribute ("signal", DECL_ATTRIBUTES (func));
482 return a != NULL_TREE;
485 /* Return nonzero if FUNC is a OS_task function. */
487 static int
488 avr_OS_task_function_p (tree func)
490 tree a;
492 gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
494 a = lookup_attribute ("OS_task", TYPE_ATTRIBUTES (TREE_TYPE (func)));
495 return a != NULL_TREE;
498 /* Return nonzero if FUNC is a OS_main function. */
500 static int
501 avr_OS_main_function_p (tree func)
503 tree a;
505 gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
507 a = lookup_attribute ("OS_main", TYPE_ATTRIBUTES (TREE_TYPE (func)));
508 return a != NULL_TREE;
511 /* Return the number of hard registers to push/pop in the prologue/epilogue
512 of the current function, and optionally store these registers in SET. */
514 static int
515 avr_regs_to_save (HARD_REG_SET *set)
517 int reg, count;
518 int int_or_sig_p = (interrupt_function_p (current_function_decl)
519 || signal_function_p (current_function_decl));
521 if (!reload_completed)
522 cfun->machine->is_leaf = leaf_function_p ();
524 if (set)
525 CLEAR_HARD_REG_SET (*set);
526 count = 0;
528 /* No need to save any registers if the function never returns or
529 is have "OS_task" or "OS_main" attribute. */
530 if (TREE_THIS_VOLATILE (current_function_decl)
531 || cfun->machine->is_OS_task
532 || cfun->machine->is_OS_main)
533 return 0;
535 for (reg = 0; reg < 32; reg++)
537 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
538 any global register variables. */
539 if (fixed_regs[reg])
540 continue;
542 if ((int_or_sig_p && !cfun->machine->is_leaf && call_used_regs[reg])
543 || (df_regs_ever_live_p (reg)
544 && (int_or_sig_p || !call_used_regs[reg])
545 && !(frame_pointer_needed
546 && (reg == REG_Y || reg == (REG_Y+1)))))
548 if (set)
549 SET_HARD_REG_BIT (*set, reg);
550 count++;
553 return count;
556 /* Return true if register FROM can be eliminated via register TO. */
558 bool
559 avr_can_eliminate (int from, int to)
561 return ((from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
562 || ((from == FRAME_POINTER_REGNUM
563 || from == FRAME_POINTER_REGNUM + 1)
564 && !frame_pointer_needed));
567 /* Compute offset between arg_pointer and frame_pointer. */
570 avr_initial_elimination_offset (int from, int to)
572 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
573 return 0;
574 else
576 int offset = frame_pointer_needed ? 2 : 0;
577 int avr_pc_size = AVR_HAVE_EIJMP_EICALL ? 3 : 2;
579 offset += avr_regs_to_save (NULL);
580 return get_frame_size () + (avr_pc_size) + 1 + offset;
584 /* Actual start of frame is virtual_stack_vars_rtx this is offset from
585 frame pointer by +STARTING_FRAME_OFFSET.
586 Using saved frame = virtual_stack_vars_rtx - STARTING_FRAME_OFFSET
587 avoids creating add/sub of offset in nonlocal goto and setjmp. */
589 rtx avr_builtin_setjmp_frame_value (void)
591 return gen_rtx_MINUS (Pmode, virtual_stack_vars_rtx,
592 gen_int_mode (STARTING_FRAME_OFFSET, Pmode));
595 /* Return 1 if the function epilogue is just a single "ret". */
598 avr_simple_epilogue (void)
600 return (! frame_pointer_needed
601 && get_frame_size () == 0
602 && avr_regs_to_save (NULL) == 0
603 && ! interrupt_function_p (current_function_decl)
604 && ! signal_function_p (current_function_decl)
605 && ! avr_naked_function_p (current_function_decl)
606 && ! TREE_THIS_VOLATILE (current_function_decl));
609 /* This function checks sequence of live registers. */
611 static int
612 sequent_regs_live (void)
614 int reg;
615 int live_seq=0;
616 int cur_seq=0;
618 for (reg = 0; reg < 18; ++reg)
620 if (!call_used_regs[reg])
622 if (df_regs_ever_live_p (reg))
624 ++live_seq;
625 ++cur_seq;
627 else
628 cur_seq = 0;
632 if (!frame_pointer_needed)
634 if (df_regs_ever_live_p (REG_Y))
636 ++live_seq;
637 ++cur_seq;
639 else
640 cur_seq = 0;
642 if (df_regs_ever_live_p (REG_Y+1))
644 ++live_seq;
645 ++cur_seq;
647 else
648 cur_seq = 0;
650 else
652 cur_seq += 2;
653 live_seq += 2;
655 return (cur_seq == live_seq) ? live_seq : 0;
658 /* Obtain the length sequence of insns. */
661 get_sequence_length (rtx insns)
663 rtx insn;
664 int length;
666 for (insn = insns, length = 0; insn; insn = NEXT_INSN (insn))
667 length += get_attr_length (insn);
669 return length;
672 /* Output function prologue. */
674 void
675 expand_prologue (void)
677 int live_seq;
678 HARD_REG_SET set;
679 int minimize;
680 HOST_WIDE_INT size = get_frame_size();
681 /* Define templates for push instructions. */
682 rtx pushbyte = gen_rtx_MEM (QImode,
683 gen_rtx_POST_DEC (HImode, stack_pointer_rtx));
684 rtx pushword = gen_rtx_MEM (HImode,
685 gen_rtx_POST_DEC (HImode, stack_pointer_rtx));
686 rtx insn;
688 last_insn_address = 0;
690 /* Init cfun->machine. */
691 cfun->machine->is_naked = avr_naked_function_p (current_function_decl);
692 cfun->machine->is_interrupt = interrupt_function_p (current_function_decl);
693 cfun->machine->is_signal = signal_function_p (current_function_decl);
694 cfun->machine->is_OS_task = avr_OS_task_function_p (current_function_decl);
695 cfun->machine->is_OS_main = avr_OS_main_function_p (current_function_decl);
697 /* Prologue: naked. */
698 if (cfun->machine->is_naked)
700 return;
703 avr_regs_to_save (&set);
704 live_seq = sequent_regs_live ();
705 minimize = (TARGET_CALL_PROLOGUES
706 && !cfun->machine->is_interrupt
707 && !cfun->machine->is_signal
708 && !cfun->machine->is_OS_task
709 && !cfun->machine->is_OS_main
710 && live_seq);
712 if (cfun->machine->is_interrupt || cfun->machine->is_signal)
714 if (cfun->machine->is_interrupt)
716 /* Enable interrupts. */
717 insn = emit_insn (gen_enable_interrupt ());
718 RTX_FRAME_RELATED_P (insn) = 1;
721 /* Push zero reg. */
722 insn = emit_move_insn (pushbyte, zero_reg_rtx);
723 RTX_FRAME_RELATED_P (insn) = 1;
725 /* Push tmp reg. */
726 insn = emit_move_insn (pushbyte, tmp_reg_rtx);
727 RTX_FRAME_RELATED_P (insn) = 1;
729 /* Push SREG. */
730 insn = emit_move_insn (tmp_reg_rtx,
731 gen_rtx_MEM (QImode, GEN_INT (SREG_ADDR)));
732 RTX_FRAME_RELATED_P (insn) = 1;
733 insn = emit_move_insn (pushbyte, tmp_reg_rtx);
734 RTX_FRAME_RELATED_P (insn) = 1;
736 /* Push RAMPZ. */
737 if(AVR_HAVE_RAMPZ
738 && (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1)))
740 insn = emit_move_insn (tmp_reg_rtx,
741 gen_rtx_MEM (QImode, GEN_INT (RAMPZ_ADDR)));
742 RTX_FRAME_RELATED_P (insn) = 1;
743 insn = emit_move_insn (pushbyte, tmp_reg_rtx);
744 RTX_FRAME_RELATED_P (insn) = 1;
747 /* Clear zero reg. */
748 insn = emit_move_insn (zero_reg_rtx, const0_rtx);
749 RTX_FRAME_RELATED_P (insn) = 1;
751 /* Prevent any attempt to delete the setting of ZERO_REG! */
752 emit_use (zero_reg_rtx);
754 if (minimize && (frame_pointer_needed
755 || (AVR_2_BYTE_PC && live_seq > 6)
756 || live_seq > 7))
758 insn = emit_move_insn (gen_rtx_REG (HImode, REG_X),
759 gen_int_mode (size, HImode));
760 RTX_FRAME_RELATED_P (insn) = 1;
762 insn =
763 emit_insn (gen_call_prologue_saves (gen_int_mode (live_seq, HImode),
764 gen_int_mode (size + live_seq, HImode)));
765 RTX_FRAME_RELATED_P (insn) = 1;
767 else
769 int reg;
770 for (reg = 0; reg < 32; ++reg)
772 if (TEST_HARD_REG_BIT (set, reg))
774 /* Emit push of register to save. */
775 insn=emit_move_insn (pushbyte, gen_rtx_REG (QImode, reg));
776 RTX_FRAME_RELATED_P (insn) = 1;
779 if (frame_pointer_needed)
781 if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
783 /* Push frame pointer. */
784 insn = emit_move_insn (pushword, frame_pointer_rtx);
785 RTX_FRAME_RELATED_P (insn) = 1;
788 if (!size)
790 insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
791 RTX_FRAME_RELATED_P (insn) = 1;
793 else
795 /* Creating a frame can be done by direct manipulation of the
796 stack or via the frame pointer. These two methods are:
797 fp=sp
798 fp-=size
799 sp=fp
801 sp-=size
802 fp=sp
803 the optimum method depends on function type, stack and frame size.
804 To avoid a complex logic, both methods are tested and shortest
805 is selected. */
806 rtx myfp;
807 rtx fp_plus_insns;
808 rtx sp_plus_insns = NULL_RTX;
810 if (TARGET_TINY_STACK)
812 /* The high byte (r29) doesn't change - prefer 'subi' (1 cycle)
813 over 'sbiw' (2 cycles, same size). */
814 myfp = gen_rtx_REG (QImode, REGNO (frame_pointer_rtx));
816 else
818 /* Normal sized addition. */
819 myfp = frame_pointer_rtx;
822 /* Method 1-Adjust frame pointer. */
823 start_sequence ();
825 insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
826 RTX_FRAME_RELATED_P (insn) = 1;
828 insn =
829 emit_move_insn (myfp,
830 gen_rtx_PLUS (GET_MODE(myfp), myfp,
831 gen_int_mode (-size,
832 GET_MODE(myfp))));
833 RTX_FRAME_RELATED_P (insn) = 1;
835 /* Copy to stack pointer. */
836 if (TARGET_TINY_STACK)
838 insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
839 RTX_FRAME_RELATED_P (insn) = 1;
841 else if (TARGET_NO_INTERRUPTS
842 || cfun->machine->is_signal
843 || cfun->machine->is_OS_main)
845 insn =
846 emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx,
847 frame_pointer_rtx));
848 RTX_FRAME_RELATED_P (insn) = 1;
850 else if (cfun->machine->is_interrupt)
852 insn = emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx,
853 frame_pointer_rtx));
854 RTX_FRAME_RELATED_P (insn) = 1;
856 else
858 insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
859 RTX_FRAME_RELATED_P (insn) = 1;
862 fp_plus_insns = get_insns ();
863 end_sequence ();
865 /* Method 2-Adjust Stack pointer. */
866 if (size <= 6)
868 start_sequence ();
870 insn =
871 emit_move_insn (stack_pointer_rtx,
872 gen_rtx_PLUS (HImode,
873 stack_pointer_rtx,
874 gen_int_mode (-size,
875 HImode)));
876 RTX_FRAME_RELATED_P (insn) = 1;
878 insn =
879 emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
880 RTX_FRAME_RELATED_P (insn) = 1;
882 sp_plus_insns = get_insns ();
883 end_sequence ();
886 /* Use shortest method. */
887 if (size <= 6 && (get_sequence_length (sp_plus_insns)
888 < get_sequence_length (fp_plus_insns)))
889 emit_insn (sp_plus_insns);
890 else
891 emit_insn (fp_plus_insns);
897 /* Output summary at end of function prologue. */
899 static void
900 avr_asm_function_end_prologue (FILE *file)
902 if (cfun->machine->is_naked)
904 fputs ("/* prologue: naked */\n", file);
906 else
908 if (cfun->machine->is_interrupt)
910 fputs ("/* prologue: Interrupt */\n", file);
912 else if (cfun->machine->is_signal)
914 fputs ("/* prologue: Signal */\n", file);
916 else
917 fputs ("/* prologue: function */\n", file);
919 fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n",
920 get_frame_size());
924 /* Implement EPILOGUE_USES. */
927 avr_epilogue_uses (int regno ATTRIBUTE_UNUSED)
929 if (reload_completed
930 && cfun->machine
931 && (cfun->machine->is_interrupt || cfun->machine->is_signal))
932 return 1;
933 return 0;
936 /* Output RTL epilogue. */
938 void
939 expand_epilogue (void)
941 int reg;
942 int live_seq;
943 HARD_REG_SET set;
944 int minimize;
945 HOST_WIDE_INT size = get_frame_size();
947 /* epilogue: naked */
948 if (cfun->machine->is_naked)
950 emit_jump_insn (gen_return ());
951 return;
954 avr_regs_to_save (&set);
955 live_seq = sequent_regs_live ();
956 minimize = (TARGET_CALL_PROLOGUES
957 && !cfun->machine->is_interrupt
958 && !cfun->machine->is_signal
959 && !cfun->machine->is_OS_task
960 && !cfun->machine->is_OS_main
961 && live_seq);
963 if (minimize && (frame_pointer_needed || live_seq > 4))
965 if (frame_pointer_needed)
967 /* Get rid of frame. */
968 emit_move_insn(frame_pointer_rtx,
969 gen_rtx_PLUS (HImode, frame_pointer_rtx,
970 gen_int_mode (size, HImode)));
972 else
974 emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
977 emit_insn (gen_epilogue_restores (gen_int_mode (live_seq, HImode)));
979 else
981 if (frame_pointer_needed)
983 if (size)
985 /* Try two methods to adjust stack and select shortest. */
986 rtx myfp;
987 rtx fp_plus_insns;
988 rtx sp_plus_insns = NULL_RTX;
990 if (TARGET_TINY_STACK)
992 /* The high byte (r29) doesn't change - prefer 'subi'
993 (1 cycle) over 'sbiw' (2 cycles, same size). */
994 myfp = gen_rtx_REG (QImode, REGNO (frame_pointer_rtx));
996 else
998 /* Normal sized addition. */
999 myfp = frame_pointer_rtx;
1002 /* Method 1-Adjust frame pointer. */
1003 start_sequence ();
1005 emit_move_insn (myfp,
1006 gen_rtx_PLUS (HImode, myfp,
1007 gen_int_mode (size,
1008 GET_MODE(myfp))));
1010 /* Copy to stack pointer. */
1011 if (TARGET_TINY_STACK)
1013 emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
1015 else if (TARGET_NO_INTERRUPTS
1016 || cfun->machine->is_signal)
1018 emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx,
1019 frame_pointer_rtx));
1021 else if (cfun->machine->is_interrupt)
1023 emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx,
1024 frame_pointer_rtx));
1026 else
1028 emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
1031 fp_plus_insns = get_insns ();
1032 end_sequence ();
1034 /* Method 2-Adjust Stack pointer. */
1035 if (size <= 5)
1037 start_sequence ();
1039 emit_move_insn (stack_pointer_rtx,
1040 gen_rtx_PLUS (HImode, stack_pointer_rtx,
1041 gen_int_mode (size,
1042 HImode)));
1044 sp_plus_insns = get_insns ();
1045 end_sequence ();
1048 /* Use shortest method. */
1049 if (size <= 5 && (get_sequence_length (sp_plus_insns)
1050 < get_sequence_length (fp_plus_insns)))
1051 emit_insn (sp_plus_insns);
1052 else
1053 emit_insn (fp_plus_insns);
1055 if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
1057 /* Restore previous frame_pointer. */
1058 emit_insn (gen_pophi (frame_pointer_rtx));
1061 /* Restore used registers. */
1062 for (reg = 31; reg >= 0; --reg)
1064 if (TEST_HARD_REG_BIT (set, reg))
1065 emit_insn (gen_popqi (gen_rtx_REG (QImode, reg)));
1067 if (cfun->machine->is_interrupt || cfun->machine->is_signal)
1069 /* Restore RAMPZ using tmp reg as scratch. */
1070 if(AVR_HAVE_RAMPZ
1071 && (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1)))
1073 emit_insn (gen_popqi (tmp_reg_rtx));
1074 emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(RAMPZ_ADDR)),
1075 tmp_reg_rtx);
1078 /* Restore SREG using tmp reg as scratch. */
1079 emit_insn (gen_popqi (tmp_reg_rtx));
1081 emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(SREG_ADDR)),
1082 tmp_reg_rtx);
1084 /* Restore tmp REG. */
1085 emit_insn (gen_popqi (tmp_reg_rtx));
1087 /* Restore zero REG. */
1088 emit_insn (gen_popqi (zero_reg_rtx));
1091 emit_jump_insn (gen_return ());
1095 /* Output summary messages at beginning of function epilogue. */
1097 static void
1098 avr_asm_function_begin_epilogue (FILE *file)
1100 fprintf (file, "/* epilogue start */\n");
1103 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
1104 machine for a memory operand of mode MODE. */
1106 bool
1107 avr_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
1109 enum reg_class r = NO_REGS;
1111 if (TARGET_ALL_DEBUG)
1113 fprintf (stderr, "mode: (%s) %s %s %s %s:",
1114 GET_MODE_NAME(mode),
1115 strict ? "(strict)": "",
1116 reload_completed ? "(reload_completed)": "",
1117 reload_in_progress ? "(reload_in_progress)": "",
1118 reg_renumber ? "(reg_renumber)" : "");
1119 if (GET_CODE (x) == PLUS
1120 && REG_P (XEXP (x, 0))
1121 && GET_CODE (XEXP (x, 1)) == CONST_INT
1122 && INTVAL (XEXP (x, 1)) >= 0
1123 && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
1124 && reg_renumber
1126 fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
1127 true_regnum (XEXP (x, 0)));
1128 debug_rtx (x);
1130 if (!strict && GET_CODE (x) == SUBREG)
1131 x = SUBREG_REG (x);
1132 if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
1133 : REG_OK_FOR_BASE_NOSTRICT_P (x)))
1134 r = POINTER_REGS;
1135 else if (CONSTANT_ADDRESS_P (x))
1136 r = ALL_REGS;
1137 else if (GET_CODE (x) == PLUS
1138 && REG_P (XEXP (x, 0))
1139 && GET_CODE (XEXP (x, 1)) == CONST_INT
1140 && INTVAL (XEXP (x, 1)) >= 0)
1142 int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
1143 if (fit)
1145 if (! strict
1146 || REGNO (XEXP (x,0)) == REG_X
1147 || REGNO (XEXP (x,0)) == REG_Y
1148 || REGNO (XEXP (x,0)) == REG_Z)
1149 r = BASE_POINTER_REGS;
1150 if (XEXP (x,0) == frame_pointer_rtx
1151 || XEXP (x,0) == arg_pointer_rtx)
1152 r = BASE_POINTER_REGS;
1154 else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
1155 r = POINTER_Y_REGS;
1157 else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
1158 && REG_P (XEXP (x, 0))
1159 && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
1160 : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
1162 r = POINTER_REGS;
1164 if (TARGET_ALL_DEBUG)
1166 fprintf (stderr, " ret = %c\n", r + '0');
1168 return r == NO_REGS ? 0 : (int)r;
1171 /* Attempts to replace X with a valid
1172 memory address for an operand of mode MODE */
1175 avr_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
1177 x = oldx;
1178 if (TARGET_ALL_DEBUG)
1180 fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
1181 debug_rtx (oldx);
1184 if (GET_CODE (oldx) == PLUS
1185 && REG_P (XEXP (oldx,0)))
1187 if (REG_P (XEXP (oldx,1)))
1188 x = force_reg (GET_MODE (oldx), oldx);
1189 else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
1191 int offs = INTVAL (XEXP (oldx,1));
1192 if (frame_pointer_rtx != XEXP (oldx,0))
1193 if (offs > MAX_LD_OFFSET (mode))
1195 if (TARGET_ALL_DEBUG)
1196 fprintf (stderr, "force_reg (big offset)\n");
1197 x = force_reg (GET_MODE (oldx), oldx);
1201 return x;
1205 /* Return a pointer register name as a string. */
1207 static const char *
1208 ptrreg_to_str (int regno)
1210 switch (regno)
1212 case REG_X: return "X";
1213 case REG_Y: return "Y";
1214 case REG_Z: return "Z";
1215 default:
1216 output_operand_lossage ("address operand requires constraint for X, Y, or Z register");
1218 return NULL;
1221 /* Return the condition name as a string.
1222 Used in conditional jump constructing */
1224 static const char *
1225 cond_string (enum rtx_code code)
1227 switch (code)
1229 case NE:
1230 return "ne";
1231 case EQ:
1232 return "eq";
1233 case GE:
1234 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1235 return "pl";
1236 else
1237 return "ge";
1238 case LT:
1239 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1240 return "mi";
1241 else
1242 return "lt";
1243 case GEU:
1244 return "sh";
1245 case LTU:
1246 return "lo";
1247 default:
1248 gcc_unreachable ();
1252 /* Output ADDR to FILE as address. */
1254 void
1255 print_operand_address (FILE *file, rtx addr)
1257 switch (GET_CODE (addr))
1259 case REG:
1260 fprintf (file, ptrreg_to_str (REGNO (addr)));
1261 break;
1263 case PRE_DEC:
1264 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1265 break;
1267 case POST_INC:
1268 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1269 break;
1271 default:
1272 if (CONSTANT_ADDRESS_P (addr)
1273 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (addr))
1274 || GET_CODE (addr) == LABEL_REF))
1276 fprintf (file, "gs(");
1277 output_addr_const (file,addr);
1278 fprintf (file ,")");
1280 else
1281 output_addr_const (file, addr);
1286 /* Output X as assembler operand to file FILE. */
1288 void
1289 print_operand (FILE *file, rtx x, int code)
1291 int abcd = 0;
1293 if (code >= 'A' && code <= 'D')
1294 abcd = code - 'A';
1296 if (code == '~')
1298 if (!AVR_HAVE_JMP_CALL)
1299 fputc ('r', file);
1301 else if (code == '!')
1303 if (AVR_HAVE_EIJMP_EICALL)
1304 fputc ('e', file);
1306 else if (REG_P (x))
1308 if (x == zero_reg_rtx)
1309 fprintf (file, "__zero_reg__");
1310 else
1311 fprintf (file, reg_names[true_regnum (x) + abcd]);
1313 else if (GET_CODE (x) == CONST_INT)
1314 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd);
1315 else if (GET_CODE (x) == MEM)
1317 rtx addr = XEXP (x,0);
1319 if (CONSTANT_P (addr) && abcd)
1321 fputc ('(', file);
1322 output_address (addr);
1323 fprintf (file, ")+%d", abcd);
1325 else if (code == 'o')
1327 if (GET_CODE (addr) != PLUS)
1328 fatal_insn ("bad address, not (reg+disp):", addr);
1330 print_operand (file, XEXP (addr, 1), 0);
1332 else if (code == 'p' || code == 'r')
1334 if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
1335 fatal_insn ("bad address, not post_inc or pre_dec:", addr);
1337 if (code == 'p')
1338 print_operand_address (file, XEXP (addr, 0)); /* X, Y, Z */
1339 else
1340 print_operand (file, XEXP (addr, 0), 0); /* r26, r28, r30 */
1342 else if (GET_CODE (addr) == PLUS)
1344 print_operand_address (file, XEXP (addr,0));
1345 if (REGNO (XEXP (addr, 0)) == REG_X)
1346 fatal_insn ("internal compiler error. Bad address:"
1347 ,addr);
1348 fputc ('+', file);
1349 print_operand (file, XEXP (addr,1), code);
1351 else
1352 print_operand_address (file, addr);
1354 else if (GET_CODE (x) == CONST_DOUBLE)
1356 long val;
1357 REAL_VALUE_TYPE rv;
1358 if (GET_MODE (x) != SFmode)
1359 fatal_insn ("internal compiler error. Unknown mode:", x);
1360 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1361 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1362 fprintf (file, "0x%lx", val);
1364 else if (code == 'j')
1365 fputs (cond_string (GET_CODE (x)), file);
1366 else if (code == 'k')
1367 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
1368 else
1369 print_operand_address (file, x);
1372 /* Update the condition code in the INSN. */
1374 void
1375 notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
1377 rtx set;
1379 switch (get_attr_cc (insn))
1381 case CC_NONE:
1382 /* Insn does not affect CC at all. */
1383 break;
1385 case CC_SET_N:
1386 CC_STATUS_INIT;
1387 break;
1389 case CC_SET_ZN:
1390 set = single_set (insn);
1391 CC_STATUS_INIT;
1392 if (set)
1394 cc_status.flags |= CC_NO_OVERFLOW;
1395 cc_status.value1 = SET_DEST (set);
1397 break;
1399 case CC_SET_CZN:
1400 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1401 The V flag may or may not be known but that's ok because
1402 alter_cond will change tests to use EQ/NE. */
1403 set = single_set (insn);
1404 CC_STATUS_INIT;
1405 if (set)
1407 cc_status.value1 = SET_DEST (set);
1408 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1410 break;
1412 case CC_COMPARE:
1413 set = single_set (insn);
1414 CC_STATUS_INIT;
1415 if (set)
1416 cc_status.value1 = SET_SRC (set);
1417 break;
1419 case CC_CLOBBER:
1420 /* Insn doesn't leave CC in a usable state. */
1421 CC_STATUS_INIT;
1423 /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1424 set = single_set (insn);
1425 if (set)
1427 rtx src = SET_SRC (set);
1429 if (GET_CODE (src) == ASHIFTRT
1430 && GET_MODE (src) == QImode)
1432 rtx x = XEXP (src, 1);
1434 if (GET_CODE (x) == CONST_INT
1435 && INTVAL (x) > 0
1436 && INTVAL (x) != 6)
1438 cc_status.value1 = SET_DEST (set);
1439 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1443 break;
1447 /* Return maximum number of consecutive registers of
1448 class CLASS needed to hold a value of mode MODE. */
1451 class_max_nregs (enum reg_class rclass ATTRIBUTE_UNUSED,enum machine_mode mode)
1453 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1456 /* Choose mode for jump insn:
1457 1 - relative jump in range -63 <= x <= 62 ;
1458 2 - relative jump in range -2046 <= x <= 2045 ;
1459 3 - absolute jump (only for ATmega[16]03). */
1462 avr_jump_mode (rtx x, rtx insn)
1464 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1465 ? XEXP (x, 0) : x));
1466 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1467 int jump_distance = cur_addr - dest_addr;
1469 if (-63 <= jump_distance && jump_distance <= 62)
1470 return 1;
1471 else if (-2046 <= jump_distance && jump_distance <= 2045)
1472 return 2;
1473 else if (AVR_HAVE_JMP_CALL)
1474 return 3;
1476 return 2;
1479 /* return an AVR condition jump commands.
1480 X is a comparison RTX.
1481 LEN is a number returned by avr_jump_mode function.
1482 if REVERSE nonzero then condition code in X must be reversed. */
1484 const char *
1485 ret_cond_branch (rtx x, int len, int reverse)
1487 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1489 switch (cond)
1491 case GT:
1492 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1493 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1494 AS1 (brpl,%0)) :
1495 len == 2 ? (AS1 (breq,.+4) CR_TAB
1496 AS1 (brmi,.+2) CR_TAB
1497 AS1 (rjmp,%0)) :
1498 (AS1 (breq,.+6) CR_TAB
1499 AS1 (brmi,.+4) CR_TAB
1500 AS1 (jmp,%0)));
1502 else
1503 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1504 AS1 (brge,%0)) :
1505 len == 2 ? (AS1 (breq,.+4) CR_TAB
1506 AS1 (brlt,.+2) CR_TAB
1507 AS1 (rjmp,%0)) :
1508 (AS1 (breq,.+6) CR_TAB
1509 AS1 (brlt,.+4) CR_TAB
1510 AS1 (jmp,%0)));
1511 case GTU:
1512 return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1513 AS1 (brsh,%0)) :
1514 len == 2 ? (AS1 (breq,.+4) CR_TAB
1515 AS1 (brlo,.+2) CR_TAB
1516 AS1 (rjmp,%0)) :
1517 (AS1 (breq,.+6) CR_TAB
1518 AS1 (brlo,.+4) CR_TAB
1519 AS1 (jmp,%0)));
1520 case LE:
1521 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1522 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1523 AS1 (brmi,%0)) :
1524 len == 2 ? (AS1 (breq,.+2) CR_TAB
1525 AS1 (brpl,.+2) CR_TAB
1526 AS1 (rjmp,%0)) :
1527 (AS1 (breq,.+2) CR_TAB
1528 AS1 (brpl,.+4) CR_TAB
1529 AS1 (jmp,%0)));
1530 else
1531 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1532 AS1 (brlt,%0)) :
1533 len == 2 ? (AS1 (breq,.+2) CR_TAB
1534 AS1 (brge,.+2) CR_TAB
1535 AS1 (rjmp,%0)) :
1536 (AS1 (breq,.+2) CR_TAB
1537 AS1 (brge,.+4) CR_TAB
1538 AS1 (jmp,%0)));
1539 case LEU:
1540 return (len == 1 ? (AS1 (breq,%0) CR_TAB
1541 AS1 (brlo,%0)) :
1542 len == 2 ? (AS1 (breq,.+2) CR_TAB
1543 AS1 (brsh,.+2) CR_TAB
1544 AS1 (rjmp,%0)) :
1545 (AS1 (breq,.+2) CR_TAB
1546 AS1 (brsh,.+4) CR_TAB
1547 AS1 (jmp,%0)));
1548 default:
1549 if (reverse)
1551 switch (len)
1553 case 1:
1554 return AS1 (br%k1,%0);
1555 case 2:
1556 return (AS1 (br%j1,.+2) CR_TAB
1557 AS1 (rjmp,%0));
1558 default:
1559 return (AS1 (br%j1,.+4) CR_TAB
1560 AS1 (jmp,%0));
1563 else
1565 switch (len)
1567 case 1:
1568 return AS1 (br%j1,%0);
1569 case 2:
1570 return (AS1 (br%k1,.+2) CR_TAB
1571 AS1 (rjmp,%0));
1572 default:
1573 return (AS1 (br%k1,.+4) CR_TAB
1574 AS1 (jmp,%0));
1578 return "";
1581 /* Predicate function for immediate operand which fits to byte (8bit) */
1584 byte_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1586 return (GET_CODE (op) == CONST_INT
1587 && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1590 /* Output all insn addresses and their sizes into the assembly language
1591 output file. This is helpful for debugging whether the length attributes
1592 in the md file are correct.
1593 Output insn cost for next insn. */
1595 void
1596 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
1597 int num_operands ATTRIBUTE_UNUSED)
1599 int uid = INSN_UID (insn);
1601 if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1603 fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1604 INSN_ADDRESSES (uid),
1605 INSN_ADDRESSES (uid) - last_insn_address,
1606 rtx_cost (PATTERN (insn), INSN, !optimize_size));
1608 last_insn_address = INSN_ADDRESSES (uid);
1611 /* Return 0 if undefined, 1 if always true or always false. */
1614 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE op, rtx x)
1616 unsigned int max = (mode == QImode ? 0xff :
1617 mode == HImode ? 0xffff :
1618 mode == SImode ? 0xffffffff : 0);
1619 if (max && op && GET_CODE (x) == CONST_INT)
1621 if (unsigned_condition (op) != op)
1622 max >>= 1;
1624 if (max != (INTVAL (x) & max)
1625 && INTVAL (x) != 0xff)
1626 return 1;
1628 return 0;
1632 /* Returns nonzero if REGNO is the number of a hard
1633 register in which function arguments are sometimes passed. */
1636 function_arg_regno_p(int r)
1638 return (r >= 8 && r <= 25);
1641 /* Initializing the variable cum for the state at the beginning
1642 of the argument list. */
1644 void
1645 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
1646 tree fndecl ATTRIBUTE_UNUSED)
1648 cum->nregs = 18;
1649 cum->regno = FIRST_CUM_REG;
1650 if (!libname && fntype)
1652 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1653 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1654 != void_type_node));
1655 if (stdarg)
1656 cum->nregs = 0;
1660 /* Returns the number of registers to allocate for a function argument. */
1662 static int
1663 avr_num_arg_regs (enum machine_mode mode, tree type)
1665 int size;
1667 if (mode == BLKmode)
1668 size = int_size_in_bytes (type);
1669 else
1670 size = GET_MODE_SIZE (mode);
1672 /* Align all function arguments to start in even-numbered registers.
1673 Odd-sized arguments leave holes above them. */
1675 return (size + 1) & ~1;
1678 /* Controls whether a function argument is passed
1679 in a register, and which register. */
1682 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1683 int named ATTRIBUTE_UNUSED)
1685 int bytes = avr_num_arg_regs (mode, type);
1687 if (cum->nregs && bytes <= cum->nregs)
1688 return gen_rtx_REG (mode, cum->regno - bytes);
1690 return NULL_RTX;
1693 /* Update the summarizer variable CUM to advance past an argument
1694 in the argument list. */
1696 void
1697 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1698 int named ATTRIBUTE_UNUSED)
1700 int bytes = avr_num_arg_regs (mode, type);
1702 cum->nregs -= bytes;
1703 cum->regno -= bytes;
1705 if (cum->nregs <= 0)
1707 cum->nregs = 0;
1708 cum->regno = FIRST_CUM_REG;
1712 /***********************************************************************
1713 Functions for outputting various mov's for a various modes
1714 ************************************************************************/
1715 const char *
1716 output_movqi (rtx insn, rtx operands[], int *l)
1718 int dummy;
1719 rtx dest = operands[0];
1720 rtx src = operands[1];
1721 int *real_l = l;
1723 if (!l)
1724 l = &dummy;
1726 *l = 1;
1728 if (register_operand (dest, QImode))
1730 if (register_operand (src, QImode)) /* mov r,r */
1732 if (test_hard_reg_class (STACK_REG, dest))
1733 return AS2 (out,%0,%1);
1734 else if (test_hard_reg_class (STACK_REG, src))
1735 return AS2 (in,%0,%1);
1737 return AS2 (mov,%0,%1);
1739 else if (CONSTANT_P (src))
1741 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1742 return AS2 (ldi,%0,lo8(%1));
1744 if (GET_CODE (src) == CONST_INT)
1746 if (src == const0_rtx) /* mov r,L */
1747 return AS1 (clr,%0);
1748 else if (src == const1_rtx)
1750 *l = 2;
1751 return (AS1 (clr,%0) CR_TAB
1752 AS1 (inc,%0));
1754 else if (src == constm1_rtx)
1756 /* Immediate constants -1 to any register */
1757 *l = 2;
1758 return (AS1 (clr,%0) CR_TAB
1759 AS1 (dec,%0));
1761 else
1763 int bit_nr = exact_log2 (INTVAL (src));
1765 if (bit_nr >= 0)
1767 *l = 3;
1768 if (!real_l)
1769 output_asm_insn ((AS1 (clr,%0) CR_TAB
1770 "set"), operands);
1771 if (!real_l)
1772 avr_output_bld (operands, bit_nr);
1774 return "";
1779 /* Last resort, larger than loading from memory. */
1780 *l = 4;
1781 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1782 AS2 (ldi,r31,lo8(%1)) CR_TAB
1783 AS2 (mov,%0,r31) CR_TAB
1784 AS2 (mov,r31,__tmp_reg__));
1786 else if (GET_CODE (src) == MEM)
1787 return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1789 else if (GET_CODE (dest) == MEM)
1791 const char *templ;
1793 if (src == const0_rtx)
1794 operands[1] = zero_reg_rtx;
1796 templ = out_movqi_mr_r (insn, operands, real_l);
1798 if (!real_l)
1799 output_asm_insn (templ, operands);
1801 operands[1] = src;
1803 return "";
1807 const char *
1808 output_movhi (rtx insn, rtx operands[], int *l)
1810 int dummy;
1811 rtx dest = operands[0];
1812 rtx src = operands[1];
1813 int *real_l = l;
1815 if (!l)
1816 l = &dummy;
1818 if (register_operand (dest, HImode))
1820 if (register_operand (src, HImode)) /* mov r,r */
1822 if (test_hard_reg_class (STACK_REG, dest))
1824 if (TARGET_TINY_STACK)
1825 return *l = 1, AS2 (out,__SP_L__,%A1);
1826 /* Use simple load of stack pointer if no interrupts are
1827 used. */
1828 else if (TARGET_NO_INTERRUPTS)
1829 return *l = 2, (AS2 (out,__SP_H__,%B1) CR_TAB
1830 AS2 (out,__SP_L__,%A1));
1831 *l = 5;
1832 return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB
1833 "cli" CR_TAB
1834 AS2 (out,__SP_H__,%B1) CR_TAB
1835 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1836 AS2 (out,__SP_L__,%A1));
1838 else if (test_hard_reg_class (STACK_REG, src))
1840 *l = 2;
1841 return (AS2 (in,%A0,__SP_L__) CR_TAB
1842 AS2 (in,%B0,__SP_H__));
1845 if (AVR_HAVE_MOVW)
1847 *l = 1;
1848 return (AS2 (movw,%0,%1));
1850 else
1852 *l = 2;
1853 return (AS2 (mov,%A0,%A1) CR_TAB
1854 AS2 (mov,%B0,%B1));
1857 else if (CONSTANT_P (src))
1859 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1861 *l = 2;
1862 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1863 AS2 (ldi,%B0,hi8(%1)));
1866 if (GET_CODE (src) == CONST_INT)
1868 if (src == const0_rtx) /* mov r,L */
1870 *l = 2;
1871 return (AS1 (clr,%A0) CR_TAB
1872 AS1 (clr,%B0));
1874 else if (src == const1_rtx)
1876 *l = 3;
1877 return (AS1 (clr,%A0) CR_TAB
1878 AS1 (clr,%B0) CR_TAB
1879 AS1 (inc,%A0));
1881 else if (src == constm1_rtx)
1883 /* Immediate constants -1 to any register */
1884 *l = 3;
1885 return (AS1 (clr,%0) CR_TAB
1886 AS1 (dec,%A0) CR_TAB
1887 AS2 (mov,%B0,%A0));
1889 else
1891 int bit_nr = exact_log2 (INTVAL (src));
1893 if (bit_nr >= 0)
1895 *l = 4;
1896 if (!real_l)
1897 output_asm_insn ((AS1 (clr,%A0) CR_TAB
1898 AS1 (clr,%B0) CR_TAB
1899 "set"), operands);
1900 if (!real_l)
1901 avr_output_bld (operands, bit_nr);
1903 return "";
1907 if ((INTVAL (src) & 0xff) == 0)
1909 *l = 5;
1910 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1911 AS1 (clr,%A0) CR_TAB
1912 AS2 (ldi,r31,hi8(%1)) CR_TAB
1913 AS2 (mov,%B0,r31) CR_TAB
1914 AS2 (mov,r31,__tmp_reg__));
1916 else if ((INTVAL (src) & 0xff00) == 0)
1918 *l = 5;
1919 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1920 AS2 (ldi,r31,lo8(%1)) CR_TAB
1921 AS2 (mov,%A0,r31) CR_TAB
1922 AS1 (clr,%B0) CR_TAB
1923 AS2 (mov,r31,__tmp_reg__));
1927 /* Last resort, equal to loading from memory. */
1928 *l = 6;
1929 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1930 AS2 (ldi,r31,lo8(%1)) CR_TAB
1931 AS2 (mov,%A0,r31) CR_TAB
1932 AS2 (ldi,r31,hi8(%1)) CR_TAB
1933 AS2 (mov,%B0,r31) CR_TAB
1934 AS2 (mov,r31,__tmp_reg__));
1936 else if (GET_CODE (src) == MEM)
1937 return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1939 else if (GET_CODE (dest) == MEM)
1941 const char *templ;
1943 if (src == const0_rtx)
1944 operands[1] = zero_reg_rtx;
1946 templ = out_movhi_mr_r (insn, operands, real_l);
1948 if (!real_l)
1949 output_asm_insn (templ, operands);
1951 operands[1] = src;
1952 return "";
1954 fatal_insn ("invalid insn:", insn);
1955 return "";
1958 const char *
1959 out_movqi_r_mr (rtx insn, rtx op[], int *l)
1961 rtx dest = op[0];
1962 rtx src = op[1];
1963 rtx x = XEXP (src, 0);
1964 int dummy;
1966 if (!l)
1967 l = &dummy;
1969 if (CONSTANT_ADDRESS_P (x))
1971 if (CONST_INT_P (x) && INTVAL (x) == SREG_ADDR)
1973 *l = 1;
1974 return AS2 (in,%0,__SREG__);
1976 if (optimize > 0 && io_address_operand (x, QImode))
1978 *l = 1;
1979 return AS2 (in,%0,%1-0x20);
1981 *l = 2;
1982 return AS2 (lds,%0,%1);
1984 /* memory access by reg+disp */
1985 else if (GET_CODE (x) == PLUS
1986 && REG_P (XEXP (x,0))
1987 && GET_CODE (XEXP (x,1)) == CONST_INT)
1989 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1991 int disp = INTVAL (XEXP (x,1));
1992 if (REGNO (XEXP (x,0)) != REG_Y)
1993 fatal_insn ("incorrect insn:",insn);
1995 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1996 return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
1997 AS2 (ldd,%0,Y+63) CR_TAB
1998 AS2 (sbiw,r28,%o1-63));
2000 return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2001 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2002 AS2 (ld,%0,Y) CR_TAB
2003 AS2 (subi,r28,lo8(%o1)) CR_TAB
2004 AS2 (sbci,r29,hi8(%o1)));
2006 else if (REGNO (XEXP (x,0)) == REG_X)
2008 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
2009 it but I have this situation with extremal optimizing options. */
2010 if (reg_overlap_mentioned_p (dest, XEXP (x,0))
2011 || reg_unused_after (insn, XEXP (x,0)))
2012 return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
2013 AS2 (ld,%0,X));
2015 return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
2016 AS2 (ld,%0,X) CR_TAB
2017 AS2 (sbiw,r26,%o1));
2019 *l = 1;
2020 return AS2 (ldd,%0,%1);
2022 *l = 1;
2023 return AS2 (ld,%0,%1);
2026 const char *
2027 out_movhi_r_mr (rtx insn, rtx op[], int *l)
2029 rtx dest = op[0];
2030 rtx src = op[1];
2031 rtx base = XEXP (src, 0);
2032 int reg_dest = true_regnum (dest);
2033 int reg_base = true_regnum (base);
2034 /* "volatile" forces reading low byte first, even if less efficient,
2035 for correct operation with 16-bit I/O registers. */
2036 int mem_volatile_p = MEM_VOLATILE_P (src);
2037 int tmp;
2039 if (!l)
2040 l = &tmp;
2042 if (reg_base > 0)
2044 if (reg_dest == reg_base) /* R = (R) */
2046 *l = 3;
2047 return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
2048 AS2 (ld,%B0,%1) CR_TAB
2049 AS2 (mov,%A0,__tmp_reg__));
2051 else if (reg_base == REG_X) /* (R26) */
2053 if (reg_unused_after (insn, base))
2055 *l = 2;
2056 return (AS2 (ld,%A0,X+) CR_TAB
2057 AS2 (ld,%B0,X));
2059 *l = 3;
2060 return (AS2 (ld,%A0,X+) CR_TAB
2061 AS2 (ld,%B0,X) CR_TAB
2062 AS2 (sbiw,r26,1));
2064 else /* (R) */
2066 *l = 2;
2067 return (AS2 (ld,%A0,%1) CR_TAB
2068 AS2 (ldd,%B0,%1+1));
2071 else if (GET_CODE (base) == PLUS) /* (R + i) */
2073 int disp = INTVAL (XEXP (base, 1));
2074 int reg_base = true_regnum (XEXP (base, 0));
2076 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2078 if (REGNO (XEXP (base, 0)) != REG_Y)
2079 fatal_insn ("incorrect insn:",insn);
2081 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2082 return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
2083 AS2 (ldd,%A0,Y+62) CR_TAB
2084 AS2 (ldd,%B0,Y+63) CR_TAB
2085 AS2 (sbiw,r28,%o1-62));
2087 return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2088 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2089 AS2 (ld,%A0,Y) CR_TAB
2090 AS2 (ldd,%B0,Y+1) CR_TAB
2091 AS2 (subi,r28,lo8(%o1)) CR_TAB
2092 AS2 (sbci,r29,hi8(%o1)));
2094 if (reg_base == REG_X)
2096 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
2097 it but I have this situation with extremal
2098 optimization options. */
2100 *l = 4;
2101 if (reg_base == reg_dest)
2102 return (AS2 (adiw,r26,%o1) CR_TAB
2103 AS2 (ld,__tmp_reg__,X+) CR_TAB
2104 AS2 (ld,%B0,X) CR_TAB
2105 AS2 (mov,%A0,__tmp_reg__));
2107 return (AS2 (adiw,r26,%o1) CR_TAB
2108 AS2 (ld,%A0,X+) CR_TAB
2109 AS2 (ld,%B0,X) CR_TAB
2110 AS2 (sbiw,r26,%o1+1));
2113 if (reg_base == reg_dest)
2115 *l = 3;
2116 return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
2117 AS2 (ldd,%B0,%B1) CR_TAB
2118 AS2 (mov,%A0,__tmp_reg__));
2121 *l = 2;
2122 return (AS2 (ldd,%A0,%A1) CR_TAB
2123 AS2 (ldd,%B0,%B1));
2125 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2127 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
2128 fatal_insn ("incorrect insn:", insn);
2130 if (mem_volatile_p)
2132 if (REGNO (XEXP (base, 0)) == REG_X)
2134 *l = 4;
2135 return (AS2 (sbiw,r26,2) CR_TAB
2136 AS2 (ld,%A0,X+) CR_TAB
2137 AS2 (ld,%B0,X) CR_TAB
2138 AS2 (sbiw,r26,1));
2140 else
2142 *l = 3;
2143 return (AS2 (sbiw,%r1,2) CR_TAB
2144 AS2 (ld,%A0,%p1) CR_TAB
2145 AS2 (ldd,%B0,%p1+1));
2149 *l = 2;
2150 return (AS2 (ld,%B0,%1) CR_TAB
2151 AS2 (ld,%A0,%1));
2153 else if (GET_CODE (base) == POST_INC) /* (R++) */
2155 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
2156 fatal_insn ("incorrect insn:", insn);
2158 *l = 2;
2159 return (AS2 (ld,%A0,%1) CR_TAB
2160 AS2 (ld,%B0,%1));
2162 else if (CONSTANT_ADDRESS_P (base))
2164 if (optimize > 0 && io_address_operand (base, HImode))
2166 *l = 2;
2167 return (AS2 (in,%A0,%A1-0x20) CR_TAB
2168 AS2 (in,%B0,%B1-0x20));
2170 *l = 4;
2171 return (AS2 (lds,%A0,%A1) CR_TAB
2172 AS2 (lds,%B0,%B1));
2175 fatal_insn ("unknown move insn:",insn);
2176 return "";
2179 const char *
2180 out_movsi_r_mr (rtx insn, rtx op[], int *l)
2182 rtx dest = op[0];
2183 rtx src = op[1];
2184 rtx base = XEXP (src, 0);
2185 int reg_dest = true_regnum (dest);
2186 int reg_base = true_regnum (base);
2187 int tmp;
2189 if (!l)
2190 l = &tmp;
2192 if (reg_base > 0)
2194 if (reg_base == REG_X) /* (R26) */
2196 if (reg_dest == REG_X)
2197 /* "ld r26,-X" is undefined */
2198 return *l=7, (AS2 (adiw,r26,3) CR_TAB
2199 AS2 (ld,r29,X) CR_TAB
2200 AS2 (ld,r28,-X) CR_TAB
2201 AS2 (ld,__tmp_reg__,-X) CR_TAB
2202 AS2 (sbiw,r26,1) CR_TAB
2203 AS2 (ld,r26,X) CR_TAB
2204 AS2 (mov,r27,__tmp_reg__));
2205 else if (reg_dest == REG_X - 2)
2206 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2207 AS2 (ld,%B0,X+) CR_TAB
2208 AS2 (ld,__tmp_reg__,X+) CR_TAB
2209 AS2 (ld,%D0,X) CR_TAB
2210 AS2 (mov,%C0,__tmp_reg__));
2211 else if (reg_unused_after (insn, base))
2212 return *l=4, (AS2 (ld,%A0,X+) CR_TAB
2213 AS2 (ld,%B0,X+) CR_TAB
2214 AS2 (ld,%C0,X+) CR_TAB
2215 AS2 (ld,%D0,X));
2216 else
2217 return *l=5, (AS2 (ld,%A0,X+) CR_TAB
2218 AS2 (ld,%B0,X+) CR_TAB
2219 AS2 (ld,%C0,X+) CR_TAB
2220 AS2 (ld,%D0,X) CR_TAB
2221 AS2 (sbiw,r26,3));
2223 else
2225 if (reg_dest == reg_base)
2226 return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
2227 AS2 (ldd,%C0,%1+2) CR_TAB
2228 AS2 (ldd,__tmp_reg__,%1+1) CR_TAB
2229 AS2 (ld,%A0,%1) CR_TAB
2230 AS2 (mov,%B0,__tmp_reg__));
2231 else if (reg_base == reg_dest + 2)
2232 return *l=5, (AS2 (ld ,%A0,%1) CR_TAB
2233 AS2 (ldd,%B0,%1+1) CR_TAB
2234 AS2 (ldd,__tmp_reg__,%1+2) CR_TAB
2235 AS2 (ldd,%D0,%1+3) CR_TAB
2236 AS2 (mov,%C0,__tmp_reg__));
2237 else
2238 return *l=4, (AS2 (ld ,%A0,%1) CR_TAB
2239 AS2 (ldd,%B0,%1+1) CR_TAB
2240 AS2 (ldd,%C0,%1+2) CR_TAB
2241 AS2 (ldd,%D0,%1+3));
2244 else if (GET_CODE (base) == PLUS) /* (R + i) */
2246 int disp = INTVAL (XEXP (base, 1));
2248 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2250 if (REGNO (XEXP (base, 0)) != REG_Y)
2251 fatal_insn ("incorrect insn:",insn);
2253 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2254 return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2255 AS2 (ldd,%A0,Y+60) CR_TAB
2256 AS2 (ldd,%B0,Y+61) CR_TAB
2257 AS2 (ldd,%C0,Y+62) CR_TAB
2258 AS2 (ldd,%D0,Y+63) CR_TAB
2259 AS2 (sbiw,r28,%o1-60));
2261 return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2262 AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2263 AS2 (ld,%A0,Y) CR_TAB
2264 AS2 (ldd,%B0,Y+1) CR_TAB
2265 AS2 (ldd,%C0,Y+2) CR_TAB
2266 AS2 (ldd,%D0,Y+3) CR_TAB
2267 AS2 (subi,r28,lo8(%o1)) CR_TAB
2268 AS2 (sbci,r29,hi8(%o1)));
2271 reg_base = true_regnum (XEXP (base, 0));
2272 if (reg_base == REG_X)
2274 /* R = (X + d) */
2275 if (reg_dest == REG_X)
2277 *l = 7;
2278 /* "ld r26,-X" is undefined */
2279 return (AS2 (adiw,r26,%o1+3) CR_TAB
2280 AS2 (ld,r29,X) CR_TAB
2281 AS2 (ld,r28,-X) CR_TAB
2282 AS2 (ld,__tmp_reg__,-X) CR_TAB
2283 AS2 (sbiw,r26,1) CR_TAB
2284 AS2 (ld,r26,X) CR_TAB
2285 AS2 (mov,r27,__tmp_reg__));
2287 *l = 6;
2288 if (reg_dest == REG_X - 2)
2289 return (AS2 (adiw,r26,%o1) CR_TAB
2290 AS2 (ld,r24,X+) CR_TAB
2291 AS2 (ld,r25,X+) CR_TAB
2292 AS2 (ld,__tmp_reg__,X+) CR_TAB
2293 AS2 (ld,r27,X) CR_TAB
2294 AS2 (mov,r26,__tmp_reg__));
2296 return (AS2 (adiw,r26,%o1) CR_TAB
2297 AS2 (ld,%A0,X+) CR_TAB
2298 AS2 (ld,%B0,X+) CR_TAB
2299 AS2 (ld,%C0,X+) CR_TAB
2300 AS2 (ld,%D0,X) CR_TAB
2301 AS2 (sbiw,r26,%o1+3));
2303 if (reg_dest == reg_base)
2304 return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2305 AS2 (ldd,%C0,%C1) CR_TAB
2306 AS2 (ldd,__tmp_reg__,%B1) CR_TAB
2307 AS2 (ldd,%A0,%A1) CR_TAB
2308 AS2 (mov,%B0,__tmp_reg__));
2309 else if (reg_dest == reg_base - 2)
2310 return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2311 AS2 (ldd,%B0,%B1) CR_TAB
2312 AS2 (ldd,__tmp_reg__,%C1) CR_TAB
2313 AS2 (ldd,%D0,%D1) CR_TAB
2314 AS2 (mov,%C0,__tmp_reg__));
2315 return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2316 AS2 (ldd,%B0,%B1) CR_TAB
2317 AS2 (ldd,%C0,%C1) CR_TAB
2318 AS2 (ldd,%D0,%D1));
2320 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2321 return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2322 AS2 (ld,%C0,%1) CR_TAB
2323 AS2 (ld,%B0,%1) CR_TAB
2324 AS2 (ld,%A0,%1));
2325 else if (GET_CODE (base) == POST_INC) /* (R++) */
2326 return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2327 AS2 (ld,%B0,%1) CR_TAB
2328 AS2 (ld,%C0,%1) CR_TAB
2329 AS2 (ld,%D0,%1));
2330 else if (CONSTANT_ADDRESS_P (base))
2331 return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2332 AS2 (lds,%B0,%B1) CR_TAB
2333 AS2 (lds,%C0,%C1) CR_TAB
2334 AS2 (lds,%D0,%D1));
2336 fatal_insn ("unknown move insn:",insn);
2337 return "";
2340 const char *
2341 out_movsi_mr_r (rtx insn, rtx op[], int *l)
2343 rtx dest = op[0];
2344 rtx src = op[1];
2345 rtx base = XEXP (dest, 0);
2346 int reg_base = true_regnum (base);
2347 int reg_src = true_regnum (src);
2348 int tmp;
2350 if (!l)
2351 l = &tmp;
2353 if (CONSTANT_ADDRESS_P (base))
2354 return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2355 AS2 (sts,%B0,%B1) CR_TAB
2356 AS2 (sts,%C0,%C1) CR_TAB
2357 AS2 (sts,%D0,%D1));
2358 if (reg_base > 0) /* (r) */
2360 if (reg_base == REG_X) /* (R26) */
2362 if (reg_src == REG_X)
2364 /* "st X+,r26" is undefined */
2365 if (reg_unused_after (insn, base))
2366 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2367 AS2 (st,X,r26) CR_TAB
2368 AS2 (adiw,r26,1) CR_TAB
2369 AS2 (st,X+,__tmp_reg__) CR_TAB
2370 AS2 (st,X+,r28) CR_TAB
2371 AS2 (st,X,r29));
2372 else
2373 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2374 AS2 (st,X,r26) CR_TAB
2375 AS2 (adiw,r26,1) CR_TAB
2376 AS2 (st,X+,__tmp_reg__) CR_TAB
2377 AS2 (st,X+,r28) CR_TAB
2378 AS2 (st,X,r29) CR_TAB
2379 AS2 (sbiw,r26,3));
2381 else if (reg_base == reg_src + 2)
2383 if (reg_unused_after (insn, base))
2384 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2385 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2386 AS2 (st,%0+,%A1) CR_TAB
2387 AS2 (st,%0+,%B1) CR_TAB
2388 AS2 (st,%0+,__zero_reg__) CR_TAB
2389 AS2 (st,%0,__tmp_reg__) CR_TAB
2390 AS1 (clr,__zero_reg__));
2391 else
2392 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2393 AS2 (mov,__tmp_reg__,%D1) CR_TAB
2394 AS2 (st,%0+,%A1) CR_TAB
2395 AS2 (st,%0+,%B1) CR_TAB
2396 AS2 (st,%0+,__zero_reg__) CR_TAB
2397 AS2 (st,%0,__tmp_reg__) CR_TAB
2398 AS1 (clr,__zero_reg__) CR_TAB
2399 AS2 (sbiw,r26,3));
2401 return *l=5, (AS2 (st,%0+,%A1) CR_TAB
2402 AS2 (st,%0+,%B1) CR_TAB
2403 AS2 (st,%0+,%C1) CR_TAB
2404 AS2 (st,%0,%D1) CR_TAB
2405 AS2 (sbiw,r26,3));
2407 else
2408 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2409 AS2 (std,%0+1,%B1) CR_TAB
2410 AS2 (std,%0+2,%C1) CR_TAB
2411 AS2 (std,%0+3,%D1));
2413 else if (GET_CODE (base) == PLUS) /* (R + i) */
2415 int disp = INTVAL (XEXP (base, 1));
2416 reg_base = REGNO (XEXP (base, 0));
2417 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2419 if (reg_base != REG_Y)
2420 fatal_insn ("incorrect insn:",insn);
2422 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2423 return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2424 AS2 (std,Y+60,%A1) CR_TAB
2425 AS2 (std,Y+61,%B1) CR_TAB
2426 AS2 (std,Y+62,%C1) CR_TAB
2427 AS2 (std,Y+63,%D1) CR_TAB
2428 AS2 (sbiw,r28,%o0-60));
2430 return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2431 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2432 AS2 (st,Y,%A1) CR_TAB
2433 AS2 (std,Y+1,%B1) CR_TAB
2434 AS2 (std,Y+2,%C1) CR_TAB
2435 AS2 (std,Y+3,%D1) CR_TAB
2436 AS2 (subi,r28,lo8(%o0)) CR_TAB
2437 AS2 (sbci,r29,hi8(%o0)));
2439 if (reg_base == REG_X)
2441 /* (X + d) = R */
2442 if (reg_src == REG_X)
2444 *l = 9;
2445 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2446 AS2 (mov,__zero_reg__,r27) CR_TAB
2447 AS2 (adiw,r26,%o0) CR_TAB
2448 AS2 (st,X+,__tmp_reg__) CR_TAB
2449 AS2 (st,X+,__zero_reg__) CR_TAB
2450 AS2 (st,X+,r28) CR_TAB
2451 AS2 (st,X,r29) CR_TAB
2452 AS1 (clr,__zero_reg__) CR_TAB
2453 AS2 (sbiw,r26,%o0+3));
2455 else if (reg_src == REG_X - 2)
2457 *l = 9;
2458 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2459 AS2 (mov,__zero_reg__,r27) CR_TAB
2460 AS2 (adiw,r26,%o0) CR_TAB
2461 AS2 (st,X+,r24) CR_TAB
2462 AS2 (st,X+,r25) CR_TAB
2463 AS2 (st,X+,__tmp_reg__) CR_TAB
2464 AS2 (st,X,__zero_reg__) CR_TAB
2465 AS1 (clr,__zero_reg__) CR_TAB
2466 AS2 (sbiw,r26,%o0+3));
2468 *l = 6;
2469 return (AS2 (adiw,r26,%o0) CR_TAB
2470 AS2 (st,X+,%A1) CR_TAB
2471 AS2 (st,X+,%B1) CR_TAB
2472 AS2 (st,X+,%C1) CR_TAB
2473 AS2 (st,X,%D1) CR_TAB
2474 AS2 (sbiw,r26,%o0+3));
2476 return *l=4, (AS2 (std,%A0,%A1) CR_TAB
2477 AS2 (std,%B0,%B1) CR_TAB
2478 AS2 (std,%C0,%C1) CR_TAB
2479 AS2 (std,%D0,%D1));
2481 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2482 return *l=4, (AS2 (st,%0,%D1) CR_TAB
2483 AS2 (st,%0,%C1) CR_TAB
2484 AS2 (st,%0,%B1) CR_TAB
2485 AS2 (st,%0,%A1));
2486 else if (GET_CODE (base) == POST_INC) /* (R++) */
2487 return *l=4, (AS2 (st,%0,%A1) CR_TAB
2488 AS2 (st,%0,%B1) CR_TAB
2489 AS2 (st,%0,%C1) CR_TAB
2490 AS2 (st,%0,%D1));
2491 fatal_insn ("unknown move insn:",insn);
2492 return "";
2495 const char *
2496 output_movsisf(rtx insn, rtx operands[], int *l)
2498 int dummy;
2499 rtx dest = operands[0];
2500 rtx src = operands[1];
2501 int *real_l = l;
2503 if (!l)
2504 l = &dummy;
2506 if (register_operand (dest, VOIDmode))
2508 if (register_operand (src, VOIDmode)) /* mov r,r */
2510 if (true_regnum (dest) > true_regnum (src))
2512 if (AVR_HAVE_MOVW)
2514 *l = 2;
2515 return (AS2 (movw,%C0,%C1) CR_TAB
2516 AS2 (movw,%A0,%A1));
2518 *l = 4;
2519 return (AS2 (mov,%D0,%D1) CR_TAB
2520 AS2 (mov,%C0,%C1) CR_TAB
2521 AS2 (mov,%B0,%B1) CR_TAB
2522 AS2 (mov,%A0,%A1));
2524 else
2526 if (AVR_HAVE_MOVW)
2528 *l = 2;
2529 return (AS2 (movw,%A0,%A1) CR_TAB
2530 AS2 (movw,%C0,%C1));
2532 *l = 4;
2533 return (AS2 (mov,%A0,%A1) CR_TAB
2534 AS2 (mov,%B0,%B1) CR_TAB
2535 AS2 (mov,%C0,%C1) CR_TAB
2536 AS2 (mov,%D0,%D1));
2539 else if (CONSTANT_P (src))
2541 if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2543 *l = 4;
2544 return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
2545 AS2 (ldi,%B0,hi8(%1)) CR_TAB
2546 AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2547 AS2 (ldi,%D0,hhi8(%1)));
2550 if (GET_CODE (src) == CONST_INT)
2552 const char *const clr_op0 =
2553 AVR_HAVE_MOVW ? (AS1 (clr,%A0) CR_TAB
2554 AS1 (clr,%B0) CR_TAB
2555 AS2 (movw,%C0,%A0))
2556 : (AS1 (clr,%A0) CR_TAB
2557 AS1 (clr,%B0) CR_TAB
2558 AS1 (clr,%C0) CR_TAB
2559 AS1 (clr,%D0));
2561 if (src == const0_rtx) /* mov r,L */
2563 *l = AVR_HAVE_MOVW ? 3 : 4;
2564 return clr_op0;
2566 else if (src == const1_rtx)
2568 if (!real_l)
2569 output_asm_insn (clr_op0, operands);
2570 *l = AVR_HAVE_MOVW ? 4 : 5;
2571 return AS1 (inc,%A0);
2573 else if (src == constm1_rtx)
2575 /* Immediate constants -1 to any register */
2576 if (AVR_HAVE_MOVW)
2578 *l = 4;
2579 return (AS1 (clr,%A0) CR_TAB
2580 AS1 (dec,%A0) CR_TAB
2581 AS2 (mov,%B0,%A0) CR_TAB
2582 AS2 (movw,%C0,%A0));
2584 *l = 5;
2585 return (AS1 (clr,%A0) CR_TAB
2586 AS1 (dec,%A0) CR_TAB
2587 AS2 (mov,%B0,%A0) CR_TAB
2588 AS2 (mov,%C0,%A0) CR_TAB
2589 AS2 (mov,%D0,%A0));
2591 else
2593 int bit_nr = exact_log2 (INTVAL (src));
2595 if (bit_nr >= 0)
2597 *l = AVR_HAVE_MOVW ? 5 : 6;
2598 if (!real_l)
2600 output_asm_insn (clr_op0, operands);
2601 output_asm_insn ("set", operands);
2603 if (!real_l)
2604 avr_output_bld (operands, bit_nr);
2606 return "";
2611 /* Last resort, better than loading from memory. */
2612 *l = 10;
2613 return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2614 AS2 (ldi,r31,lo8(%1)) CR_TAB
2615 AS2 (mov,%A0,r31) CR_TAB
2616 AS2 (ldi,r31,hi8(%1)) CR_TAB
2617 AS2 (mov,%B0,r31) CR_TAB
2618 AS2 (ldi,r31,hlo8(%1)) CR_TAB
2619 AS2 (mov,%C0,r31) CR_TAB
2620 AS2 (ldi,r31,hhi8(%1)) CR_TAB
2621 AS2 (mov,%D0,r31) CR_TAB
2622 AS2 (mov,r31,__tmp_reg__));
2624 else if (GET_CODE (src) == MEM)
2625 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2627 else if (GET_CODE (dest) == MEM)
2629 const char *templ;
2631 if (src == const0_rtx)
2632 operands[1] = zero_reg_rtx;
2634 templ = out_movsi_mr_r (insn, operands, real_l);
2636 if (!real_l)
2637 output_asm_insn (templ, operands);
2639 operands[1] = src;
2640 return "";
2642 fatal_insn ("invalid insn:", insn);
2643 return "";
2646 const char *
2647 out_movqi_mr_r (rtx insn, rtx op[], int *l)
2649 rtx dest = op[0];
2650 rtx src = op[1];
2651 rtx x = XEXP (dest, 0);
2652 int dummy;
2654 if (!l)
2655 l = &dummy;
2657 if (CONSTANT_ADDRESS_P (x))
2659 if (CONST_INT_P (x) && INTVAL (x) == SREG_ADDR)
2661 *l = 1;
2662 return AS2 (out,__SREG__,%1);
2664 if (optimize > 0 && io_address_operand (x, QImode))
2666 *l = 1;
2667 return AS2 (out,%0-0x20,%1);
2669 *l = 2;
2670 return AS2 (sts,%0,%1);
2672 /* memory access by reg+disp */
2673 else if (GET_CODE (x) == PLUS
2674 && REG_P (XEXP (x,0))
2675 && GET_CODE (XEXP (x,1)) == CONST_INT)
2677 if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2679 int disp = INTVAL (XEXP (x,1));
2680 if (REGNO (XEXP (x,0)) != REG_Y)
2681 fatal_insn ("incorrect insn:",insn);
2683 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2684 return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2685 AS2 (std,Y+63,%1) CR_TAB
2686 AS2 (sbiw,r28,%o0-63));
2688 return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2689 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2690 AS2 (st,Y,%1) CR_TAB
2691 AS2 (subi,r28,lo8(%o0)) CR_TAB
2692 AS2 (sbci,r29,hi8(%o0)));
2694 else if (REGNO (XEXP (x,0)) == REG_X)
2696 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2698 if (reg_unused_after (insn, XEXP (x,0)))
2699 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2700 AS2 (adiw,r26,%o0) CR_TAB
2701 AS2 (st,X,__tmp_reg__));
2703 return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2704 AS2 (adiw,r26,%o0) CR_TAB
2705 AS2 (st,X,__tmp_reg__) CR_TAB
2706 AS2 (sbiw,r26,%o0));
2708 else
2710 if (reg_unused_after (insn, XEXP (x,0)))
2711 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2712 AS2 (st,X,%1));
2714 return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2715 AS2 (st,X,%1) CR_TAB
2716 AS2 (sbiw,r26,%o0));
2719 *l = 1;
2720 return AS2 (std,%0,%1);
2722 *l = 1;
2723 return AS2 (st,%0,%1);
2726 const char *
2727 out_movhi_mr_r (rtx insn, rtx op[], int *l)
2729 rtx dest = op[0];
2730 rtx src = op[1];
2731 rtx base = XEXP (dest, 0);
2732 int reg_base = true_regnum (base);
2733 int reg_src = true_regnum (src);
2734 /* "volatile" forces writing high byte first, even if less efficient,
2735 for correct operation with 16-bit I/O registers. */
2736 int mem_volatile_p = MEM_VOLATILE_P (dest);
2737 int tmp;
2739 if (!l)
2740 l = &tmp;
2741 if (CONSTANT_ADDRESS_P (base))
2743 if (optimize > 0 && io_address_operand (base, HImode))
2745 *l = 2;
2746 return (AS2 (out,%B0-0x20,%B1) CR_TAB
2747 AS2 (out,%A0-0x20,%A1));
2749 return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2750 AS2 (sts,%A0,%A1));
2752 if (reg_base > 0)
2754 if (reg_base == REG_X)
2756 if (reg_src == REG_X)
2758 /* "st X+,r26" and "st -X,r26" are undefined. */
2759 if (!mem_volatile_p && reg_unused_after (insn, src))
2760 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2761 AS2 (st,X,r26) CR_TAB
2762 AS2 (adiw,r26,1) CR_TAB
2763 AS2 (st,X,__tmp_reg__));
2764 else
2765 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2766 AS2 (adiw,r26,1) CR_TAB
2767 AS2 (st,X,__tmp_reg__) CR_TAB
2768 AS2 (sbiw,r26,1) CR_TAB
2769 AS2 (st,X,r26));
2771 else
2773 if (!mem_volatile_p && reg_unused_after (insn, base))
2774 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2775 AS2 (st,X,%B1));
2776 else
2777 return *l=3, (AS2 (adiw,r26,1) CR_TAB
2778 AS2 (st,X,%B1) CR_TAB
2779 AS2 (st,-X,%A1));
2782 else
2783 return *l=2, (AS2 (std,%0+1,%B1) CR_TAB
2784 AS2 (st,%0,%A1));
2786 else if (GET_CODE (base) == PLUS)
2788 int disp = INTVAL (XEXP (base, 1));
2789 reg_base = REGNO (XEXP (base, 0));
2790 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2792 if (reg_base != REG_Y)
2793 fatal_insn ("incorrect insn:",insn);
2795 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2796 return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2797 AS2 (std,Y+63,%B1) CR_TAB
2798 AS2 (std,Y+62,%A1) CR_TAB
2799 AS2 (sbiw,r28,%o0-62));
2801 return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2802 AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2803 AS2 (std,Y+1,%B1) CR_TAB
2804 AS2 (st,Y,%A1) CR_TAB
2805 AS2 (subi,r28,lo8(%o0)) CR_TAB
2806 AS2 (sbci,r29,hi8(%o0)));
2808 if (reg_base == REG_X)
2810 /* (X + d) = R */
2811 if (reg_src == REG_X)
2813 *l = 7;
2814 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
2815 AS2 (mov,__zero_reg__,r27) CR_TAB
2816 AS2 (adiw,r26,%o0+1) CR_TAB
2817 AS2 (st,X,__zero_reg__) CR_TAB
2818 AS2 (st,-X,__tmp_reg__) CR_TAB
2819 AS1 (clr,__zero_reg__) CR_TAB
2820 AS2 (sbiw,r26,%o0));
2822 *l = 4;
2823 return (AS2 (adiw,r26,%o0+1) CR_TAB
2824 AS2 (st,X,%B1) CR_TAB
2825 AS2 (st,-X,%A1) CR_TAB
2826 AS2 (sbiw,r26,%o0));
2828 return *l=2, (AS2 (std,%B0,%B1) CR_TAB
2829 AS2 (std,%A0,%A1));
2831 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2832 return *l=2, (AS2 (st,%0,%B1) CR_TAB
2833 AS2 (st,%0,%A1));
2834 else if (GET_CODE (base) == POST_INC) /* (R++) */
2836 if (mem_volatile_p)
2838 if (REGNO (XEXP (base, 0)) == REG_X)
2840 *l = 4;
2841 return (AS2 (adiw,r26,1) CR_TAB
2842 AS2 (st,X,%B1) CR_TAB
2843 AS2 (st,-X,%A1) CR_TAB
2844 AS2 (adiw,r26,2));
2846 else
2848 *l = 3;
2849 return (AS2 (std,%p0+1,%B1) CR_TAB
2850 AS2 (st,%p0,%A1) CR_TAB
2851 AS2 (adiw,%r0,2));
2855 *l = 2;
2856 return (AS2 (st,%0,%A1) CR_TAB
2857 AS2 (st,%0,%B1));
2859 fatal_insn ("unknown move insn:",insn);
2860 return "";
2863 /* Return 1 if frame pointer for current function required. */
2865 bool
2866 avr_frame_pointer_required_p (void)
2868 return (cfun->calls_alloca
2869 || crtl->args.info.nregs == 0
2870 || get_frame_size () > 0);
2873 /* Returns the condition of compare insn INSN, or UNKNOWN. */
2875 static RTX_CODE
2876 compare_condition (rtx insn)
2878 rtx next = next_real_insn (insn);
2879 RTX_CODE cond = UNKNOWN;
2880 if (next && GET_CODE (next) == JUMP_INSN)
2882 rtx pat = PATTERN (next);
2883 rtx src = SET_SRC (pat);
2884 rtx t = XEXP (src, 0);
2885 cond = GET_CODE (t);
2887 return cond;
2890 /* Returns nonzero if INSN is a tst insn that only tests the sign. */
2892 static int
2893 compare_sign_p (rtx insn)
2895 RTX_CODE cond = compare_condition (insn);
2896 return (cond == GE || cond == LT);
2899 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
2900 that needs to be swapped (GT, GTU, LE, LEU). */
2903 compare_diff_p (rtx insn)
2905 RTX_CODE cond = compare_condition (insn);
2906 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2909 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition. */
2912 compare_eq_p (rtx insn)
2914 RTX_CODE cond = compare_condition (insn);
2915 return (cond == EQ || cond == NE);
2919 /* Output test instruction for HImode. */
2921 const char *
2922 out_tsthi (rtx insn, rtx op, int *l)
2924 if (compare_sign_p (insn))
2926 if (l) *l = 1;
2927 return AS1 (tst,%B0);
2929 if (reg_unused_after (insn, op)
2930 && compare_eq_p (insn))
2932 /* Faster than sbiw if we can clobber the operand. */
2933 if (l) *l = 1;
2934 return AS2 (or,%A0,%B0);
2936 if (test_hard_reg_class (ADDW_REGS, op))
2938 if (l) *l = 1;
2939 return AS2 (sbiw,%0,0);
2941 if (l) *l = 2;
2942 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2943 AS2 (cpc,%B0,__zero_reg__));
2947 /* Output test instruction for SImode. */
2949 const char *
2950 out_tstsi (rtx insn, rtx op, int *l)
2952 if (compare_sign_p (insn))
2954 if (l) *l = 1;
2955 return AS1 (tst,%D0);
2957 if (test_hard_reg_class (ADDW_REGS, op))
2959 if (l) *l = 3;
2960 return (AS2 (sbiw,%A0,0) CR_TAB
2961 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2962 AS2 (cpc,%D0,__zero_reg__));
2964 if (l) *l = 4;
2965 return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2966 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2967 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2968 AS2 (cpc,%D0,__zero_reg__));
2972 /* Generate asm equivalent for various shifts.
2973 Shift count is a CONST_INT, MEM or REG.
2974 This only handles cases that are not already
2975 carefully hand-optimized in ?sh??i3_out. */
2977 void
2978 out_shift_with_cnt (const char *templ, rtx insn, rtx operands[],
2979 int *len, int t_len)
2981 rtx op[10];
2982 char str[500];
2983 int second_label = 1;
2984 int saved_in_tmp = 0;
2985 int use_zero_reg = 0;
2987 op[0] = operands[0];
2988 op[1] = operands[1];
2989 op[2] = operands[2];
2990 op[3] = operands[3];
2991 str[0] = 0;
2993 if (len)
2994 *len = 1;
2996 if (GET_CODE (operands[2]) == CONST_INT)
2998 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2999 int count = INTVAL (operands[2]);
3000 int max_len = 10; /* If larger than this, always use a loop. */
3002 if (count <= 0)
3004 if (len)
3005 *len = 0;
3006 return;
3009 if (count < 8 && !scratch)
3010 use_zero_reg = 1;
3012 if (optimize_size)
3013 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
3015 if (t_len * count <= max_len)
3017 /* Output shifts inline with no loop - faster. */
3018 if (len)
3019 *len = t_len * count;
3020 else
3022 while (count-- > 0)
3023 output_asm_insn (templ, op);
3026 return;
3029 if (scratch)
3031 if (!len)
3032 strcat (str, AS2 (ldi,%3,%2));
3034 else if (use_zero_reg)
3036 /* Hack to save one word: use __zero_reg__ as loop counter.
3037 Set one bit, then shift in a loop until it is 0 again. */
3039 op[3] = zero_reg_rtx;
3040 if (len)
3041 *len = 2;
3042 else
3043 strcat (str, ("set" CR_TAB
3044 AS2 (bld,%3,%2-1)));
3046 else
3048 /* No scratch register available, use one from LD_REGS (saved in
3049 __tmp_reg__) that doesn't overlap with registers to shift. */
3051 op[3] = gen_rtx_REG (QImode,
3052 ((true_regnum (operands[0]) - 1) & 15) + 16);
3053 op[4] = tmp_reg_rtx;
3054 saved_in_tmp = 1;
3056 if (len)
3057 *len = 3; /* Includes "mov %3,%4" after the loop. */
3058 else
3059 strcat (str, (AS2 (mov,%4,%3) CR_TAB
3060 AS2 (ldi,%3,%2)));
3063 second_label = 0;
3065 else if (GET_CODE (operands[2]) == MEM)
3067 rtx op_mov[10];
3069 op[3] = op_mov[0] = tmp_reg_rtx;
3070 op_mov[1] = op[2];
3072 if (len)
3073 out_movqi_r_mr (insn, op_mov, len);
3074 else
3075 output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
3077 else if (register_operand (operands[2], QImode))
3079 if (reg_unused_after (insn, operands[2]))
3080 op[3] = op[2];
3081 else
3083 op[3] = tmp_reg_rtx;
3084 if (!len)
3085 strcat (str, (AS2 (mov,%3,%2) CR_TAB));
3088 else
3089 fatal_insn ("bad shift insn:", insn);
3091 if (second_label)
3093 if (len)
3094 ++*len;
3095 else
3096 strcat (str, AS1 (rjmp,2f));
3099 if (len)
3100 *len += t_len + 2; /* template + dec + brXX */
3101 else
3103 strcat (str, "\n1:\t");
3104 strcat (str, templ);
3105 strcat (str, second_label ? "\n2:\t" : "\n\t");
3106 strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
3107 strcat (str, CR_TAB);
3108 strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
3109 if (saved_in_tmp)
3110 strcat (str, (CR_TAB AS2 (mov,%3,%4)));
3111 output_asm_insn (str, op);
3116 /* 8bit shift left ((char)x << i) */
3118 const char *
3119 ashlqi3_out (rtx insn, rtx operands[], int *len)
3121 if (GET_CODE (operands[2]) == CONST_INT)
3123 int k;
3125 if (!len)
3126 len = &k;
3128 switch (INTVAL (operands[2]))
3130 default:
3131 if (INTVAL (operands[2]) < 8)
3132 break;
3134 *len = 1;
3135 return AS1 (clr,%0);
3137 case 1:
3138 *len = 1;
3139 return AS1 (lsl,%0);
3141 case 2:
3142 *len = 2;
3143 return (AS1 (lsl,%0) CR_TAB
3144 AS1 (lsl,%0));
3146 case 3:
3147 *len = 3;
3148 return (AS1 (lsl,%0) CR_TAB
3149 AS1 (lsl,%0) CR_TAB
3150 AS1 (lsl,%0));
3152 case 4:
3153 if (test_hard_reg_class (LD_REGS, operands[0]))
3155 *len = 2;
3156 return (AS1 (swap,%0) CR_TAB
3157 AS2 (andi,%0,0xf0));
3159 *len = 4;
3160 return (AS1 (lsl,%0) CR_TAB
3161 AS1 (lsl,%0) CR_TAB
3162 AS1 (lsl,%0) CR_TAB
3163 AS1 (lsl,%0));
3165 case 5:
3166 if (test_hard_reg_class (LD_REGS, operands[0]))
3168 *len = 3;
3169 return (AS1 (swap,%0) CR_TAB
3170 AS1 (lsl,%0) CR_TAB
3171 AS2 (andi,%0,0xe0));
3173 *len = 5;
3174 return (AS1 (lsl,%0) CR_TAB
3175 AS1 (lsl,%0) CR_TAB
3176 AS1 (lsl,%0) CR_TAB
3177 AS1 (lsl,%0) CR_TAB
3178 AS1 (lsl,%0));
3180 case 6:
3181 if (test_hard_reg_class (LD_REGS, operands[0]))
3183 *len = 4;
3184 return (AS1 (swap,%0) CR_TAB
3185 AS1 (lsl,%0) CR_TAB
3186 AS1 (lsl,%0) CR_TAB
3187 AS2 (andi,%0,0xc0));
3189 *len = 6;
3190 return (AS1 (lsl,%0) CR_TAB
3191 AS1 (lsl,%0) CR_TAB
3192 AS1 (lsl,%0) CR_TAB
3193 AS1 (lsl,%0) CR_TAB
3194 AS1 (lsl,%0) CR_TAB
3195 AS1 (lsl,%0));
3197 case 7:
3198 *len = 3;
3199 return (AS1 (ror,%0) CR_TAB
3200 AS1 (clr,%0) CR_TAB
3201 AS1 (ror,%0));
3204 else if (CONSTANT_P (operands[2]))
3205 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3207 out_shift_with_cnt (AS1 (lsl,%0),
3208 insn, operands, len, 1);
3209 return "";
3213 /* 16bit shift left ((short)x << i) */
3215 const char *
3216 ashlhi3_out (rtx insn, rtx operands[], int *len)
3218 if (GET_CODE (operands[2]) == CONST_INT)
3220 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3221 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3222 int k;
3223 int *t = len;
3225 if (!len)
3226 len = &k;
3228 switch (INTVAL (operands[2]))
3230 default:
3231 if (INTVAL (operands[2]) < 16)
3232 break;
3234 *len = 2;
3235 return (AS1 (clr,%B0) CR_TAB
3236 AS1 (clr,%A0));
3238 case 4:
3239 if (optimize_size && scratch)
3240 break; /* 5 */
3241 if (ldi_ok)
3243 *len = 6;
3244 return (AS1 (swap,%A0) CR_TAB
3245 AS1 (swap,%B0) CR_TAB
3246 AS2 (andi,%B0,0xf0) CR_TAB
3247 AS2 (eor,%B0,%A0) CR_TAB
3248 AS2 (andi,%A0,0xf0) CR_TAB
3249 AS2 (eor,%B0,%A0));
3251 if (scratch)
3253 *len = 7;
3254 return (AS1 (swap,%A0) CR_TAB
3255 AS1 (swap,%B0) CR_TAB
3256 AS2 (ldi,%3,0xf0) CR_TAB
3257 AS2 (and,%B0,%3) CR_TAB
3258 AS2 (eor,%B0,%A0) CR_TAB
3259 AS2 (and,%A0,%3) CR_TAB
3260 AS2 (eor,%B0,%A0));
3262 break; /* optimize_size ? 6 : 8 */
3264 case 5:
3265 if (optimize_size)
3266 break; /* scratch ? 5 : 6 */
3267 if (ldi_ok)
3269 *len = 8;
3270 return (AS1 (lsl,%A0) CR_TAB
3271 AS1 (rol,%B0) CR_TAB
3272 AS1 (swap,%A0) CR_TAB
3273 AS1 (swap,%B0) CR_TAB
3274 AS2 (andi,%B0,0xf0) CR_TAB
3275 AS2 (eor,%B0,%A0) CR_TAB
3276 AS2 (andi,%A0,0xf0) CR_TAB
3277 AS2 (eor,%B0,%A0));
3279 if (scratch)
3281 *len = 9;
3282 return (AS1 (lsl,%A0) CR_TAB
3283 AS1 (rol,%B0) CR_TAB
3284 AS1 (swap,%A0) CR_TAB
3285 AS1 (swap,%B0) CR_TAB
3286 AS2 (ldi,%3,0xf0) CR_TAB
3287 AS2 (and,%B0,%3) CR_TAB
3288 AS2 (eor,%B0,%A0) CR_TAB
3289 AS2 (and,%A0,%3) CR_TAB
3290 AS2 (eor,%B0,%A0));
3292 break; /* 10 */
3294 case 6:
3295 if (optimize_size)
3296 break; /* scratch ? 5 : 6 */
3297 *len = 9;
3298 return (AS1 (clr,__tmp_reg__) CR_TAB
3299 AS1 (lsr,%B0) CR_TAB
3300 AS1 (ror,%A0) CR_TAB
3301 AS1 (ror,__tmp_reg__) CR_TAB
3302 AS1 (lsr,%B0) CR_TAB
3303 AS1 (ror,%A0) CR_TAB
3304 AS1 (ror,__tmp_reg__) CR_TAB
3305 AS2 (mov,%B0,%A0) CR_TAB
3306 AS2 (mov,%A0,__tmp_reg__));
3308 case 7:
3309 *len = 5;
3310 return (AS1 (lsr,%B0) CR_TAB
3311 AS2 (mov,%B0,%A0) CR_TAB
3312 AS1 (clr,%A0) CR_TAB
3313 AS1 (ror,%B0) CR_TAB
3314 AS1 (ror,%A0));
3316 case 8:
3317 return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3318 AS1 (clr,%A0));
3320 case 9:
3321 *len = 3;
3322 return (AS2 (mov,%B0,%A0) CR_TAB
3323 AS1 (clr,%A0) CR_TAB
3324 AS1 (lsl,%B0));
3326 case 10:
3327 *len = 4;
3328 return (AS2 (mov,%B0,%A0) CR_TAB
3329 AS1 (clr,%A0) CR_TAB
3330 AS1 (lsl,%B0) CR_TAB
3331 AS1 (lsl,%B0));
3333 case 11:
3334 *len = 5;
3335 return (AS2 (mov,%B0,%A0) CR_TAB
3336 AS1 (clr,%A0) CR_TAB
3337 AS1 (lsl,%B0) CR_TAB
3338 AS1 (lsl,%B0) CR_TAB
3339 AS1 (lsl,%B0));
3341 case 12:
3342 if (ldi_ok)
3344 *len = 4;
3345 return (AS2 (mov,%B0,%A0) CR_TAB
3346 AS1 (clr,%A0) CR_TAB
3347 AS1 (swap,%B0) CR_TAB
3348 AS2 (andi,%B0,0xf0));
3350 if (scratch)
3352 *len = 5;
3353 return (AS2 (mov,%B0,%A0) CR_TAB
3354 AS1 (clr,%A0) CR_TAB
3355 AS1 (swap,%B0) CR_TAB
3356 AS2 (ldi,%3,0xf0) CR_TAB
3357 AS2 (and,%B0,%3));
3359 *len = 6;
3360 return (AS2 (mov,%B0,%A0) CR_TAB
3361 AS1 (clr,%A0) CR_TAB
3362 AS1 (lsl,%B0) CR_TAB
3363 AS1 (lsl,%B0) CR_TAB
3364 AS1 (lsl,%B0) CR_TAB
3365 AS1 (lsl,%B0));
3367 case 13:
3368 if (ldi_ok)
3370 *len = 5;
3371 return (AS2 (mov,%B0,%A0) CR_TAB
3372 AS1 (clr,%A0) CR_TAB
3373 AS1 (swap,%B0) CR_TAB
3374 AS1 (lsl,%B0) CR_TAB
3375 AS2 (andi,%B0,0xe0));
3377 if (AVR_HAVE_MUL && scratch)
3379 *len = 5;
3380 return (AS2 (ldi,%3,0x20) CR_TAB
3381 AS2 (mul,%A0,%3) CR_TAB
3382 AS2 (mov,%B0,r0) CR_TAB
3383 AS1 (clr,%A0) CR_TAB
3384 AS1 (clr,__zero_reg__));
3386 if (optimize_size && scratch)
3387 break; /* 5 */
3388 if (scratch)
3390 *len = 6;
3391 return (AS2 (mov,%B0,%A0) CR_TAB
3392 AS1 (clr,%A0) CR_TAB
3393 AS1 (swap,%B0) CR_TAB
3394 AS1 (lsl,%B0) CR_TAB
3395 AS2 (ldi,%3,0xe0) CR_TAB
3396 AS2 (and,%B0,%3));
3398 if (AVR_HAVE_MUL)
3400 *len = 6;
3401 return ("set" CR_TAB
3402 AS2 (bld,r1,5) CR_TAB
3403 AS2 (mul,%A0,r1) CR_TAB
3404 AS2 (mov,%B0,r0) CR_TAB
3405 AS1 (clr,%A0) CR_TAB
3406 AS1 (clr,__zero_reg__));
3408 *len = 7;
3409 return (AS2 (mov,%B0,%A0) CR_TAB
3410 AS1 (clr,%A0) CR_TAB
3411 AS1 (lsl,%B0) CR_TAB
3412 AS1 (lsl,%B0) CR_TAB
3413 AS1 (lsl,%B0) CR_TAB
3414 AS1 (lsl,%B0) CR_TAB
3415 AS1 (lsl,%B0));
3417 case 14:
3418 if (AVR_HAVE_MUL && ldi_ok)
3420 *len = 5;
3421 return (AS2 (ldi,%B0,0x40) CR_TAB
3422 AS2 (mul,%A0,%B0) CR_TAB
3423 AS2 (mov,%B0,r0) CR_TAB
3424 AS1 (clr,%A0) CR_TAB
3425 AS1 (clr,__zero_reg__));
3427 if (AVR_HAVE_MUL && scratch)
3429 *len = 5;
3430 return (AS2 (ldi,%3,0x40) CR_TAB
3431 AS2 (mul,%A0,%3) CR_TAB
3432 AS2 (mov,%B0,r0) CR_TAB
3433 AS1 (clr,%A0) CR_TAB
3434 AS1 (clr,__zero_reg__));
3436 if (optimize_size && ldi_ok)
3438 *len = 5;
3439 return (AS2 (mov,%B0,%A0) CR_TAB
3440 AS2 (ldi,%A0,6) "\n1:\t"
3441 AS1 (lsl,%B0) CR_TAB
3442 AS1 (dec,%A0) CR_TAB
3443 AS1 (brne,1b));
3445 if (optimize_size && scratch)
3446 break; /* 5 */
3447 *len = 6;
3448 return (AS1 (clr,%B0) CR_TAB
3449 AS1 (lsr,%A0) CR_TAB
3450 AS1 (ror,%B0) CR_TAB
3451 AS1 (lsr,%A0) CR_TAB
3452 AS1 (ror,%B0) CR_TAB
3453 AS1 (clr,%A0));
3455 case 15:
3456 *len = 4;
3457 return (AS1 (clr,%B0) CR_TAB
3458 AS1 (lsr,%A0) CR_TAB
3459 AS1 (ror,%B0) CR_TAB
3460 AS1 (clr,%A0));
3462 len = t;
3464 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3465 AS1 (rol,%B0)),
3466 insn, operands, len, 2);
3467 return "";
3471 /* 32bit shift left ((long)x << i) */
3473 const char *
3474 ashlsi3_out (rtx insn, rtx operands[], int *len)
3476 if (GET_CODE (operands[2]) == CONST_INT)
3478 int k;
3479 int *t = len;
3481 if (!len)
3482 len = &k;
3484 switch (INTVAL (operands[2]))
3486 default:
3487 if (INTVAL (operands[2]) < 32)
3488 break;
3490 if (AVR_HAVE_MOVW)
3491 return *len = 3, (AS1 (clr,%D0) CR_TAB
3492 AS1 (clr,%C0) CR_TAB
3493 AS2 (movw,%A0,%C0));
3494 *len = 4;
3495 return (AS1 (clr,%D0) CR_TAB
3496 AS1 (clr,%C0) CR_TAB
3497 AS1 (clr,%B0) CR_TAB
3498 AS1 (clr,%A0));
3500 case 8:
3502 int reg0 = true_regnum (operands[0]);
3503 int reg1 = true_regnum (operands[1]);
3504 *len = 4;
3505 if (reg0 >= reg1)
3506 return (AS2 (mov,%D0,%C1) CR_TAB
3507 AS2 (mov,%C0,%B1) CR_TAB
3508 AS2 (mov,%B0,%A1) CR_TAB
3509 AS1 (clr,%A0));
3510 else
3511 return (AS1 (clr,%A0) CR_TAB
3512 AS2 (mov,%B0,%A1) CR_TAB
3513 AS2 (mov,%C0,%B1) CR_TAB
3514 AS2 (mov,%D0,%C1));
3517 case 16:
3519 int reg0 = true_regnum (operands[0]);
3520 int reg1 = true_regnum (operands[1]);
3521 if (reg0 + 2 == reg1)
3522 return *len = 2, (AS1 (clr,%B0) CR_TAB
3523 AS1 (clr,%A0));
3524 if (AVR_HAVE_MOVW)
3525 return *len = 3, (AS2 (movw,%C0,%A1) CR_TAB
3526 AS1 (clr,%B0) CR_TAB
3527 AS1 (clr,%A0));
3528 else
3529 return *len = 4, (AS2 (mov,%C0,%A1) CR_TAB
3530 AS2 (mov,%D0,%B1) CR_TAB
3531 AS1 (clr,%B0) CR_TAB
3532 AS1 (clr,%A0));
3535 case 24:
3536 *len = 4;
3537 return (AS2 (mov,%D0,%A1) CR_TAB
3538 AS1 (clr,%C0) CR_TAB
3539 AS1 (clr,%B0) CR_TAB
3540 AS1 (clr,%A0));
3542 case 31:
3543 *len = 6;
3544 return (AS1 (clr,%D0) CR_TAB
3545 AS1 (lsr,%A0) CR_TAB
3546 AS1 (ror,%D0) CR_TAB
3547 AS1 (clr,%C0) CR_TAB
3548 AS1 (clr,%B0) CR_TAB
3549 AS1 (clr,%A0));
3551 len = t;
3553 out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3554 AS1 (rol,%B0) CR_TAB
3555 AS1 (rol,%C0) CR_TAB
3556 AS1 (rol,%D0)),
3557 insn, operands, len, 4);
3558 return "";
3561 /* 8bit arithmetic shift right ((signed char)x >> i) */
3563 const char *
3564 ashrqi3_out (rtx insn, rtx operands[], int *len)
3566 if (GET_CODE (operands[2]) == CONST_INT)
3568 int k;
3570 if (!len)
3571 len = &k;
3573 switch (INTVAL (operands[2]))
3575 case 1:
3576 *len = 1;
3577 return AS1 (asr,%0);
3579 case 2:
3580 *len = 2;
3581 return (AS1 (asr,%0) CR_TAB
3582 AS1 (asr,%0));
3584 case 3:
3585 *len = 3;
3586 return (AS1 (asr,%0) CR_TAB
3587 AS1 (asr,%0) CR_TAB
3588 AS1 (asr,%0));
3590 case 4:
3591 *len = 4;
3592 return (AS1 (asr,%0) CR_TAB
3593 AS1 (asr,%0) CR_TAB
3594 AS1 (asr,%0) CR_TAB
3595 AS1 (asr,%0));
3597 case 5:
3598 *len = 5;
3599 return (AS1 (asr,%0) CR_TAB
3600 AS1 (asr,%0) CR_TAB
3601 AS1 (asr,%0) CR_TAB
3602 AS1 (asr,%0) CR_TAB
3603 AS1 (asr,%0));
3605 case 6:
3606 *len = 4;
3607 return (AS2 (bst,%0,6) CR_TAB
3608 AS1 (lsl,%0) CR_TAB
3609 AS2 (sbc,%0,%0) CR_TAB
3610 AS2 (bld,%0,0));
3612 default:
3613 if (INTVAL (operands[2]) < 8)
3614 break;
3616 /* fall through */
3618 case 7:
3619 *len = 2;
3620 return (AS1 (lsl,%0) CR_TAB
3621 AS2 (sbc,%0,%0));
3624 else if (CONSTANT_P (operands[2]))
3625 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3627 out_shift_with_cnt (AS1 (asr,%0),
3628 insn, operands, len, 1);
3629 return "";
3633 /* 16bit arithmetic shift right ((signed short)x >> i) */
3635 const char *
3636 ashrhi3_out (rtx insn, rtx operands[], int *len)
3638 if (GET_CODE (operands[2]) == CONST_INT)
3640 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3641 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3642 int k;
3643 int *t = len;
3645 if (!len)
3646 len = &k;
3648 switch (INTVAL (operands[2]))
3650 case 4:
3651 case 5:
3652 /* XXX try to optimize this too? */
3653 break;
3655 case 6:
3656 if (optimize_size)
3657 break; /* scratch ? 5 : 6 */
3658 *len = 8;
3659 return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3660 AS2 (mov,%A0,%B0) CR_TAB
3661 AS1 (lsl,__tmp_reg__) CR_TAB
3662 AS1 (rol,%A0) CR_TAB
3663 AS2 (sbc,%B0,%B0) CR_TAB
3664 AS1 (lsl,__tmp_reg__) CR_TAB
3665 AS1 (rol,%A0) CR_TAB
3666 AS1 (rol,%B0));
3668 case 7:
3669 *len = 4;
3670 return (AS1 (lsl,%A0) CR_TAB
3671 AS2 (mov,%A0,%B0) CR_TAB
3672 AS1 (rol,%A0) CR_TAB
3673 AS2 (sbc,%B0,%B0));
3675 case 8:
3677 int reg0 = true_regnum (operands[0]);
3678 int reg1 = true_regnum (operands[1]);
3680 if (reg0 == reg1)
3681 return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3682 AS1 (lsl,%B0) CR_TAB
3683 AS2 (sbc,%B0,%B0));
3684 else
3685 return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3686 AS1 (clr,%B0) CR_TAB
3687 AS2 (sbrc,%A0,7) CR_TAB
3688 AS1 (dec,%B0));
3691 case 9:
3692 *len = 4;
3693 return (AS2 (mov,%A0,%B0) CR_TAB
3694 AS1 (lsl,%B0) CR_TAB
3695 AS2 (sbc,%B0,%B0) CR_TAB
3696 AS1 (asr,%A0));
3698 case 10:
3699 *len = 5;
3700 return (AS2 (mov,%A0,%B0) CR_TAB
3701 AS1 (lsl,%B0) CR_TAB
3702 AS2 (sbc,%B0,%B0) CR_TAB
3703 AS1 (asr,%A0) CR_TAB
3704 AS1 (asr,%A0));
3706 case 11:
3707 if (AVR_HAVE_MUL && ldi_ok)
3709 *len = 5;
3710 return (AS2 (ldi,%A0,0x20) CR_TAB
3711 AS2 (muls,%B0,%A0) CR_TAB
3712 AS2 (mov,%A0,r1) CR_TAB
3713 AS2 (sbc,%B0,%B0) CR_TAB
3714 AS1 (clr,__zero_reg__));
3716 if (optimize_size && scratch)
3717 break; /* 5 */
3718 *len = 6;
3719 return (AS2 (mov,%A0,%B0) CR_TAB
3720 AS1 (lsl,%B0) CR_TAB
3721 AS2 (sbc,%B0,%B0) CR_TAB
3722 AS1 (asr,%A0) CR_TAB
3723 AS1 (asr,%A0) CR_TAB
3724 AS1 (asr,%A0));
3726 case 12:
3727 if (AVR_HAVE_MUL && ldi_ok)
3729 *len = 5;
3730 return (AS2 (ldi,%A0,0x10) CR_TAB
3731 AS2 (muls,%B0,%A0) CR_TAB
3732 AS2 (mov,%A0,r1) CR_TAB
3733 AS2 (sbc,%B0,%B0) CR_TAB
3734 AS1 (clr,__zero_reg__));
3736 if (optimize_size && scratch)
3737 break; /* 5 */
3738 *len = 7;
3739 return (AS2 (mov,%A0,%B0) CR_TAB
3740 AS1 (lsl,%B0) CR_TAB
3741 AS2 (sbc,%B0,%B0) CR_TAB
3742 AS1 (asr,%A0) CR_TAB
3743 AS1 (asr,%A0) CR_TAB
3744 AS1 (asr,%A0) CR_TAB
3745 AS1 (asr,%A0));
3747 case 13:
3748 if (AVR_HAVE_MUL && ldi_ok)
3750 *len = 5;
3751 return (AS2 (ldi,%A0,0x08) CR_TAB
3752 AS2 (muls,%B0,%A0) CR_TAB
3753 AS2 (mov,%A0,r1) CR_TAB
3754 AS2 (sbc,%B0,%B0) CR_TAB
3755 AS1 (clr,__zero_reg__));
3757 if (optimize_size)
3758 break; /* scratch ? 5 : 7 */
3759 *len = 8;
3760 return (AS2 (mov,%A0,%B0) CR_TAB
3761 AS1 (lsl,%B0) CR_TAB
3762 AS2 (sbc,%B0,%B0) CR_TAB
3763 AS1 (asr,%A0) CR_TAB
3764 AS1 (asr,%A0) CR_TAB
3765 AS1 (asr,%A0) CR_TAB
3766 AS1 (asr,%A0) CR_TAB
3767 AS1 (asr,%A0));
3769 case 14:
3770 *len = 5;
3771 return (AS1 (lsl,%B0) CR_TAB
3772 AS2 (sbc,%A0,%A0) CR_TAB
3773 AS1 (lsl,%B0) CR_TAB
3774 AS2 (mov,%B0,%A0) CR_TAB
3775 AS1 (rol,%A0));
3777 default:
3778 if (INTVAL (operands[2]) < 16)
3779 break;
3781 /* fall through */
3783 case 15:
3784 return *len = 3, (AS1 (lsl,%B0) CR_TAB
3785 AS2 (sbc,%A0,%A0) CR_TAB
3786 AS2 (mov,%B0,%A0));
3788 len = t;
3790 out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3791 AS1 (ror,%A0)),
3792 insn, operands, len, 2);
3793 return "";
3797 /* 32bit arithmetic shift right ((signed long)x >> i) */
3799 const char *
3800 ashrsi3_out (rtx insn, rtx operands[], int *len)
3802 if (GET_CODE (operands[2]) == CONST_INT)
3804 int k;
3805 int *t = len;
3807 if (!len)
3808 len = &k;
3810 switch (INTVAL (operands[2]))
3812 case 8:
3814 int reg0 = true_regnum (operands[0]);
3815 int reg1 = true_regnum (operands[1]);
3816 *len=6;
3817 if (reg0 <= reg1)
3818 return (AS2 (mov,%A0,%B1) CR_TAB
3819 AS2 (mov,%B0,%C1) CR_TAB
3820 AS2 (mov,%C0,%D1) CR_TAB
3821 AS1 (clr,%D0) CR_TAB
3822 AS2 (sbrc,%C0,7) CR_TAB
3823 AS1 (dec,%D0));
3824 else
3825 return (AS1 (clr,%D0) CR_TAB
3826 AS2 (sbrc,%D1,7) CR_TAB
3827 AS1 (dec,%D0) CR_TAB
3828 AS2 (mov,%C0,%D1) CR_TAB
3829 AS2 (mov,%B0,%C1) CR_TAB
3830 AS2 (mov,%A0,%B1));
3833 case 16:
3835 int reg0 = true_regnum (operands[0]);
3836 int reg1 = true_regnum (operands[1]);
3838 if (reg0 == reg1 + 2)
3839 return *len = 4, (AS1 (clr,%D0) CR_TAB
3840 AS2 (sbrc,%B0,7) CR_TAB
3841 AS1 (com,%D0) CR_TAB
3842 AS2 (mov,%C0,%D0));
3843 if (AVR_HAVE_MOVW)
3844 return *len = 5, (AS2 (movw,%A0,%C1) CR_TAB
3845 AS1 (clr,%D0) CR_TAB
3846 AS2 (sbrc,%B0,7) CR_TAB
3847 AS1 (com,%D0) CR_TAB
3848 AS2 (mov,%C0,%D0));
3849 else
3850 return *len = 6, (AS2 (mov,%B0,%D1) CR_TAB
3851 AS2 (mov,%A0,%C1) CR_TAB
3852 AS1 (clr,%D0) CR_TAB
3853 AS2 (sbrc,%B0,7) CR_TAB
3854 AS1 (com,%D0) CR_TAB
3855 AS2 (mov,%C0,%D0));
3858 case 24:
3859 return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3860 AS1 (clr,%D0) CR_TAB
3861 AS2 (sbrc,%A0,7) CR_TAB
3862 AS1 (com,%D0) CR_TAB
3863 AS2 (mov,%B0,%D0) CR_TAB
3864 AS2 (mov,%C0,%D0));
3866 default:
3867 if (INTVAL (operands[2]) < 32)
3868 break;
3870 /* fall through */
3872 case 31:
3873 if (AVR_HAVE_MOVW)
3874 return *len = 4, (AS1 (lsl,%D0) CR_TAB
3875 AS2 (sbc,%A0,%A0) CR_TAB
3876 AS2 (mov,%B0,%A0) CR_TAB
3877 AS2 (movw,%C0,%A0));
3878 else
3879 return *len = 5, (AS1 (lsl,%D0) CR_TAB
3880 AS2 (sbc,%A0,%A0) CR_TAB
3881 AS2 (mov,%B0,%A0) CR_TAB
3882 AS2 (mov,%C0,%A0) CR_TAB
3883 AS2 (mov,%D0,%A0));
3885 len = t;
3887 out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
3888 AS1 (ror,%C0) CR_TAB
3889 AS1 (ror,%B0) CR_TAB
3890 AS1 (ror,%A0)),
3891 insn, operands, len, 4);
3892 return "";
3895 /* 8bit logic shift right ((unsigned char)x >> i) */
3897 const char *
3898 lshrqi3_out (rtx insn, rtx operands[], int *len)
3900 if (GET_CODE (operands[2]) == CONST_INT)
3902 int k;
3904 if (!len)
3905 len = &k;
3907 switch (INTVAL (operands[2]))
3909 default:
3910 if (INTVAL (operands[2]) < 8)
3911 break;
3913 *len = 1;
3914 return AS1 (clr,%0);
3916 case 1:
3917 *len = 1;
3918 return AS1 (lsr,%0);
3920 case 2:
3921 *len = 2;
3922 return (AS1 (lsr,%0) CR_TAB
3923 AS1 (lsr,%0));
3924 case 3:
3925 *len = 3;
3926 return (AS1 (lsr,%0) CR_TAB
3927 AS1 (lsr,%0) CR_TAB
3928 AS1 (lsr,%0));
3930 case 4:
3931 if (test_hard_reg_class (LD_REGS, operands[0]))
3933 *len=2;
3934 return (AS1 (swap,%0) CR_TAB
3935 AS2 (andi,%0,0x0f));
3937 *len = 4;
3938 return (AS1 (lsr,%0) CR_TAB
3939 AS1 (lsr,%0) CR_TAB
3940 AS1 (lsr,%0) CR_TAB
3941 AS1 (lsr,%0));
3943 case 5:
3944 if (test_hard_reg_class (LD_REGS, operands[0]))
3946 *len = 3;
3947 return (AS1 (swap,%0) CR_TAB
3948 AS1 (lsr,%0) CR_TAB
3949 AS2 (andi,%0,0x7));
3951 *len = 5;
3952 return (AS1 (lsr,%0) CR_TAB
3953 AS1 (lsr,%0) CR_TAB
3954 AS1 (lsr,%0) CR_TAB
3955 AS1 (lsr,%0) CR_TAB
3956 AS1 (lsr,%0));
3958 case 6:
3959 if (test_hard_reg_class (LD_REGS, operands[0]))
3961 *len = 4;
3962 return (AS1 (swap,%0) CR_TAB
3963 AS1 (lsr,%0) CR_TAB
3964 AS1 (lsr,%0) CR_TAB
3965 AS2 (andi,%0,0x3));
3967 *len = 6;
3968 return (AS1 (lsr,%0) CR_TAB
3969 AS1 (lsr,%0) CR_TAB
3970 AS1 (lsr,%0) CR_TAB
3971 AS1 (lsr,%0) CR_TAB
3972 AS1 (lsr,%0) CR_TAB
3973 AS1 (lsr,%0));
3975 case 7:
3976 *len = 3;
3977 return (AS1 (rol,%0) CR_TAB
3978 AS1 (clr,%0) CR_TAB
3979 AS1 (rol,%0));
3982 else if (CONSTANT_P (operands[2]))
3983 fatal_insn ("internal compiler error. Incorrect shift:", insn);
3985 out_shift_with_cnt (AS1 (lsr,%0),
3986 insn, operands, len, 1);
3987 return "";
3990 /* 16bit logic shift right ((unsigned short)x >> i) */
3992 const char *
3993 lshrhi3_out (rtx insn, rtx operands[], int *len)
3995 if (GET_CODE (operands[2]) == CONST_INT)
3997 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3998 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3999 int k;
4000 int *t = len;
4002 if (!len)
4003 len = &k;
4005 switch (INTVAL (operands[2]))
4007 default:
4008 if (INTVAL (operands[2]) < 16)
4009 break;
4011 *len = 2;
4012 return (AS1 (clr,%B0) CR_TAB
4013 AS1 (clr,%A0));
4015 case 4:
4016 if (optimize_size && scratch)
4017 break; /* 5 */
4018 if (ldi_ok)
4020 *len = 6;
4021 return (AS1 (swap,%B0) CR_TAB
4022 AS1 (swap,%A0) CR_TAB
4023 AS2 (andi,%A0,0x0f) CR_TAB
4024 AS2 (eor,%A0,%B0) CR_TAB
4025 AS2 (andi,%B0,0x0f) CR_TAB
4026 AS2 (eor,%A0,%B0));
4028 if (scratch)
4030 *len = 7;
4031 return (AS1 (swap,%B0) CR_TAB
4032 AS1 (swap,%A0) CR_TAB
4033 AS2 (ldi,%3,0x0f) CR_TAB
4034 AS2 (and,%A0,%3) CR_TAB
4035 AS2 (eor,%A0,%B0) CR_TAB
4036 AS2 (and,%B0,%3) CR_TAB
4037 AS2 (eor,%A0,%B0));
4039 break; /* optimize_size ? 6 : 8 */
4041 case 5:
4042 if (optimize_size)
4043 break; /* scratch ? 5 : 6 */
4044 if (ldi_ok)
4046 *len = 8;
4047 return (AS1 (lsr,%B0) CR_TAB
4048 AS1 (ror,%A0) CR_TAB
4049 AS1 (swap,%B0) CR_TAB
4050 AS1 (swap,%A0) CR_TAB
4051 AS2 (andi,%A0,0x0f) CR_TAB
4052 AS2 (eor,%A0,%B0) CR_TAB
4053 AS2 (andi,%B0,0x0f) CR_TAB
4054 AS2 (eor,%A0,%B0));
4056 if (scratch)
4058 *len = 9;
4059 return (AS1 (lsr,%B0) CR_TAB
4060 AS1 (ror,%A0) CR_TAB
4061 AS1 (swap,%B0) CR_TAB
4062 AS1 (swap,%A0) CR_TAB
4063 AS2 (ldi,%3,0x0f) CR_TAB
4064 AS2 (and,%A0,%3) CR_TAB
4065 AS2 (eor,%A0,%B0) CR_TAB
4066 AS2 (and,%B0,%3) CR_TAB
4067 AS2 (eor,%A0,%B0));
4069 break; /* 10 */
4071 case 6:
4072 if (optimize_size)
4073 break; /* scratch ? 5 : 6 */
4074 *len = 9;
4075 return (AS1 (clr,__tmp_reg__) CR_TAB
4076 AS1 (lsl,%A0) CR_TAB
4077 AS1 (rol,%B0) CR_TAB
4078 AS1 (rol,__tmp_reg__) CR_TAB
4079 AS1 (lsl,%A0) CR_TAB
4080 AS1 (rol,%B0) CR_TAB
4081 AS1 (rol,__tmp_reg__) CR_TAB
4082 AS2 (mov,%A0,%B0) CR_TAB
4083 AS2 (mov,%B0,__tmp_reg__));
4085 case 7:
4086 *len = 5;
4087 return (AS1 (lsl,%A0) CR_TAB
4088 AS2 (mov,%A0,%B0) CR_TAB
4089 AS1 (rol,%A0) CR_TAB
4090 AS2 (sbc,%B0,%B0) CR_TAB
4091 AS1 (neg,%B0));
4093 case 8:
4094 return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
4095 AS1 (clr,%B0));
4097 case 9:
4098 *len = 3;
4099 return (AS2 (mov,%A0,%B0) CR_TAB
4100 AS1 (clr,%B0) CR_TAB
4101 AS1 (lsr,%A0));
4103 case 10:
4104 *len = 4;
4105 return (AS2 (mov,%A0,%B0) CR_TAB
4106 AS1 (clr,%B0) CR_TAB
4107 AS1 (lsr,%A0) CR_TAB
4108 AS1 (lsr,%A0));
4110 case 11:
4111 *len = 5;
4112 return (AS2 (mov,%A0,%B0) CR_TAB
4113 AS1 (clr,%B0) CR_TAB
4114 AS1 (lsr,%A0) CR_TAB
4115 AS1 (lsr,%A0) CR_TAB
4116 AS1 (lsr,%A0));
4118 case 12:
4119 if (ldi_ok)
4121 *len = 4;
4122 return (AS2 (mov,%A0,%B0) CR_TAB
4123 AS1 (clr,%B0) CR_TAB
4124 AS1 (swap,%A0) CR_TAB
4125 AS2 (andi,%A0,0x0f));
4127 if (scratch)
4129 *len = 5;
4130 return (AS2 (mov,%A0,%B0) CR_TAB
4131 AS1 (clr,%B0) CR_TAB
4132 AS1 (swap,%A0) CR_TAB
4133 AS2 (ldi,%3,0x0f) CR_TAB
4134 AS2 (and,%A0,%3));
4136 *len = 6;
4137 return (AS2 (mov,%A0,%B0) CR_TAB
4138 AS1 (clr,%B0) CR_TAB
4139 AS1 (lsr,%A0) CR_TAB
4140 AS1 (lsr,%A0) CR_TAB
4141 AS1 (lsr,%A0) CR_TAB
4142 AS1 (lsr,%A0));
4144 case 13:
4145 if (ldi_ok)
4147 *len = 5;
4148 return (AS2 (mov,%A0,%B0) CR_TAB
4149 AS1 (clr,%B0) CR_TAB
4150 AS1 (swap,%A0) CR_TAB
4151 AS1 (lsr,%A0) CR_TAB
4152 AS2 (andi,%A0,0x07));
4154 if (AVR_HAVE_MUL && scratch)
4156 *len = 5;
4157 return (AS2 (ldi,%3,0x08) CR_TAB
4158 AS2 (mul,%B0,%3) CR_TAB
4159 AS2 (mov,%A0,r1) CR_TAB
4160 AS1 (clr,%B0) CR_TAB
4161 AS1 (clr,__zero_reg__));
4163 if (optimize_size && scratch)
4164 break; /* 5 */
4165 if (scratch)
4167 *len = 6;
4168 return (AS2 (mov,%A0,%B0) CR_TAB
4169 AS1 (clr,%B0) CR_TAB
4170 AS1 (swap,%A0) CR_TAB
4171 AS1 (lsr,%A0) CR_TAB
4172 AS2 (ldi,%3,0x07) CR_TAB
4173 AS2 (and,%A0,%3));
4175 if (AVR_HAVE_MUL)
4177 *len = 6;
4178 return ("set" CR_TAB
4179 AS2 (bld,r1,3) CR_TAB
4180 AS2 (mul,%B0,r1) CR_TAB
4181 AS2 (mov,%A0,r1) CR_TAB
4182 AS1 (clr,%B0) CR_TAB
4183 AS1 (clr,__zero_reg__));
4185 *len = 7;
4186 return (AS2 (mov,%A0,%B0) CR_TAB
4187 AS1 (clr,%B0) CR_TAB
4188 AS1 (lsr,%A0) CR_TAB
4189 AS1 (lsr,%A0) CR_TAB
4190 AS1 (lsr,%A0) CR_TAB
4191 AS1 (lsr,%A0) CR_TAB
4192 AS1 (lsr,%A0));
4194 case 14:
4195 if (AVR_HAVE_MUL && ldi_ok)
4197 *len = 5;
4198 return (AS2 (ldi,%A0,0x04) CR_TAB
4199 AS2 (mul,%B0,%A0) CR_TAB
4200 AS2 (mov,%A0,r1) CR_TAB
4201 AS1 (clr,%B0) CR_TAB
4202 AS1 (clr,__zero_reg__));
4204 if (AVR_HAVE_MUL && scratch)
4206 *len = 5;
4207 return (AS2 (ldi,%3,0x04) CR_TAB
4208 AS2 (mul,%B0,%3) CR_TAB
4209 AS2 (mov,%A0,r1) CR_TAB
4210 AS1 (clr,%B0) CR_TAB
4211 AS1 (clr,__zero_reg__));
4213 if (optimize_size && ldi_ok)
4215 *len = 5;
4216 return (AS2 (mov,%A0,%B0) CR_TAB
4217 AS2 (ldi,%B0,6) "\n1:\t"
4218 AS1 (lsr,%A0) CR_TAB
4219 AS1 (dec,%B0) CR_TAB
4220 AS1 (brne,1b));
4222 if (optimize_size && scratch)
4223 break; /* 5 */
4224 *len = 6;
4225 return (AS1 (clr,%A0) CR_TAB
4226 AS1 (lsl,%B0) CR_TAB
4227 AS1 (rol,%A0) CR_TAB
4228 AS1 (lsl,%B0) CR_TAB
4229 AS1 (rol,%A0) CR_TAB
4230 AS1 (clr,%B0));
4232 case 15:
4233 *len = 4;
4234 return (AS1 (clr,%A0) CR_TAB
4235 AS1 (lsl,%B0) CR_TAB
4236 AS1 (rol,%A0) CR_TAB
4237 AS1 (clr,%B0));
4239 len = t;
4241 out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
4242 AS1 (ror,%A0)),
4243 insn, operands, len, 2);
4244 return "";
4247 /* 32bit logic shift right ((unsigned int)x >> i) */
4249 const char *
4250 lshrsi3_out (rtx insn, rtx operands[], int *len)
4252 if (GET_CODE (operands[2]) == CONST_INT)
4254 int k;
4255 int *t = len;
4257 if (!len)
4258 len = &k;
4260 switch (INTVAL (operands[2]))
4262 default:
4263 if (INTVAL (operands[2]) < 32)
4264 break;
4266 if (AVR_HAVE_MOVW)
4267 return *len = 3, (AS1 (clr,%D0) CR_TAB
4268 AS1 (clr,%C0) CR_TAB
4269 AS2 (movw,%A0,%C0));
4270 *len = 4;
4271 return (AS1 (clr,%D0) CR_TAB
4272 AS1 (clr,%C0) CR_TAB
4273 AS1 (clr,%B0) CR_TAB
4274 AS1 (clr,%A0));
4276 case 8:
4278 int reg0 = true_regnum (operands[0]);
4279 int reg1 = true_regnum (operands[1]);
4280 *len = 4;
4281 if (reg0 <= reg1)
4282 return (AS2 (mov,%A0,%B1) CR_TAB
4283 AS2 (mov,%B0,%C1) CR_TAB
4284 AS2 (mov,%C0,%D1) CR_TAB
4285 AS1 (clr,%D0));
4286 else
4287 return (AS1 (clr,%D0) CR_TAB
4288 AS2 (mov,%C0,%D1) CR_TAB
4289 AS2 (mov,%B0,%C1) CR_TAB
4290 AS2 (mov,%A0,%B1));
4293 case 16:
4295 int reg0 = true_regnum (operands[0]);
4296 int reg1 = true_regnum (operands[1]);
4298 if (reg0 == reg1 + 2)
4299 return *len = 2, (AS1 (clr,%C0) CR_TAB
4300 AS1 (clr,%D0));
4301 if (AVR_HAVE_MOVW)
4302 return *len = 3, (AS2 (movw,%A0,%C1) CR_TAB
4303 AS1 (clr,%C0) CR_TAB
4304 AS1 (clr,%D0));
4305 else
4306 return *len = 4, (AS2 (mov,%B0,%D1) CR_TAB
4307 AS2 (mov,%A0,%C1) CR_TAB
4308 AS1 (clr,%C0) CR_TAB
4309 AS1 (clr,%D0));
4312 case 24:
4313 return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4314 AS1 (clr,%B0) CR_TAB
4315 AS1 (clr,%C0) CR_TAB
4316 AS1 (clr,%D0));
4318 case 31:
4319 *len = 6;
4320 return (AS1 (clr,%A0) CR_TAB
4321 AS2 (sbrc,%D0,7) CR_TAB
4322 AS1 (inc,%A0) CR_TAB
4323 AS1 (clr,%B0) CR_TAB
4324 AS1 (clr,%C0) CR_TAB
4325 AS1 (clr,%D0));
4327 len = t;
4329 out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4330 AS1 (ror,%C0) CR_TAB
4331 AS1 (ror,%B0) CR_TAB
4332 AS1 (ror,%A0)),
4333 insn, operands, len, 4);
4334 return "";
4337 /* Modifies the length assigned to instruction INSN
4338 LEN is the initially computed length of the insn. */
4341 adjust_insn_length (rtx insn, int len)
4343 rtx patt = PATTERN (insn);
4344 rtx set;
4346 if (GET_CODE (patt) == SET)
4348 rtx op[10];
4349 op[1] = SET_SRC (patt);
4350 op[0] = SET_DEST (patt);
4351 if (general_operand (op[1], VOIDmode)
4352 && general_operand (op[0], VOIDmode))
4354 switch (GET_MODE (op[0]))
4356 case QImode:
4357 output_movqi (insn, op, &len);
4358 break;
4359 case HImode:
4360 output_movhi (insn, op, &len);
4361 break;
4362 case SImode:
4363 case SFmode:
4364 output_movsisf (insn, op, &len);
4365 break;
4366 default:
4367 break;
4370 else if (op[0] == cc0_rtx && REG_P (op[1]))
4372 switch (GET_MODE (op[1]))
4374 case HImode: out_tsthi (insn, op[1], &len); break;
4375 case SImode: out_tstsi (insn, op[1], &len); break;
4376 default: break;
4379 else if (GET_CODE (op[1]) == AND)
4381 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4383 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4384 if (GET_MODE (op[1]) == SImode)
4385 len = (((mask & 0xff) != 0xff)
4386 + ((mask & 0xff00) != 0xff00)
4387 + ((mask & 0xff0000L) != 0xff0000L)
4388 + ((mask & 0xff000000L) != 0xff000000L));
4389 else if (GET_MODE (op[1]) == HImode)
4390 len = (((mask & 0xff) != 0xff)
4391 + ((mask & 0xff00) != 0xff00));
4394 else if (GET_CODE (op[1]) == IOR)
4396 if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4398 HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4399 if (GET_MODE (op[1]) == SImode)
4400 len = (((mask & 0xff) != 0)
4401 + ((mask & 0xff00) != 0)
4402 + ((mask & 0xff0000L) != 0)
4403 + ((mask & 0xff000000L) != 0));
4404 else if (GET_MODE (op[1]) == HImode)
4405 len = (((mask & 0xff) != 0)
4406 + ((mask & 0xff00) != 0));
4410 set = single_set (insn);
4411 if (set)
4413 rtx op[10];
4415 op[1] = SET_SRC (set);
4416 op[0] = SET_DEST (set);
4418 if (GET_CODE (patt) == PARALLEL
4419 && general_operand (op[1], VOIDmode)
4420 && general_operand (op[0], VOIDmode))
4422 if (XVECLEN (patt, 0) == 2)
4423 op[2] = XVECEXP (patt, 0, 1);
4425 switch (GET_MODE (op[0]))
4427 case QImode:
4428 len = 2;
4429 break;
4430 case HImode:
4431 output_reload_inhi (insn, op, &len);
4432 break;
4433 case SImode:
4434 case SFmode:
4435 output_reload_insisf (insn, op, &len);
4436 break;
4437 default:
4438 break;
4441 else if (GET_CODE (op[1]) == ASHIFT
4442 || GET_CODE (op[1]) == ASHIFTRT
4443 || GET_CODE (op[1]) == LSHIFTRT)
4445 rtx ops[10];
4446 ops[0] = op[0];
4447 ops[1] = XEXP (op[1],0);
4448 ops[2] = XEXP (op[1],1);
4449 switch (GET_CODE (op[1]))
4451 case ASHIFT:
4452 switch (GET_MODE (op[0]))
4454 case QImode: ashlqi3_out (insn,ops,&len); break;
4455 case HImode: ashlhi3_out (insn,ops,&len); break;
4456 case SImode: ashlsi3_out (insn,ops,&len); break;
4457 default: break;
4459 break;
4460 case ASHIFTRT:
4461 switch (GET_MODE (op[0]))
4463 case QImode: ashrqi3_out (insn,ops,&len); break;
4464 case HImode: ashrhi3_out (insn,ops,&len); break;
4465 case SImode: ashrsi3_out (insn,ops,&len); break;
4466 default: break;
4468 break;
4469 case LSHIFTRT:
4470 switch (GET_MODE (op[0]))
4472 case QImode: lshrqi3_out (insn,ops,&len); break;
4473 case HImode: lshrhi3_out (insn,ops,&len); break;
4474 case SImode: lshrsi3_out (insn,ops,&len); break;
4475 default: break;
4477 break;
4478 default:
4479 break;
4483 return len;
4486 /* Return nonzero if register REG dead after INSN. */
4489 reg_unused_after (rtx insn, rtx reg)
4491 return (dead_or_set_p (insn, reg)
4492 || (REG_P(reg) && _reg_unused_after (insn, reg)));
4495 /* Return nonzero if REG is not used after INSN.
4496 We assume REG is a reload reg, and therefore does
4497 not live past labels. It may live past calls or jumps though. */
4500 _reg_unused_after (rtx insn, rtx reg)
4502 enum rtx_code code;
4503 rtx set;
4505 /* If the reg is set by this instruction, then it is safe for our
4506 case. Disregard the case where this is a store to memory, since
4507 we are checking a register used in the store address. */
4508 set = single_set (insn);
4509 if (set && GET_CODE (SET_DEST (set)) != MEM
4510 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4511 return 1;
4513 while ((insn = NEXT_INSN (insn)))
4515 rtx set;
4516 code = GET_CODE (insn);
4518 #if 0
4519 /* If this is a label that existed before reload, then the register
4520 if dead here. However, if this is a label added by reorg, then
4521 the register may still be live here. We can't tell the difference,
4522 so we just ignore labels completely. */
4523 if (code == CODE_LABEL)
4524 return 1;
4525 /* else */
4526 #endif
4528 if (!INSN_P (insn))
4529 continue;
4531 if (code == JUMP_INSN)
4532 return 0;
4534 /* If this is a sequence, we must handle them all at once.
4535 We could have for instance a call that sets the target register,
4536 and an insn in a delay slot that uses the register. In this case,
4537 we must return 0. */
4538 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
4540 int i;
4541 int retval = 0;
4543 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
4545 rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
4546 rtx set = single_set (this_insn);
4548 if (GET_CODE (this_insn) == CALL_INSN)
4549 code = CALL_INSN;
4550 else if (GET_CODE (this_insn) == JUMP_INSN)
4552 if (INSN_ANNULLED_BRANCH_P (this_insn))
4553 return 0;
4554 code = JUMP_INSN;
4557 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4558 return 0;
4559 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4561 if (GET_CODE (SET_DEST (set)) != MEM)
4562 retval = 1;
4563 else
4564 return 0;
4566 if (set == 0
4567 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
4568 return 0;
4570 if (retval == 1)
4571 return 1;
4572 else if (code == JUMP_INSN)
4573 return 0;
4576 if (code == CALL_INSN)
4578 rtx tem;
4579 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4580 if (GET_CODE (XEXP (tem, 0)) == USE
4581 && REG_P (XEXP (XEXP (tem, 0), 0))
4582 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
4583 return 0;
4584 if (call_used_regs[REGNO (reg)])
4585 return 1;
4588 set = single_set (insn);
4590 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4591 return 0;
4592 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4593 return GET_CODE (SET_DEST (set)) != MEM;
4594 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
4595 return 0;
4597 return 1;
4600 /* Target hook for assembling integer objects. The AVR version needs
4601 special handling for references to certain labels. */
4603 static bool
4604 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
4606 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
4607 && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x))
4608 || GET_CODE (x) == LABEL_REF))
4610 fputs ("\t.word\tgs(", asm_out_file);
4611 output_addr_const (asm_out_file, x);
4612 fputs (")\n", asm_out_file);
4613 return true;
4615 return default_assemble_integer (x, size, aligned_p);
4618 /* Worker function for ASM_DECLARE_FUNCTION_NAME. */
4620 void
4621 avr_asm_declare_function_name (FILE *file, const char *name, tree decl)
4624 /* If the function has the 'signal' or 'interrupt' attribute, test to
4625 make sure that the name of the function is "__vector_NN" so as to
4626 catch when the user misspells the interrupt vector name. */
4628 if (cfun->machine->is_interrupt)
4630 if (strncmp (name, "__vector", strlen ("__vector")) != 0)
4632 warning_at (DECL_SOURCE_LOCATION (decl), 0,
4633 "%qs appears to be a misspelled interrupt handler",
4634 name);
4637 else if (cfun->machine->is_signal)
4639 if (strncmp (name, "__vector", strlen ("__vector")) != 0)
4641 warning_at (DECL_SOURCE_LOCATION (decl), 0,
4642 "%qs appears to be a misspelled signal handler",
4643 name);
4647 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
4648 ASM_OUTPUT_LABEL (file, name);
4651 /* The routine used to output NUL terminated strings. We use a special
4652 version of this for most svr4 targets because doing so makes the
4653 generated assembly code more compact (and thus faster to assemble)
4654 as well as more readable, especially for targets like the i386
4655 (where the only alternative is to output character sequences as
4656 comma separated lists of numbers). */
4658 void
4659 gas_output_limited_string(FILE *file, const char *str)
4661 const unsigned char *_limited_str = (const unsigned char *) str;
4662 unsigned ch;
4663 fprintf (file, "%s\"", STRING_ASM_OP);
4664 for (; (ch = *_limited_str); _limited_str++)
4666 int escape;
4667 switch (escape = ESCAPES[ch])
4669 case 0:
4670 putc (ch, file);
4671 break;
4672 case 1:
4673 fprintf (file, "\\%03o", ch);
4674 break;
4675 default:
4676 putc ('\\', file);
4677 putc (escape, file);
4678 break;
4681 fprintf (file, "\"\n");
4684 /* The routine used to output sequences of byte values. We use a special
4685 version of this for most svr4 targets because doing so makes the
4686 generated assembly code more compact (and thus faster to assemble)
4687 as well as more readable. Note that if we find subparts of the
4688 character sequence which end with NUL (and which are shorter than
4689 STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
4691 void
4692 gas_output_ascii(FILE *file, const char *str, size_t length)
4694 const unsigned char *_ascii_bytes = (const unsigned char *) str;
4695 const unsigned char *limit = _ascii_bytes + length;
4696 unsigned bytes_in_chunk = 0;
4697 for (; _ascii_bytes < limit; _ascii_bytes++)
4699 const unsigned char *p;
4700 if (bytes_in_chunk >= 60)
4702 fprintf (file, "\"\n");
4703 bytes_in_chunk = 0;
4705 for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
4706 continue;
4707 if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
4709 if (bytes_in_chunk > 0)
4711 fprintf (file, "\"\n");
4712 bytes_in_chunk = 0;
4714 gas_output_limited_string (file, (const char*)_ascii_bytes);
4715 _ascii_bytes = p;
4717 else
4719 int escape;
4720 unsigned ch;
4721 if (bytes_in_chunk == 0)
4722 fprintf (file, "\t.ascii\t\"");
4723 switch (escape = ESCAPES[ch = *_ascii_bytes])
4725 case 0:
4726 putc (ch, file);
4727 bytes_in_chunk++;
4728 break;
4729 case 1:
4730 fprintf (file, "\\%03o", ch);
4731 bytes_in_chunk += 4;
4732 break;
4733 default:
4734 putc ('\\', file);
4735 putc (escape, file);
4736 bytes_in_chunk += 2;
4737 break;
4741 if (bytes_in_chunk > 0)
4742 fprintf (file, "\"\n");
4745 /* Return value is nonzero if pseudos that have been
4746 assigned to registers of class CLASS would likely be spilled
4747 because registers of CLASS are needed for spill registers. */
4749 enum reg_class
4750 class_likely_spilled_p (int c)
4752 return (c != ALL_REGS && c != ADDW_REGS);
4755 /* Valid attributes:
4756 progmem - put data to program memory;
4757 signal - make a function to be hardware interrupt. After function
4758 prologue interrupts are disabled;
4759 interrupt - make a function to be hardware interrupt. After function
4760 prologue interrupts are enabled;
4761 naked - don't generate function prologue/epilogue and `ret' command.
4763 Only `progmem' attribute valid for type. */
4765 const struct attribute_spec avr_attribute_table[] =
4767 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
4768 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute },
4769 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4770 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute },
4771 { "naked", 0, 0, false, true, true, avr_handle_fntype_attribute },
4772 { "OS_task", 0, 0, false, true, true, avr_handle_fntype_attribute },
4773 { "OS_main", 0, 0, false, true, true, avr_handle_fntype_attribute },
4774 { NULL, 0, 0, false, false, false, NULL }
4777 /* Handle a "progmem" attribute; arguments as in
4778 struct attribute_spec.handler. */
4779 static tree
4780 avr_handle_progmem_attribute (tree *node, tree name,
4781 tree args ATTRIBUTE_UNUSED,
4782 int flags ATTRIBUTE_UNUSED,
4783 bool *no_add_attrs)
4785 if (DECL_P (*node))
4787 if (TREE_CODE (*node) == TYPE_DECL)
4789 /* This is really a decl attribute, not a type attribute,
4790 but try to handle it for GCC 3.0 backwards compatibility. */
4792 tree type = TREE_TYPE (*node);
4793 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
4794 tree newtype = build_type_attribute_variant (type, attr);
4796 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
4797 TREE_TYPE (*node) = newtype;
4798 *no_add_attrs = true;
4800 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
4802 if (DECL_INITIAL (*node) == NULL_TREE && !DECL_EXTERNAL (*node))
4804 warning (0, "only initialized variables can be placed into "
4805 "program memory area");
4806 *no_add_attrs = true;
4809 else
4811 warning (OPT_Wattributes, "%qE attribute ignored",
4812 name);
4813 *no_add_attrs = true;
4817 return NULL_TREE;
4820 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
4821 struct attribute_spec.handler. */
4823 static tree
4824 avr_handle_fndecl_attribute (tree *node, tree name,
4825 tree args ATTRIBUTE_UNUSED,
4826 int flags ATTRIBUTE_UNUSED,
4827 bool *no_add_attrs)
4829 if (TREE_CODE (*node) != FUNCTION_DECL)
4831 warning (OPT_Wattributes, "%qE attribute only applies to functions",
4832 name);
4833 *no_add_attrs = true;
4836 return NULL_TREE;
4839 static tree
4840 avr_handle_fntype_attribute (tree *node, tree name,
4841 tree args ATTRIBUTE_UNUSED,
4842 int flags ATTRIBUTE_UNUSED,
4843 bool *no_add_attrs)
4845 if (TREE_CODE (*node) != FUNCTION_TYPE)
4847 warning (OPT_Wattributes, "%qE attribute only applies to functions",
4848 name);
4849 *no_add_attrs = true;
4852 return NULL_TREE;
4855 /* Look for attribute `progmem' in DECL
4856 if found return 1, otherwise 0. */
4859 avr_progmem_p (tree decl, tree attributes)
4861 tree a;
4863 if (TREE_CODE (decl) != VAR_DECL)
4864 return 0;
4866 if (NULL_TREE
4867 != lookup_attribute ("progmem", attributes))
4868 return 1;
4870 a=decl;
4872 a = TREE_TYPE(a);
4873 while (TREE_CODE (a) == ARRAY_TYPE);
4875 if (a == error_mark_node)
4876 return 0;
4878 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
4879 return 1;
4881 return 0;
4884 /* Add the section attribute if the variable is in progmem. */
4886 static void
4887 avr_insert_attributes (tree node, tree *attributes)
4889 if (TREE_CODE (node) == VAR_DECL
4890 && (TREE_STATIC (node) || DECL_EXTERNAL (node))
4891 && avr_progmem_p (node, *attributes))
4893 static const char dsec[] = ".progmem.data";
4894 *attributes = tree_cons (get_identifier ("section"),
4895 build_tree_list (NULL, build_string (strlen (dsec), dsec)),
4896 *attributes);
4898 /* ??? This seems sketchy. Why can't the user declare the
4899 thing const in the first place? */
4900 TREE_READONLY (node) = 1;
4904 /* A get_unnamed_section callback for switching to progmem_section. */
4906 static void
4907 avr_output_progmem_section_asm_op (const void *arg ATTRIBUTE_UNUSED)
4909 fprintf (asm_out_file,
4910 "\t.section .progmem.gcc_sw_table, \"%s\", @progbits\n",
4911 AVR_HAVE_JMP_CALL ? "a" : "ax");
4912 /* Should already be aligned, this is just to be safe if it isn't. */
4913 fprintf (asm_out_file, "\t.p2align 1\n");
4916 /* Implement TARGET_ASM_INIT_SECTIONS. */
4918 static void
4919 avr_asm_init_sections (void)
4921 progmem_section = get_unnamed_section (AVR_HAVE_JMP_CALL ? 0 : SECTION_CODE,
4922 avr_output_progmem_section_asm_op,
4923 NULL);
4924 readonly_data_section = data_section;
4927 static unsigned int
4928 avr_section_type_flags (tree decl, const char *name, int reloc)
4930 unsigned int flags = default_section_type_flags (decl, name, reloc);
4932 if (strncmp (name, ".noinit", 7) == 0)
4934 if (decl && TREE_CODE (decl) == VAR_DECL
4935 && DECL_INITIAL (decl) == NULL_TREE)
4936 flags |= SECTION_BSS; /* @nobits */
4937 else
4938 warning (0, "only uninitialized variables can be placed in the "
4939 ".noinit section");
4942 return flags;
4945 /* Outputs some appropriate text to go at the start of an assembler
4946 file. */
4948 static void
4949 avr_file_start (void)
4951 if (avr_current_arch->asm_only)
4952 error ("MCU %qs supported for assembler only", avr_mcu_name);
4954 default_file_start ();
4956 /* fprintf (asm_out_file, "\t.arch %s\n", avr_mcu_name);*/
4957 fputs ("__SREG__ = 0x3f\n"
4958 "__SP_H__ = 0x3e\n"
4959 "__SP_L__ = 0x3d\n", asm_out_file);
4961 fputs ("__tmp_reg__ = 0\n"
4962 "__zero_reg__ = 1\n", asm_out_file);
4964 /* FIXME: output these only if there is anything in the .data / .bss
4965 sections - some code size could be saved by not linking in the
4966 initialization code from libgcc if one or both sections are empty. */
4967 fputs ("\t.global __do_copy_data\n", asm_out_file);
4968 fputs ("\t.global __do_clear_bss\n", asm_out_file);
4971 /* Outputs to the stdio stream FILE some
4972 appropriate text to go at the end of an assembler file. */
4974 static void
4975 avr_file_end (void)
4979 /* Choose the order in which to allocate hard registers for
4980 pseudo-registers local to a basic block.
4982 Store the desired register order in the array `reg_alloc_order'.
4983 Element 0 should be the register to allocate first; element 1, the
4984 next register; and so on. */
4986 void
4987 order_regs_for_local_alloc (void)
4989 unsigned int i;
4990 static const int order_0[] = {
4991 24,25,
4992 18,19,
4993 20,21,
4994 22,23,
4995 30,31,
4996 26,27,
4997 28,29,
4998 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4999 0,1,
5000 32,33,34,35
5002 static const int order_1[] = {
5003 18,19,
5004 20,21,
5005 22,23,
5006 24,25,
5007 30,31,
5008 26,27,
5009 28,29,
5010 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
5011 0,1,
5012 32,33,34,35
5014 static const int order_2[] = {
5015 25,24,
5016 23,22,
5017 21,20,
5018 19,18,
5019 30,31,
5020 26,27,
5021 28,29,
5022 17,16,
5023 15,14,13,12,11,10,9,8,7,6,5,4,3,2,
5024 1,0,
5025 32,33,34,35
5028 const int *order = (TARGET_ORDER_1 ? order_1 :
5029 TARGET_ORDER_2 ? order_2 :
5030 order_0);
5031 for (i=0; i < ARRAY_SIZE (order_0); ++i)
5032 reg_alloc_order[i] = order[i];
5036 /* Mutually recursive subroutine of avr_rtx_cost for calculating the
5037 cost of an RTX operand given its context. X is the rtx of the
5038 operand, MODE is its mode, and OUTER is the rtx_code of this
5039 operand's parent operator. */
5041 static int
5042 avr_operand_rtx_cost (rtx x, enum machine_mode mode, enum rtx_code outer,
5043 bool speed)
5045 enum rtx_code code = GET_CODE (x);
5046 int total;
5048 switch (code)
5050 case REG:
5051 case SUBREG:
5052 return 0;
5054 case CONST_INT:
5055 case CONST_DOUBLE:
5056 return COSTS_N_INSNS (GET_MODE_SIZE (mode));
5058 default:
5059 break;
5062 total = 0;
5063 avr_rtx_costs (x, code, outer, &total, speed);
5064 return total;
5067 /* The AVR backend's rtx_cost function. X is rtx expression whose cost
5068 is to be calculated. Return true if the complete cost has been
5069 computed, and false if subexpressions should be scanned. In either
5070 case, *TOTAL contains the cost result. */
5072 static bool
5073 avr_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total,
5074 bool speed)
5076 enum machine_mode mode = GET_MODE (x);
5077 HOST_WIDE_INT val;
5079 switch (code)
5081 case CONST_INT:
5082 case CONST_DOUBLE:
5083 /* Immediate constants are as cheap as registers. */
5084 *total = 0;
5085 return true;
5087 case MEM:
5088 case CONST:
5089 case LABEL_REF:
5090 case SYMBOL_REF:
5091 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5092 return true;
5094 case NEG:
5095 switch (mode)
5097 case QImode:
5098 case SFmode:
5099 *total = COSTS_N_INSNS (1);
5100 break;
5102 case HImode:
5103 *total = COSTS_N_INSNS (3);
5104 break;
5106 case SImode:
5107 *total = COSTS_N_INSNS (7);
5108 break;
5110 default:
5111 return false;
5113 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5114 return true;
5116 case ABS:
5117 switch (mode)
5119 case QImode:
5120 case SFmode:
5121 *total = COSTS_N_INSNS (1);
5122 break;
5124 default:
5125 return false;
5127 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5128 return true;
5130 case NOT:
5131 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5132 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5133 return true;
5135 case ZERO_EXTEND:
5136 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
5137 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
5138 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5139 return true;
5141 case SIGN_EXTEND:
5142 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
5143 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
5144 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5145 return true;
5147 case PLUS:
5148 switch (mode)
5150 case QImode:
5151 *total = COSTS_N_INSNS (1);
5152 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5153 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5154 break;
5156 case HImode:
5157 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5159 *total = COSTS_N_INSNS (2);
5160 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5162 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
5163 *total = COSTS_N_INSNS (1);
5164 else
5165 *total = COSTS_N_INSNS (2);
5166 break;
5168 case SImode:
5169 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5171 *total = COSTS_N_INSNS (4);
5172 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5174 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
5175 *total = COSTS_N_INSNS (1);
5176 else
5177 *total = COSTS_N_INSNS (4);
5178 break;
5180 default:
5181 return false;
5183 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5184 return true;
5186 case MINUS:
5187 case AND:
5188 case IOR:
5189 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5190 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5191 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5192 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5193 return true;
5195 case XOR:
5196 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5197 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5198 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5199 return true;
5201 case MULT:
5202 switch (mode)
5204 case QImode:
5205 if (AVR_HAVE_MUL)
5206 *total = COSTS_N_INSNS (!speed ? 3 : 4);
5207 else if (!speed)
5208 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
5209 else
5210 return false;
5211 break;
5213 case HImode:
5214 if (AVR_HAVE_MUL)
5215 *total = COSTS_N_INSNS (!speed ? 7 : 10);
5216 else if (!speed)
5217 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
5218 else
5219 return false;
5220 break;
5222 default:
5223 return false;
5225 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5226 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5227 return true;
5229 case DIV:
5230 case MOD:
5231 case UDIV:
5232 case UMOD:
5233 if (!speed)
5234 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
5235 else
5236 return false;
5237 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5238 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5239 return true;
5241 case ROTATE:
5242 switch (mode)
5244 case QImode:
5245 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 4)
5246 *total = COSTS_N_INSNS (1);
5248 break;
5250 case HImode:
5251 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 8)
5252 *total = COSTS_N_INSNS (3);
5254 break;
5256 case SImode:
5257 if (CONST_INT_P (XEXP (x, 1)))
5258 switch (INTVAL (XEXP (x, 1)))
5260 case 8:
5261 case 24:
5262 *total = COSTS_N_INSNS (5);
5263 break;
5264 case 16:
5265 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 6);
5266 break;
5268 break;
5270 default:
5271 return false;
5273 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5274 return true;
5276 case ASHIFT:
5277 switch (mode)
5279 case QImode:
5280 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5282 *total = COSTS_N_INSNS (!speed ? 4 : 17);
5283 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5285 else
5287 val = INTVAL (XEXP (x, 1));
5288 if (val == 7)
5289 *total = COSTS_N_INSNS (3);
5290 else if (val >= 0 && val <= 7)
5291 *total = COSTS_N_INSNS (val);
5292 else
5293 *total = COSTS_N_INSNS (1);
5295 break;
5297 case HImode:
5298 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5300 *total = COSTS_N_INSNS (!speed ? 5 : 41);
5301 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5303 else
5304 switch (INTVAL (XEXP (x, 1)))
5306 case 0:
5307 *total = 0;
5308 break;
5309 case 1:
5310 case 8:
5311 *total = COSTS_N_INSNS (2);
5312 break;
5313 case 9:
5314 *total = COSTS_N_INSNS (3);
5315 break;
5316 case 2:
5317 case 3:
5318 case 10:
5319 case 15:
5320 *total = COSTS_N_INSNS (4);
5321 break;
5322 case 7:
5323 case 11:
5324 case 12:
5325 *total = COSTS_N_INSNS (5);
5326 break;
5327 case 4:
5328 *total = COSTS_N_INSNS (!speed ? 5 : 8);
5329 break;
5330 case 6:
5331 *total = COSTS_N_INSNS (!speed ? 5 : 9);
5332 break;
5333 case 5:
5334 *total = COSTS_N_INSNS (!speed ? 5 : 10);
5335 break;
5336 default:
5337 *total = COSTS_N_INSNS (!speed ? 5 : 41);
5338 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5340 break;
5342 case SImode:
5343 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5345 *total = COSTS_N_INSNS (!speed ? 7 : 113);
5346 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5348 else
5349 switch (INTVAL (XEXP (x, 1)))
5351 case 0:
5352 *total = 0;
5353 break;
5354 case 24:
5355 *total = COSTS_N_INSNS (3);
5356 break;
5357 case 1:
5358 case 8:
5359 case 16:
5360 *total = COSTS_N_INSNS (4);
5361 break;
5362 case 31:
5363 *total = COSTS_N_INSNS (6);
5364 break;
5365 case 2:
5366 *total = COSTS_N_INSNS (!speed ? 7 : 8);
5367 break;
5368 default:
5369 *total = COSTS_N_INSNS (!speed ? 7 : 113);
5370 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5372 break;
5374 default:
5375 return false;
5377 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5378 return true;
5380 case ASHIFTRT:
5381 switch (mode)
5383 case QImode:
5384 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5386 *total = COSTS_N_INSNS (!speed ? 4 : 17);
5387 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5389 else
5391 val = INTVAL (XEXP (x, 1));
5392 if (val == 6)
5393 *total = COSTS_N_INSNS (4);
5394 else if (val == 7)
5395 *total = COSTS_N_INSNS (2);
5396 else if (val >= 0 && val <= 7)
5397 *total = COSTS_N_INSNS (val);
5398 else
5399 *total = COSTS_N_INSNS (1);
5401 break;
5403 case HImode:
5404 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5406 *total = COSTS_N_INSNS (!speed ? 5 : 41);
5407 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5409 else
5410 switch (INTVAL (XEXP (x, 1)))
5412 case 0:
5413 *total = 0;
5414 break;
5415 case 1:
5416 *total = COSTS_N_INSNS (2);
5417 break;
5418 case 15:
5419 *total = COSTS_N_INSNS (3);
5420 break;
5421 case 2:
5422 case 7:
5423 case 8:
5424 case 9:
5425 *total = COSTS_N_INSNS (4);
5426 break;
5427 case 10:
5428 case 14:
5429 *total = COSTS_N_INSNS (5);
5430 break;
5431 case 11:
5432 *total = COSTS_N_INSNS (!speed ? 5 : 6);
5433 break;
5434 case 12:
5435 *total = COSTS_N_INSNS (!speed ? 5 : 7);
5436 break;
5437 case 6:
5438 case 13:
5439 *total = COSTS_N_INSNS (!speed ? 5 : 8);
5440 break;
5441 default:
5442 *total = COSTS_N_INSNS (!speed ? 5 : 41);
5443 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5445 break;
5447 case SImode:
5448 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5450 *total = COSTS_N_INSNS (!speed ? 7 : 113);
5451 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5453 else
5454 switch (INTVAL (XEXP (x, 1)))
5456 case 0:
5457 *total = 0;
5458 break;
5459 case 1:
5460 *total = COSTS_N_INSNS (4);
5461 break;
5462 case 8:
5463 case 16:
5464 case 24:
5465 *total = COSTS_N_INSNS (6);
5466 break;
5467 case 2:
5468 *total = COSTS_N_INSNS (!speed ? 7 : 8);
5469 break;
5470 case 31:
5471 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 5);
5472 break;
5473 default:
5474 *total = COSTS_N_INSNS (!speed ? 7 : 113);
5475 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5477 break;
5479 default:
5480 return false;
5482 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5483 return true;
5485 case LSHIFTRT:
5486 switch (mode)
5488 case QImode:
5489 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5491 *total = COSTS_N_INSNS (!speed ? 4 : 17);
5492 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5494 else
5496 val = INTVAL (XEXP (x, 1));
5497 if (val == 7)
5498 *total = COSTS_N_INSNS (3);
5499 else if (val >= 0 && val <= 7)
5500 *total = COSTS_N_INSNS (val);
5501 else
5502 *total = COSTS_N_INSNS (1);
5504 break;
5506 case HImode:
5507 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5509 *total = COSTS_N_INSNS (!speed ? 5 : 41);
5510 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5512 else
5513 switch (INTVAL (XEXP (x, 1)))
5515 case 0:
5516 *total = 0;
5517 break;
5518 case 1:
5519 case 8:
5520 *total = COSTS_N_INSNS (2);
5521 break;
5522 case 9:
5523 *total = COSTS_N_INSNS (3);
5524 break;
5525 case 2:
5526 case 10:
5527 case 15:
5528 *total = COSTS_N_INSNS (4);
5529 break;
5530 case 7:
5531 case 11:
5532 *total = COSTS_N_INSNS (5);
5533 break;
5534 case 3:
5535 case 12:
5536 case 13:
5537 case 14:
5538 *total = COSTS_N_INSNS (!speed ? 5 : 6);
5539 break;
5540 case 4:
5541 *total = COSTS_N_INSNS (!speed ? 5 : 7);
5542 break;
5543 case 5:
5544 case 6:
5545 *total = COSTS_N_INSNS (!speed ? 5 : 9);
5546 break;
5547 default:
5548 *total = COSTS_N_INSNS (!speed ? 5 : 41);
5549 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5551 break;
5553 case SImode:
5554 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5556 *total = COSTS_N_INSNS (!speed ? 7 : 113);
5557 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5559 else
5560 switch (INTVAL (XEXP (x, 1)))
5562 case 0:
5563 *total = 0;
5564 break;
5565 case 1:
5566 *total = COSTS_N_INSNS (4);
5567 break;
5568 case 2:
5569 *total = COSTS_N_INSNS (!speed ? 7 : 8);
5570 break;
5571 case 8:
5572 case 16:
5573 case 24:
5574 *total = COSTS_N_INSNS (4);
5575 break;
5576 case 31:
5577 *total = COSTS_N_INSNS (6);
5578 break;
5579 default:
5580 *total = COSTS_N_INSNS (!speed ? 7 : 113);
5581 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5583 break;
5585 default:
5586 return false;
5588 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5589 return true;
5591 case COMPARE:
5592 switch (GET_MODE (XEXP (x, 0)))
5594 case QImode:
5595 *total = COSTS_N_INSNS (1);
5596 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5597 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5598 break;
5600 case HImode:
5601 *total = COSTS_N_INSNS (2);
5602 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5603 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5604 else if (INTVAL (XEXP (x, 1)) != 0)
5605 *total += COSTS_N_INSNS (1);
5606 break;
5608 case SImode:
5609 *total = COSTS_N_INSNS (4);
5610 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5611 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5612 else if (INTVAL (XEXP (x, 1)) != 0)
5613 *total += COSTS_N_INSNS (3);
5614 break;
5616 default:
5617 return false;
5619 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5620 return true;
5622 default:
5623 break;
5625 return false;
5628 /* Calculate the cost of a memory address. */
5630 static int
5631 avr_address_cost (rtx x, bool speed ATTRIBUTE_UNUSED)
5633 if (GET_CODE (x) == PLUS
5634 && GET_CODE (XEXP (x,1)) == CONST_INT
5635 && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
5636 && INTVAL (XEXP (x,1)) >= 61)
5637 return 18;
5638 if (CONSTANT_ADDRESS_P (x))
5640 if (optimize > 0 && io_address_operand (x, QImode))
5641 return 2;
5642 return 4;
5644 return 4;
5647 /* Test for extra memory constraint 'Q'.
5648 It's a memory address based on Y or Z pointer with valid displacement. */
5651 extra_constraint_Q (rtx x)
5653 if (GET_CODE (XEXP (x,0)) == PLUS
5654 && REG_P (XEXP (XEXP (x,0), 0))
5655 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
5656 && (INTVAL (XEXP (XEXP (x,0), 1))
5657 <= MAX_LD_OFFSET (GET_MODE (x))))
5659 rtx xx = XEXP (XEXP (x,0), 0);
5660 int regno = REGNO (xx);
5661 if (TARGET_ALL_DEBUG)
5663 fprintf (stderr, ("extra_constraint:\n"
5664 "reload_completed: %d\n"
5665 "reload_in_progress: %d\n"),
5666 reload_completed, reload_in_progress);
5667 debug_rtx (x);
5669 if (regno >= FIRST_PSEUDO_REGISTER)
5670 return 1; /* allocate pseudos */
5671 else if (regno == REG_Z || regno == REG_Y)
5672 return 1; /* strictly check */
5673 else if (xx == frame_pointer_rtx
5674 || xx == arg_pointer_rtx)
5675 return 1; /* XXX frame & arg pointer checks */
5677 return 0;
5680 /* Convert condition code CONDITION to the valid AVR condition code. */
5682 RTX_CODE
5683 avr_normalize_condition (RTX_CODE condition)
5685 switch (condition)
5687 case GT:
5688 return GE;
5689 case GTU:
5690 return GEU;
5691 case LE:
5692 return LT;
5693 case LEU:
5694 return LTU;
5695 default:
5696 gcc_unreachable ();
5700 /* This function optimizes conditional jumps. */
5702 static void
5703 avr_reorg (void)
5705 rtx insn, pattern;
5707 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5709 if (! (GET_CODE (insn) == INSN
5710 || GET_CODE (insn) == CALL_INSN
5711 || GET_CODE (insn) == JUMP_INSN)
5712 || !single_set (insn))
5713 continue;
5715 pattern = PATTERN (insn);
5717 if (GET_CODE (pattern) == PARALLEL)
5718 pattern = XVECEXP (pattern, 0, 0);
5719 if (GET_CODE (pattern) == SET
5720 && SET_DEST (pattern) == cc0_rtx
5721 && compare_diff_p (insn))
5723 if (GET_CODE (SET_SRC (pattern)) == COMPARE)
5725 /* Now we work under compare insn. */
5727 pattern = SET_SRC (pattern);
5728 if (true_regnum (XEXP (pattern,0)) >= 0
5729 && true_regnum (XEXP (pattern,1)) >= 0 )
5731 rtx x = XEXP (pattern,0);
5732 rtx next = next_real_insn (insn);
5733 rtx pat = PATTERN (next);
5734 rtx src = SET_SRC (pat);
5735 rtx t = XEXP (src,0);
5736 PUT_CODE (t, swap_condition (GET_CODE (t)));
5737 XEXP (pattern,0) = XEXP (pattern,1);
5738 XEXP (pattern,1) = x;
5739 INSN_CODE (next) = -1;
5741 else if (true_regnum (XEXP (pattern, 0)) >= 0
5742 && XEXP (pattern, 1) == const0_rtx)
5744 /* This is a tst insn, we can reverse it. */
5745 rtx next = next_real_insn (insn);
5746 rtx pat = PATTERN (next);
5747 rtx src = SET_SRC (pat);
5748 rtx t = XEXP (src,0);
5750 PUT_CODE (t, swap_condition (GET_CODE (t)));
5751 XEXP (pattern, 1) = XEXP (pattern, 0);
5752 XEXP (pattern, 0) = const0_rtx;
5753 INSN_CODE (next) = -1;
5754 INSN_CODE (insn) = -1;
5756 else if (true_regnum (XEXP (pattern,0)) >= 0
5757 && GET_CODE (XEXP (pattern,1)) == CONST_INT)
5759 rtx x = XEXP (pattern,1);
5760 rtx next = next_real_insn (insn);
5761 rtx pat = PATTERN (next);
5762 rtx src = SET_SRC (pat);
5763 rtx t = XEXP (src,0);
5764 enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
5766 if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
5768 XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
5769 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
5770 INSN_CODE (next) = -1;
5771 INSN_CODE (insn) = -1;
5779 /* Returns register number for function return value.*/
5782 avr_ret_register (void)
5784 return 24;
5787 /* Create an RTX representing the place where a
5788 library function returns a value of mode MODE. */
5791 avr_libcall_value (enum machine_mode mode)
5793 int offs = GET_MODE_SIZE (mode);
5794 if (offs < 2)
5795 offs = 2;
5796 return gen_rtx_REG (mode, RET_REGISTER + 2 - offs);
5799 /* Create an RTX representing the place where a
5800 function returns a value of data type VALTYPE. */
5803 avr_function_value (const_tree type,
5804 const_tree func ATTRIBUTE_UNUSED,
5805 bool outgoing ATTRIBUTE_UNUSED)
5807 unsigned int offs;
5809 if (TYPE_MODE (type) != BLKmode)
5810 return avr_libcall_value (TYPE_MODE (type));
5812 offs = int_size_in_bytes (type);
5813 if (offs < 2)
5814 offs = 2;
5815 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
5816 offs = GET_MODE_SIZE (SImode);
5817 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
5818 offs = GET_MODE_SIZE (DImode);
5820 return gen_rtx_REG (BLKmode, RET_REGISTER + 2 - offs);
5823 /* Places additional restrictions on the register class to
5824 use when it is necessary to copy value X into a register
5825 in class CLASS. */
5827 enum reg_class
5828 preferred_reload_class (rtx x ATTRIBUTE_UNUSED, enum reg_class rclass)
5830 return rclass;
5834 test_hard_reg_class (enum reg_class rclass, rtx x)
5836 int regno = true_regnum (x);
5837 if (regno < 0)
5838 return 0;
5840 if (TEST_HARD_REG_CLASS (rclass, regno))
5841 return 1;
5843 return 0;
5848 jump_over_one_insn_p (rtx insn, rtx dest)
5850 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
5851 ? XEXP (dest, 0)
5852 : dest);
5853 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
5854 int dest_addr = INSN_ADDRESSES (uid);
5855 return dest_addr - jump_addr == get_attr_length (insn) + 1;
5858 /* Returns 1 if a value of mode MODE can be stored starting with hard
5859 register number REGNO. On the enhanced core, anything larger than
5860 1 byte must start in even numbered register for "movw" to work
5861 (this way we don't have to check for odd registers everywhere). */
5864 avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
5866 /* Disallow QImode in stack pointer regs. */
5867 if ((regno == REG_SP || regno == (REG_SP + 1)) && mode == QImode)
5868 return 0;
5870 /* The only thing that can go into registers r28:r29 is a Pmode. */
5871 if (regno == REG_Y && mode == Pmode)
5872 return 1;
5874 /* Otherwise disallow all regno/mode combinations that span r28:r29. */
5875 if (regno <= (REG_Y + 1) && (regno + GET_MODE_SIZE (mode)) >= (REG_Y + 1))
5876 return 0;
5878 if (mode == QImode)
5879 return 1;
5881 /* Modes larger than QImode occupy consecutive registers. */
5882 if (regno + GET_MODE_SIZE (mode) > FIRST_PSEUDO_REGISTER)
5883 return 0;
5885 /* All modes larger than QImode should start in an even register. */
5886 return !(regno & 1);
5889 const char *
5890 output_reload_inhi (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
5892 int tmp;
5893 if (!len)
5894 len = &tmp;
5896 if (GET_CODE (operands[1]) == CONST_INT)
5898 int val = INTVAL (operands[1]);
5899 if ((val & 0xff) == 0)
5901 *len = 3;
5902 return (AS2 (mov,%A0,__zero_reg__) CR_TAB
5903 AS2 (ldi,%2,hi8(%1)) CR_TAB
5904 AS2 (mov,%B0,%2));
5906 else if ((val & 0xff00) == 0)
5908 *len = 3;
5909 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5910 AS2 (mov,%A0,%2) CR_TAB
5911 AS2 (mov,%B0,__zero_reg__));
5913 else if ((val & 0xff) == ((val & 0xff00) >> 8))
5915 *len = 3;
5916 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5917 AS2 (mov,%A0,%2) CR_TAB
5918 AS2 (mov,%B0,%2));
5921 *len = 4;
5922 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5923 AS2 (mov,%A0,%2) CR_TAB
5924 AS2 (ldi,%2,hi8(%1)) CR_TAB
5925 AS2 (mov,%B0,%2));
5929 const char *
5930 output_reload_insisf (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
5932 rtx src = operands[1];
5933 int cnst = (GET_CODE (src) == CONST_INT);
5935 if (len)
5937 if (cnst)
5938 *len = 4 + ((INTVAL (src) & 0xff) != 0)
5939 + ((INTVAL (src) & 0xff00) != 0)
5940 + ((INTVAL (src) & 0xff0000) != 0)
5941 + ((INTVAL (src) & 0xff000000) != 0);
5942 else
5943 *len = 8;
5945 return "";
5948 if (cnst && ((INTVAL (src) & 0xff) == 0))
5949 output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
5950 else
5952 output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
5953 output_asm_insn (AS2 (mov, %A0, %2), operands);
5955 if (cnst && ((INTVAL (src) & 0xff00) == 0))
5956 output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
5957 else
5959 output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
5960 output_asm_insn (AS2 (mov, %B0, %2), operands);
5962 if (cnst && ((INTVAL (src) & 0xff0000) == 0))
5963 output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
5964 else
5966 output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
5967 output_asm_insn (AS2 (mov, %C0, %2), operands);
5969 if (cnst && ((INTVAL (src) & 0xff000000) == 0))
5970 output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
5971 else
5973 output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
5974 output_asm_insn (AS2 (mov, %D0, %2), operands);
5976 return "";
5979 void
5980 avr_output_bld (rtx operands[], int bit_nr)
5982 static char s[] = "bld %A0,0";
5984 s[5] = 'A' + (bit_nr >> 3);
5985 s[8] = '0' + (bit_nr & 7);
5986 output_asm_insn (s, operands);
5989 void
5990 avr_output_addr_vec_elt (FILE *stream, int value)
5992 switch_to_section (progmem_section);
5993 if (AVR_HAVE_JMP_CALL)
5994 fprintf (stream, "\t.word gs(.L%d)\n", value);
5995 else
5996 fprintf (stream, "\trjmp .L%d\n", value);
5999 /* Returns true if SCRATCH are safe to be allocated as a scratch
6000 registers (for a define_peephole2) in the current function. */
6002 bool
6003 avr_hard_regno_scratch_ok (unsigned int regno)
6005 /* Interrupt functions can only use registers that have already been saved
6006 by the prologue, even if they would normally be call-clobbered. */
6008 if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
6009 && !df_regs_ever_live_p (regno))
6010 return false;
6012 return true;
6015 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
6018 avr_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
6019 unsigned int new_reg)
6021 /* Interrupt functions can only use registers that have already been
6022 saved by the prologue, even if they would normally be
6023 call-clobbered. */
6025 if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
6026 && !df_regs_ever_live_p (new_reg))
6027 return 0;
6029 return 1;
6032 /* Output a branch that tests a single bit of a register (QI, HI or SImode)
6033 or memory location in the I/O space (QImode only).
6035 Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
6036 Operand 1: register operand to test, or CONST_INT memory address.
6037 Operand 2: bit number (for QImode operand) or mask (HImode, SImode).
6038 Operand 3: label to jump to if the test is true. */
6040 const char *
6041 avr_out_sbxx_branch (rtx insn, rtx operands[])
6043 enum rtx_code comp = GET_CODE (operands[0]);
6044 int long_jump = (get_attr_length (insn) >= 4);
6045 int reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
6047 if (comp == GE)
6048 comp = EQ;
6049 else if (comp == LT)
6050 comp = NE;
6052 if (reverse)
6053 comp = reverse_condition (comp);
6055 if (GET_CODE (operands[1]) == CONST_INT)
6057 if (INTVAL (operands[1]) < 0x40)
6059 if (comp == EQ)
6060 output_asm_insn (AS2 (sbis,%1-0x20,%2), operands);
6061 else
6062 output_asm_insn (AS2 (sbic,%1-0x20,%2), operands);
6064 else
6066 output_asm_insn (AS2 (in,__tmp_reg__,%1-0x20), operands);
6067 if (comp == EQ)
6068 output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands);
6069 else
6070 output_asm_insn (AS2 (sbrc,__tmp_reg__,%2), operands);
6073 else /* GET_CODE (operands[1]) == REG */
6075 if (GET_MODE (operands[1]) == QImode)
6077 if (comp == EQ)
6078 output_asm_insn (AS2 (sbrs,%1,%2), operands);
6079 else
6080 output_asm_insn (AS2 (sbrc,%1,%2), operands);
6082 else /* HImode or SImode */
6084 static char buf[] = "sbrc %A1,0";
6085 int bit_nr = exact_log2 (INTVAL (operands[2])
6086 & GET_MODE_MASK (GET_MODE (operands[1])));
6088 buf[3] = (comp == EQ) ? 's' : 'c';
6089 buf[6] = 'A' + (bit_nr >> 3);
6090 buf[9] = '0' + (bit_nr & 7);
6091 output_asm_insn (buf, operands);
6095 if (long_jump)
6096 return (AS1 (rjmp,.+4) CR_TAB
6097 AS1 (jmp,%3));
6098 if (!reverse)
6099 return AS1 (rjmp,%3);
6100 return "";
6103 /* Worker function for TARGET_ASM_CONSTRUCTOR. */
6105 static void
6106 avr_asm_out_ctor (rtx symbol, int priority)
6108 fputs ("\t.global __do_global_ctors\n", asm_out_file);
6109 default_ctor_section_asm_out_constructor (symbol, priority);
6112 /* Worker function for TARGET_ASM_DESTRUCTOR. */
6114 static void
6115 avr_asm_out_dtor (rtx symbol, int priority)
6117 fputs ("\t.global __do_global_dtors\n", asm_out_file);
6118 default_dtor_section_asm_out_destructor (symbol, priority);
6121 /* Worker function for TARGET_RETURN_IN_MEMORY. */
6123 static bool
6124 avr_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6126 if (TYPE_MODE (type) == BLKmode)
6128 HOST_WIDE_INT size = int_size_in_bytes (type);
6129 return (size == -1 || size > 8);
6131 else
6132 return false;
6135 /* Worker function for CASE_VALUES_THRESHOLD. */
6137 unsigned int avr_case_values_threshold (void)
6139 return (!AVR_HAVE_JMP_CALL || TARGET_CALL_PROLOGUES) ? 8 : 17;
6142 #include "gt-avr.h"