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