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