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