1 /* Subroutines for insn-output.cc for ATMEL AVR micro controllers 2 Copyright (C) 1998-2024 Free Software Foundation, Inc. 3 Contributed by Denis Chertykov (chertykov (at) gmail.com) 4 5 This file is part of GCC. 6 7 GCC 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 3, or (at your option) 10 any later version. 11 12 GCC 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 GCC; see the file COPYING3. If not see 19 <http://www.gnu.org/licenses/>. */ 20 21 #define IN_TARGET_CODE 1 22 23 #include "config.h" 24 #include "system.h" 25 #include "intl.h" 26 #include "coretypes.h" 27 #include "backend.h" 28 #include "target.h" 29 #include "rtl.h" 30 #include "tree.h" 31 #include "stringpool.h" 32 #include "attribs.h" 33 #include "cgraph.h" 34 #include "c-family/c-common.h" 35 #include "cfghooks.h" 36 #include "df.h" 37 #include "memmodel.h" 38 #include "tm_p.h" 39 #include "optabs.h" 40 #include "regs.h" 41 #include "emit-rtl.h" 42 #include "recog.h" 43 #include "conditions.h" 44 #include "insn-attr.h" 45 #include "reload.h" 46 #include "varasm.h" 47 #include "calls.h" 48 #include "stor-layout.h" 49 #include "output.h" 50 #include "explow.h" 51 #include "expr.h" 52 #include "langhooks.h" 53 #include "cfgrtl.h" 54 #include "builtins.h" 55 #include "context.h" 56 #include "tree-pass.h" 57 #include "print-rtl.h" 58 #include "rtl-iter.h" 59 60 /* This file should be included last. */ 61 #include "target-def.h" 62 63 /* Maximal allowed offset for an address in the LD command */ 64 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE)) 65 66 /* The 4 bits starting at SECTION_MACH_DEP are reserved to store the 67 address space where data is to be located. 68 As the only non-generic address spaces are all located in flash, 69 this can be used to test if data shall go into some .progmem* section. 70 This must be the rightmost field of machine dependent section flags. */ 71 #define AVR_SECTION_PROGMEM (0xf * SECTION_MACH_DEP) 72 73 /* Similar 4-bit region for SYMBOL_REF_FLAGS. */ 74 #define AVR_SYMBOL_FLAG_PROGMEM (0xf * SYMBOL_FLAG_MACH_DEP) 75 76 /* Similar 4-bit region in SYMBOL_REF_FLAGS: 77 Set address-space AS in SYMBOL_REF_FLAGS of SYM */ 78 #define AVR_SYMBOL_SET_ADDR_SPACE(SYM,AS) \ 79 do { \ 80 SYMBOL_REF_FLAGS (sym) &= ~AVR_SYMBOL_FLAG_PROGMEM; \ 81 SYMBOL_REF_FLAGS (sym) |= (AS) * SYMBOL_FLAG_MACH_DEP; \ 82 } while (0) 83 84 /* Read address-space from SYMBOL_REF_FLAGS of SYM */ 85 #define AVR_SYMBOL_GET_ADDR_SPACE(SYM) \ 86 ((SYMBOL_REF_FLAGS (sym) & AVR_SYMBOL_FLAG_PROGMEM) \ 87 / SYMBOL_FLAG_MACH_DEP) 88 89 /* (AVR_TINY only): Symbol has attribute progmem */ 90 #define AVR_SYMBOL_FLAG_TINY_PM \ 91 (SYMBOL_FLAG_MACH_DEP << 7) 92 93 /* (AVR_TINY only): Symbol has attribute absdata */ 94 #define AVR_SYMBOL_FLAG_TINY_ABSDATA \ 95 (SYMBOL_FLAG_MACH_DEP << 8) 96 97 #define TINY_ADIW(REG1, REG2, I) \ 98 "subi " #REG1 ",lo8(-(" #I "))" CR_TAB \ 99 "sbci " #REG2 ",hi8(-(" #I "))" 100 101 #define TINY_SBIW(REG1, REG2, I) \ 102 "subi " #REG1 ",lo8((" #I "))" CR_TAB \ 103 "sbci " #REG2 ",hi8((" #I "))" 104 105 #define AVR_TMP_REGNO (AVR_TINY ? TMP_REGNO_TINY : TMP_REGNO) 106 #define AVR_ZERO_REGNO (AVR_TINY ? ZERO_REGNO_TINY : ZERO_REGNO) 107 108 /* Known address spaces. The order must be the same as in the respective 109 enum from avr.h (or designated initialized must be used). */ 110 const avr_addrspace_t avr_addrspace[ADDR_SPACE_COUNT] = 111 { 112 { ADDR_SPACE_RAM, 0, 2, "", 0, NULL }, 113 { ADDR_SPACE_FLASH, 1, 2, "__flash", 0, ".progmem.data" }, 114 { ADDR_SPACE_FLASH1, 1, 2, "__flash1", 1, ".progmem1.data" }, 115 { ADDR_SPACE_FLASH2, 1, 2, "__flash2", 2, ".progmem2.data" }, 116 { ADDR_SPACE_FLASH3, 1, 2, "__flash3", 3, ".progmem3.data" }, 117 { ADDR_SPACE_FLASH4, 1, 2, "__flash4", 4, ".progmem4.data" }, 118 { ADDR_SPACE_FLASH5, 1, 2, "__flash5", 5, ".progmem5.data" }, 119 { ADDR_SPACE_MEMX, 1, 3, "__memx", 0, ".progmemx.data" }, 120 }; 121 122 123 /* Holding RAM addresses of some SFRs used by the compiler and that 124 are unique over all devices in an architecture like 'avr4'. */ 125 126 typedef struct 127 { 128 /* SREG: The processor status */ 129 int sreg; 130 131 /* RAMPX, RAMPY, RAMPD and CCP of XMEGA */ 132 int ccp; 133 int rampd; 134 int rampx; 135 int rampy; 136 137 /* RAMPZ: The high byte of 24-bit address used with ELPM */ 138 int rampz; 139 140 /* SP: The stack pointer and its low and high byte */ 141 int sp_l; 142 int sp_h; 143 } avr_addr_t; 144 145 static avr_addr_t avr_addr; 146 147 148 /* Prototypes for local helper functions. */ 149 150 static const char *out_movqi_r_mr (rtx_insn *, rtx[], int *); 151 static const char *out_movhi_r_mr (rtx_insn *, rtx[], int *); 152 static const char *out_movsi_r_mr (rtx_insn *, rtx[], int *); 153 static const char *out_movqi_mr_r (rtx_insn *, rtx[], int *); 154 static const char *out_movhi_mr_r (rtx_insn *, rtx[], int *); 155 static const char *out_movsi_mr_r (rtx_insn *, rtx[], int *); 156 157 static int get_sequence_length (rtx_insn *insns); 158 static int sequent_regs_live (void); 159 static const char *ptrreg_to_str (int); 160 static const char *cond_string (enum rtx_code); 161 static int avr_num_arg_regs (machine_mode, const_tree); 162 static int avr_operand_rtx_cost (rtx, machine_mode, enum rtx_code, 163 int, bool); 164 static void output_reload_in_const (rtx *, rtx, int *, bool); 165 static struct machine_function *avr_init_machine_status (void); 166 static bool _reg_unused_after (rtx_insn *insn, rtx reg, bool look_at_insn); 167 168 169 /* Prototypes for hook implementors if needed before their implementation. */ 170 171 static bool avr_rtx_costs (rtx, machine_mode, int, int, int *, bool); 172 173 174 /* Allocate registers from r25 to r8 for parameters for function calls 175 resp. r25 to r20 for reduced Tiny. */ 176 #define FIRST_CUM_REG REG_26 177 178 /* Last call saved register */ 179 #define LAST_CALLEE_SAVED_REG (AVR_TINY ? REG_19 : REG_17) 180 181 /* Implicit target register of LPM instruction (R0) */ 182 extern GTY(()) rtx lpm_reg_rtx; 183 rtx lpm_reg_rtx; 184 185 /* (Implicit) address register of LPM instruction (R31:R30 = Z) */ 186 extern GTY(()) rtx lpm_addr_reg_rtx; 187 rtx lpm_addr_reg_rtx; 188 189 /* Temporary register RTX (reg:QI TMP_REGNO) */ 190 extern GTY(()) rtx tmp_reg_rtx; 191 rtx tmp_reg_rtx; 192 193 /* Zeroed register RTX (reg:QI ZERO_REGNO) */ 194 extern GTY(()) rtx zero_reg_rtx; 195 rtx zero_reg_rtx; 196 197 /* Condition Code register RTX (reg:CC REG_CC) */ 198 extern GTY(()) rtx cc_reg_rtx; 199 rtx cc_reg_rtx; 200 201 /* RTXs for all general purpose registers as QImode */ 202 extern GTY(()) rtx all_regs_rtx[REG_32]; 203 rtx all_regs_rtx[REG_32]; 204 205 /* SREG, the processor status */ 206 extern GTY(()) rtx sreg_rtx; 207 rtx sreg_rtx; 208 209 /* RAMP* special function registers */ 210 extern GTY(()) rtx rampd_rtx; 211 extern GTY(()) rtx rampx_rtx; 212 extern GTY(()) rtx rampy_rtx; 213 extern GTY(()) rtx rampz_rtx; 214 rtx rampd_rtx; 215 rtx rampx_rtx; 216 rtx rampy_rtx; 217 rtx rampz_rtx; 218 219 /* RTX containing the strings "" and "e", respectively */ 220 static GTY(()) rtx xstring_empty; 221 static GTY(()) rtx xstring_e; 222 223 /* Current architecture. */ 224 const avr_arch_t *avr_arch; 225 enum avr_arch_id avr_arch_index; 226 227 /* Unnamed sections associated to __attribute__((progmem)) aka. PROGMEM 228 or to address space __flash* or __memx. Only used as singletons inside 229 avr_asm_select_section, but it must not be local there because of GTY. */ 230 static GTY(()) section *progmem_section[ADDR_SPACE_COUNT]; 231 232 /* Condition for insns/expanders from avr-dimode.md. */ 233 bool avr_have_dimode = true; 234 235 /* To track if code will use .bss, .data, .rodata. */ 236 bool avr_need_clear_bss_p = false; 237 bool avr_need_copy_data_p = false; 238 bool avr_has_rodata_p = false; 239 240 241 /* Transform UP into lowercase and write the result to LO. 243 You must provide enough space for LO. Return LO. */ 244 245 static char * 246 avr_tolower (char *lo, const char *up) 247 { 248 char *lo0 = lo; 249 250 for (; *up; up++, lo++) 251 *lo = TOLOWER (*up); 252 253 *lo = '\0'; 254 255 return lo0; 256 } 257 258 259 /* Constraint helper function. XVAL is a CONST_INT or a CONST_DOUBLE. 260 Return true if the least significant N_BYTES bytes of XVAL all have a 261 popcount in POP_MASK and false, otherwise. POP_MASK represents a subset 262 of integers which contains an integer N iff bit N of POP_MASK is set. */ 263 264 bool 265 avr_popcount_each_byte (rtx xval, int n_bytes, int pop_mask) 266 { 267 machine_mode mode = GET_MODE (xval); 268 269 if (VOIDmode == mode) 270 mode = SImode; 271 272 for (int i = 0; i < n_bytes; i++) 273 { 274 rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i); 275 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode); 276 277 if ((pop_mask & (1 << popcount_hwi (val8))) == 0) 278 return false; 279 } 280 281 return true; 282 } 283 284 285 /* Constraint helper function. XVAL is a CONST_INT. Return true if we 286 can perform XOR without a clobber reg, provided the operation is on 287 a d-register. This means each byte is in { 0, 0xff, 0x80 }. */ 288 289 bool 290 avr_xor_noclobber_dconst (rtx xval, int n_bytes) 291 { 292 machine_mode mode = GET_MODE (xval); 293 294 if (VOIDmode == mode) 295 mode = SImode; 296 297 for (int i = 0; i < n_bytes; ++i) 298 { 299 rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i); 300 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode); 301 302 if (val8 != 0 && val8 != 0xff && val8 != 0x80) 303 return false; 304 } 305 306 return true; 307 } 308 309 310 /* Access some RTX as INT_MODE. If X is a CONST_FIXED we can get 311 the bit representation of X by "casting" it to CONST_INT. */ 312 313 rtx 314 avr_to_int_mode (rtx x) 315 { 316 machine_mode mode = GET_MODE (x); 317 318 return VOIDmode == mode 319 ? x 320 : simplify_gen_subreg (int_mode_for_mode (mode).require (), x, mode, 0); 321 } 322 323 324 /* Return true if hard register REG supports the ADIW and SBIW instructions. */ 325 326 bool 327 avr_adiw_reg_p (rtx reg) 328 { 329 return (AVR_HAVE_ADIW 330 && test_hard_reg_class (ADDW_REGS, reg)); 331 } 332 333 334 namespace { 335 336 static const pass_data avr_pass_data_recompute_notes = 337 { 338 RTL_PASS, // type 339 "", // name (will be patched) 340 OPTGROUP_NONE, // optinfo_flags 341 TV_DF_SCAN, // tv_id 342 0, // properties_required 343 0, // properties_provided 344 0, // properties_destroyed 345 0, // todo_flags_start 346 TODO_df_finish | TODO_df_verify // todo_flags_finish 347 }; 348 349 350 class avr_pass_recompute_notes : public rtl_opt_pass 351 { 352 public: 353 avr_pass_recompute_notes (gcc::context *ctxt, const char *name) 354 : rtl_opt_pass (avr_pass_data_recompute_notes, ctxt) 355 { 356 this->name = name; 357 } 358 359 virtual unsigned int execute (function *) 360 { 361 df_note_add_problem (); 362 df_analyze (); 363 364 return 0; 365 } 366 }; // avr_pass_recompute_notes 367 368 static const pass_data avr_pass_data_casesi = 369 { 370 RTL_PASS, // type 371 "", // name (will be patched) 372 OPTGROUP_NONE, // optinfo_flags 373 TV_DF_SCAN, // tv_id 374 0, // properties_required 375 0, // properties_provided 376 0, // properties_destroyed 377 0, // todo_flags_start 378 0 // todo_flags_finish 379 }; 380 381 382 class avr_pass_casesi : public rtl_opt_pass 383 { 384 public: 385 avr_pass_casesi (gcc::context *ctxt, const char *name) 386 : rtl_opt_pass (avr_pass_data_casesi, ctxt) 387 { 388 this->name = name; 389 } 390 391 void avr_rest_of_handle_casesi (function *); 392 393 virtual bool gate (function *) { return optimize > 0; } 394 395 virtual unsigned int execute (function *func) 396 { 397 avr_rest_of_handle_casesi (func); 398 399 return 0; 400 } 401 }; // avr_pass_casesi 402 403 404 static const pass_data avr_pass_data_ifelse = 405 { 406 RTL_PASS, // type 407 "", // name (will be patched) 408 OPTGROUP_NONE, // optinfo_flags 409 TV_DF_SCAN, // tv_id 410 0, // properties_required 411 0, // properties_provided 412 0, // properties_destroyed 413 0, // todo_flags_start 414 TODO_df_finish | TODO_df_verify // todo_flags_finish 415 }; 416 417 class avr_pass_ifelse : public rtl_opt_pass 418 { 419 public: 420 avr_pass_ifelse (gcc::context *ctxt, const char *name) 421 : rtl_opt_pass (avr_pass_data_ifelse, ctxt) 422 { 423 this->name = name; 424 } 425 426 void avr_rest_of_handle_ifelse (function *); 427 428 virtual bool gate (function *) { return optimize > 0; } 429 430 virtual unsigned int execute (function *func) 431 { 432 avr_rest_of_handle_ifelse (func); 433 434 return 0; 435 } 436 }; // avr_pass_ifelse 437 438 } // anon namespace 439 440 rtl_opt_pass * 441 make_avr_pass_recompute_notes (gcc::context *ctxt) 442 { 443 return new avr_pass_recompute_notes (ctxt, "avr-notes-free-cfg"); 444 } 445 446 rtl_opt_pass * 447 make_avr_pass_casesi (gcc::context *ctxt) 448 { 449 return new avr_pass_casesi (ctxt, "avr-casesi"); 450 } 451 452 rtl_opt_pass * 453 make_avr_pass_ifelse (gcc::context *ctxt) 454 { 455 return new avr_pass_ifelse (ctxt, "avr-ifelse"); 456 } 457 458 459 /* Make one parallel insn with all the patterns from insns i[0]..i[5]. */ 460 461 static rtx_insn * 462 avr_parallel_insn_from_insns (rtx_insn *i[5]) 463 { 464 rtvec vec = gen_rtvec (5, PATTERN (i[0]), PATTERN (i[1]), PATTERN (i[2]), 465 PATTERN (i[3]), PATTERN (i[4])); 466 start_sequence(); 467 emit (gen_rtx_PARALLEL (VOIDmode, vec)); 468 rtx_insn *insn = get_insns(); 469 end_sequence(); 470 471 return insn; 472 } 473 474 475 /* Return true if we see an insn stream generated by casesi expander together 476 with an extension to SImode of the switch value. 477 478 If this is the case, fill in the insns from casesi to INSNS[1..5] and 479 the SImode extension to INSNS[0]. Moreover, extract the operands of 480 pattern casesi_<mode>_sequence forged from the sequence to recog_data. */ 481 482 static bool 483 avr_is_casesi_sequence (basic_block bb, rtx_insn *insn, rtx_insn *insns[5]) 484 { 485 rtx set_4, set_0; 486 487 /* A first and quick test for a casesi sequences. As a side effect of 488 the test, harvest respective insns to INSNS[0..4]. */ 489 490 if (!(JUMP_P (insns[4] = insn) 491 // casesi is the only insn that comes up with UNSPEC_INDEX_JMP, 492 // hence the following test ensures that we are actually dealing 493 // with code from casesi. 494 && (set_4 = single_set (insns[4])) 495 && UNSPEC == GET_CODE (SET_SRC (set_4)) 496 && UNSPEC_INDEX_JMP == XINT (SET_SRC (set_4), 1) 497 498 && (insns[3] = prev_real_insn (insns[4])) 499 && (insns[2] = prev_real_insn (insns[3])) 500 && (insns[1] = prev_real_insn (insns[2])) 501 502 // Insn prior to casesi. 503 && (insns[0] = prev_real_insn (insns[1])) 504 && (set_0 = single_set (insns[0])) 505 && extend_operator (SET_SRC (set_0), SImode))) 506 { 507 return false; 508 } 509 510 if (dump_file) 511 { 512 fprintf (dump_file, ";; Sequence from casesi in " 513 "[bb %d]:\n\n", bb->index); 514 for (int i = 0; i < 5; i++) 515 print_rtl_single (dump_file, insns[i]); 516 } 517 518 /* We have to deal with quite some operands. Extracting them by hand 519 would be tedious, therefore wrap the insn patterns into a parallel, 520 run recog against it and then use insn extract to get the operands. */ 521 522 rtx_insn *xinsn = avr_parallel_insn_from_insns (insns); 523 524 INSN_CODE (xinsn) = recog (PATTERN (xinsn), xinsn, NULL /* num_clobbers */); 525 526 /* Failing to recognize means that someone changed the casesi expander or 527 that some passes prior to this one performed some unexpected changes. 528 Gracefully drop such situations instead of aborting. */ 529 530 if (INSN_CODE (xinsn) < 0) 531 { 532 if (dump_file) 533 fprintf (dump_file, ";; Sequence not recognized, giving up.\n\n"); 534 535 return false; 536 } 537 538 gcc_assert (CODE_FOR_casesi_qi_sequence == INSN_CODE (xinsn) 539 || CODE_FOR_casesi_hi_sequence == INSN_CODE (xinsn)); 540 541 extract_insn (xinsn); 542 543 // Assert on the anatomy of xinsn's operands we are going to work with. 544 545 gcc_assert (recog_data.n_operands == 11); 546 gcc_assert (recog_data.n_dups == 4); 547 548 if (dump_file) 549 { 550 fprintf (dump_file, ";; Operands extracted:\n"); 551 for (int i = 0; i < recog_data.n_operands; i++) 552 avr_fdump (dump_file, ";; $%d = %r\n", i, recog_data.operand[i]); 553 fprintf (dump_file, "\n"); 554 } 555 556 return true; 557 } 558 559 560 /* Perform some extra checks on operands of casesi_<mode>_sequence. 561 Not all operand dependencies can be described by means of predicates. 562 This function performs left over checks and should always return true. 563 Returning false means that someone changed the casesi expander but did 564 not adjust casesi_<mode>_sequence. */ 565 566 bool 567 avr_casei_sequence_check_operands (rtx *xop) 568 { 569 rtx sub_5 = NULL_RTX; 570 571 if (AVR_HAVE_EIJMP_EICALL 572 // The last clobber op of the tablejump. 573 && xop[8] == all_regs_rtx[REG_24]) 574 { 575 // $6 is: (subreg:SI ($5) 0) 576 sub_5 = xop[6]; 577 } 578 579 if (!AVR_HAVE_EIJMP_EICALL 580 // $6 is: (plus:HI (subreg:SI ($5) 0) 581 // (label_ref ($3))) 582 && PLUS == GET_CODE (xop[6]) 583 && LABEL_REF == GET_CODE (XEXP (xop[6], 1)) 584 && rtx_equal_p (xop[3], XEXP (XEXP (xop[6], 1), 0)) 585 // The last clobber op of the tablejump. 586 && xop[8] == const0_rtx) 587 { 588 sub_5 = XEXP (xop[6], 0); 589 } 590 591 if (sub_5 592 && SUBREG_P (sub_5) 593 && SUBREG_BYTE (sub_5) == 0 594 && rtx_equal_p (xop[5], SUBREG_REG (sub_5))) 595 return true; 596 597 if (dump_file) 598 fprintf (dump_file, "\n;; Failed condition for casesi_<mode>_sequence\n\n"); 599 600 return false; 601 } 602 603 604 /* INSNS[1..4] is a sequence as generated by casesi and INSNS[0] is an 605 extension of an 8-bit or 16-bit integer to SImode. XOP contains the 606 operands of INSNS as extracted by insn_extract from pattern 607 casesi_<mode>_sequence: 608 609 $0: SImode reg switch value as result of $9. 610 $1: Negative of smallest index in switch. 611 $2: Number of entries in switch. 612 $3: Label to table. 613 $4: Label if out-of-bounds. 614 $5: $0 + $1. 615 $6: 3-byte PC: subreg:HI ($5) + label_ref ($3) 616 2-byte PC: subreg:HI ($5) 617 $7: HI reg index into table (Z or pseudo) 618 $8: R24 or const0_rtx (to be clobbered) 619 $9: Extension to SImode of an 8-bit or 16-bit integer register $10. 620 $10: QImode or HImode register input of $9. 621 622 Try to optimize this sequence, i.e. use the original HImode / QImode 623 switch value instead of SImode. */ 624 625 static void 626 avr_optimize_casesi (rtx_insn *insns[5], rtx *xop) 627 { 628 // Original mode of the switch value; this is QImode or HImode. 629 machine_mode mode = GET_MODE (xop[10]); 630 631 // How the original switch value was extended to SImode; this is 632 // SIGN_EXTEND or ZERO_EXTEND. 633 enum rtx_code code = GET_CODE (xop[9]); 634 635 // Lower index, upper index (plus one) and range of case calues. 636 HOST_WIDE_INT low_idx = -INTVAL (xop[1]); 637 HOST_WIDE_INT num_idx = INTVAL (xop[2]); 638 HOST_WIDE_INT hig_idx = low_idx + num_idx; 639 640 // Maximum ranges of (un)signed QImode resp. HImode. 641 unsigned umax = QImode == mode ? 0xff : 0xffff; 642 int imax = QImode == mode ? 0x7f : 0x7fff; 643 int imin = -imax - 1; 644 645 // Testing the case range and whether it fits into the range of the 646 // (un)signed mode. This test should actually always pass because it 647 // makes no sense to have case values outside the mode range. Notice 648 // that case labels which are unreachable because they are outside the 649 // mode of the switch value (e.g. "case -1" for uint8_t) have already 650 // been thrown away by the middle-end. 651 652 if (SIGN_EXTEND == code 653 && low_idx >= imin 654 && hig_idx <= imax) 655 { 656 // ok 657 } 658 else if (ZERO_EXTEND == code 659 && low_idx >= 0 660 && (unsigned) hig_idx <= umax) 661 { 662 // ok 663 } 664 else 665 { 666 if (dump_file) 667 fprintf (dump_file, ";; Case ranges too big, giving up.\n\n"); 668 return; 669 } 670 671 // Do normalization of switch value $10 and out-of-bound check in its 672 // original mode instead of in SImode. Use a newly created pseudo. 673 // This will replace insns[1..2]. 674 675 start_sequence(); 676 677 rtx reg = copy_to_mode_reg (mode, xop[10]); 678 679 rtx (*gen_add)(rtx,rtx,rtx) = QImode == mode ? gen_addqi3 : gen_addhi3; 680 rtx (*gen_cbranch)(rtx,rtx,rtx,rtx) 681 = QImode == mode ? gen_cbranchqi4 : gen_cbranchhi4; 682 683 emit_insn (gen_add (reg, reg, gen_int_mode (-low_idx, mode))); 684 rtx op0 = reg; rtx op1 = gen_int_mode (num_idx, mode); 685 rtx labelref = copy_rtx (xop[4]); 686 rtx xbranch = gen_cbranch (gen_rtx_fmt_ee (GTU, VOIDmode, op0, op1), 687 op0, op1, labelref); 688 rtx_insn *cbranch = emit_jump_insn (xbranch); 689 JUMP_LABEL (cbranch) = xop[4]; 690 ++LABEL_NUSES (xop[4]); 691 692 rtx_insn *seq1 = get_insns(); 693 rtx_insn *last1 = get_last_insn(); 694 end_sequence(); 695 696 emit_insn_after (seq1, insns[2]); 697 698 // After the out-of-bounds test and corresponding branch, use a 699 // 16-bit index. If QImode is used, extend it to HImode first. 700 // This will replace insns[4]. 701 702 start_sequence(); 703 704 if (QImode == mode) 705 reg = force_reg (HImode, gen_rtx_fmt_e (code, HImode, reg)); 706 707 rtx pat_4 = AVR_3_BYTE_PC 708 ? gen_movhi (xop[7], reg) 709 : gen_addhi3 (xop[7], reg, gen_rtx_LABEL_REF (VOIDmode, xop[3])); 710 711 emit_insn (pat_4); 712 713 rtx_insn *seq2 = get_insns(); 714 rtx_insn *last2 = get_last_insn(); 715 end_sequence(); 716 717 emit_insn_after (seq2, insns[3]); 718 719 if (dump_file) 720 { 721 fprintf (dump_file, ";; New insns: "); 722 723 for (rtx_insn *insn = seq1; ; insn = NEXT_INSN (insn)) 724 { 725 fprintf (dump_file, "%d, ", INSN_UID (insn)); 726 if (insn == last1) 727 break; 728 } 729 for (rtx_insn *insn = seq2; ; insn = NEXT_INSN (insn)) 730 { 731 fprintf (dump_file, "%d%s", INSN_UID (insn), 732 insn == last2 ? ".\n\n" : ", "); 733 if (insn == last2) 734 break; 735 } 736 737 fprintf (dump_file, ";; Deleting insns: %d, %d, %d.\n\n", 738 INSN_UID (insns[1]), INSN_UID (insns[2]), INSN_UID (insns[3])); 739 } 740 741 // Pseudodelete the SImode and subreg of SImode insns. We don't care 742 // about the extension insns[0]: Its result is now unused and other 743 // passes will clean it up. 744 745 SET_INSN_DELETED (insns[1]); 746 SET_INSN_DELETED (insns[2]); 747 SET_INSN_DELETED (insns[3]); 748 } 749 750 751 void 752 avr_pass_casesi::avr_rest_of_handle_casesi (function *func) 753 { 754 basic_block bb; 755 756 FOR_EACH_BB_FN (bb, func) 757 { 758 rtx_insn *insn, *insns[5]; 759 760 FOR_BB_INSNS (bb, insn) 761 { 762 if (avr_is_casesi_sequence (bb, insn, insns)) 763 { 764 avr_optimize_casesi (insns, recog_data.operand); 765 } 766 } 767 } 768 } 769 770 771 /* A helper for the next method. Suppose we have two conditional branches 772 773 if (reg <cond1> xval1) goto label1; 774 if (reg <cond2> xval2) goto label2; 775 776 If the second comparison is redundant and there is a code <cond> such 777 that the sequence can be performed as 778 779 REG_CC = compare (reg, xval1); 780 if (REG_CC <cond1> 0) goto label1; 781 if (REG_CC <cond> 0) goto label2; 782 783 then return <cond>. Otherwise, return UNKNOWN. 784 xval1 and xval2 are CONST_INT, and mode is the scalar int mode in which 785 the comparison will be carried out. reverse_cond1 can be set to reverse 786 condition cond1. This is useful if the second comparison does not follow 787 the first one, but is located after label1 like in: 788 789 if (reg <cond1> xval1) goto label1; 790 ... 791 label1: 792 if (reg <cond2> xval2) goto label2; */ 793 794 static enum rtx_code 795 avr_redundant_compare (enum rtx_code cond1, rtx xval1, 796 enum rtx_code cond2, rtx xval2, 797 machine_mode mode, bool reverse_cond1) 798 { 799 HOST_WIDE_INT ival1 = INTVAL (xval1); 800 HOST_WIDE_INT ival2 = INTVAL (xval2); 801 802 unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode); 803 unsigned HOST_WIDE_INT uval1 = mask & UINTVAL (xval1); 804 unsigned HOST_WIDE_INT uval2 = mask & UINTVAL (xval2); 805 806 if (reverse_cond1) 807 cond1 = reverse_condition (cond1); 808 809 if (cond1 == EQ) 810 { 811 //////////////////////////////////////////////// 812 // A sequence like 813 // if (reg == val) goto label1; 814 // if (reg > val) goto label2; 815 // can be re-written using the same, simple comparison like in: 816 // REG_CC = compare (reg, val) 817 // if (REG_CC == 0) goto label1; 818 // if (REG_CC >= 0) goto label2; 819 if (ival1 == ival2 820 && (cond2 == GT || cond2 == GTU)) 821 return avr_normalize_condition (cond2); 822 823 // Similar, but the input sequence is like 824 // if (reg == val) goto label1; 825 // if (reg >= val) goto label2; 826 if (ival1 == ival2 827 && (cond2 == GE || cond2 == GEU)) 828 return cond2; 829 830 // Similar, but the input sequence is like 831 // if (reg == val) goto label1; 832 // if (reg >= val + 1) goto label2; 833 if ((cond2 == GE && ival2 == 1 + ival1) 834 || (cond2 == GEU && uval2 == 1 + uval1)) 835 return cond2; 836 837 // Similar, but the input sequence is like 838 // if (reg == val) goto label1; 839 // if (reg > val - 1) goto label2; 840 if ((cond2 == GT && ival2 == ival1 - 1) 841 || (cond2 == GTU && uval2 == uval1 - 1)) 842 return avr_normalize_condition (cond2); 843 844 ///////////////////////////////////////////////////////// 845 // A sequence like 846 // if (reg == val) goto label1; 847 // if (reg < 1 + val) goto label2; 848 // can be re-written as 849 // REG_CC = compare (reg, val) 850 // if (REG_CC == 0) goto label1; 851 // if (REG_CC < 0) goto label2; 852 if ((cond2 == LT && ival2 == 1 + ival1) 853 || (cond2 == LTU && uval2 == 1 + uval1)) 854 return cond2; 855 856 // Similar, but with an input sequence like 857 // if (reg == val) goto label1; 858 // if (reg <= val) goto label2; 859 if (ival1 == ival2 860 && (cond2 == LE || cond2 == LEU)) 861 return avr_normalize_condition (cond2); 862 863 // Similar, but with an input sequence like 864 // if (reg == val) goto label1; 865 // if (reg < val) goto label2; 866 if (ival1 == ival2 867 && (cond2 == LT || cond2 == LTU)) 868 return cond2; 869 870 // Similar, but with an input sequence like 871 // if (reg == val) goto label1; 872 // if (reg <= val - 1) goto label2; 873 if ((cond2 == LE && ival2 == ival1 - 1) 874 || (cond2 == LEU && uval2 == uval1 - 1)) 875 return avr_normalize_condition (cond2); 876 877 } // cond1 == EQ 878 879 return UNKNOWN; 880 } 881 882 883 /* If-else decision trees generated for switch / case may produce sequences 884 like 885 886 SREG = compare (reg, val); 887 if (SREG == 0) goto label1; 888 SREG = compare (reg, 1 + val); 889 if (SREG >= 0) goto label2; 890 891 which can be optimized to 892 893 SREG = compare (reg, val); 894 if (SREG == 0) goto label1; 895 if (SREG >= 0) goto label2; 896 897 The optimal place for such a pass would be directly after expand, but 898 it's not possible for a jump insn to target more than one code label. 899 Hence, run a mini pass right before split2 which introduces REG_CC. */ 900 901 void 902 avr_pass_ifelse::avr_rest_of_handle_ifelse (function *) 903 { 904 rtx_insn *next_insn; 905 906 for (rtx_insn *insn = get_insns(); insn; insn = next_insn) 907 { 908 next_insn = next_nonnote_nondebug_insn (insn); 909 910 if (! next_insn) 911 break; 912 913 // Search for two cbranch insns. The first one is a cbranch. 914 // Filter for "cbranch<mode>4_insn" with mode in QI, HI, PSI, SI. 915 916 if (! JUMP_P (insn)) 917 continue; 918 919 int icode1 = recog_memoized (insn); 920 921 if (icode1 != CODE_FOR_cbranchqi4_insn 922 && icode1 != CODE_FOR_cbranchhi4_insn 923 && icode1 != CODE_FOR_cbranchpsi4_insn 924 && icode1 != CODE_FOR_cbranchsi4_insn) 925 continue; 926 927 rtx_jump_insn *insn1 = as_a<rtx_jump_insn *> (insn); 928 rtx_jump_insn *insn2 = nullptr; 929 bool follow_label1 = false; 930 931 // Extract the operands of the first insn: 932 // $0 = comparison operator ($1, $2) 933 // $1 = reg 934 // $2 = reg or const_int 935 // $3 = code_label 936 // $4 = optional SCRATCH for HI, PSI, SI cases. 937 938 const auto &op = recog_data.operand; 939 940 extract_insn (insn1); 941 rtx xop1[5] = { op[0], op[1], op[2], op[3], op[4] }; 942 int n_operands = recog_data.n_operands; 943 944 // For now, we can optimize cbranches that follow an EQ cbranch, 945 // and cbranches that follow the label of a NE cbranch. 946 947 if (GET_CODE (xop1[0]) == EQ 948 && JUMP_P (next_insn) 949 && recog_memoized (next_insn) == icode1) 950 { 951 // The 2nd cbranch insn follows insn1, i.e. is located in the 952 // fallthrough path of insn1. 953 954 insn2 = as_a<rtx_jump_insn *> (next_insn); 955 } 956 else if (GET_CODE (xop1[0]) == NE) 957 { 958 // insn1 might branch to a label followed by a cbranch. 959 960 rtx target1 = JUMP_LABEL (insn1); 961 rtx_insn *code_label1 = JUMP_LABEL_AS_INSN (insn1); 962 rtx_insn *next = next_nonnote_nondebug_insn (code_label1); 963 rtx_insn *barrier = prev_nonnote_nondebug_insn (code_label1); 964 965 if (// Target label of insn1 is used exactly once and 966 // is not a fallthru, i.e. is preceded by a barrier. 967 LABEL_NUSES (target1) == 1 968 && barrier 969 && BARRIER_P (barrier) 970 // Following the target label is a cbranch of the same kind. 971 && next 972 && JUMP_P (next) 973 && recog_memoized (next) == icode1) 974 { 975 follow_label1 = true; 976 insn2 = as_a<rtx_jump_insn *> (next); 977 } 978 } 979 980 if (! insn2) 981 continue; 982 983 // Also extract operands of insn2, and filter for REG + CONST_INT 984 // comparsons against the same register. 985 986 extract_insn (insn2); 987 rtx xop2[5] = { op[0], op[1], op[2], op[3], op[4] }; 988 989 if (! rtx_equal_p (xop1[1], xop2[1]) 990 || ! CONST_INT_P (xop1[2]) 991 || ! CONST_INT_P (xop2[2])) 992 continue; 993 994 machine_mode mode = GET_MODE (xop1[1]); 995 enum rtx_code code1 = GET_CODE (xop1[0]); 996 enum rtx_code code2 = GET_CODE (xop2[0]); 997 998 code2 = avr_redundant_compare (code1, xop1[2], code2, xop2[2], 999 mode, follow_label1); 1000 if (code2 == UNKNOWN) 1001 continue; 1002 1003 ////////////////////////////////////////////////////// 1004 // Found a replacement. 1005 1006 if (dump_file) 1007 { 1008 fprintf (dump_file, "\n;; Found chain of jump_insn %d and" 1009 " jump_insn %d, follow_label1=%d:\n", 1010 INSN_UID (insn1), INSN_UID (insn2), follow_label1); 1011 print_rtl_single (dump_file, PATTERN (insn1)); 1012 print_rtl_single (dump_file, PATTERN (insn2)); 1013 } 1014 1015 if (! follow_label1) 1016 next_insn = next_nonnote_nondebug_insn (insn2); 1017 1018 // Pop the new branch conditions and the new comparison. 1019 // Prematurely split into compare + branch so that we can drop 1020 // the 2nd comparison. The following pass, split2, splits all 1021 // insns for REG_CC, and it should still work as usual even when 1022 // there are already some REG_CC insns around. 1023 1024 rtx xcond1 = gen_rtx_fmt_ee (code1, VOIDmode, cc_reg_rtx, const0_rtx); 1025 rtx xcond2 = gen_rtx_fmt_ee (code2, VOIDmode, cc_reg_rtx, const0_rtx); 1026 rtx xpat1 = gen_branch (xop1[3], xcond1); 1027 rtx xpat2 = gen_branch (xop2[3], xcond2); 1028 rtx xcompare = NULL_RTX; 1029 1030 if (mode == QImode) 1031 { 1032 gcc_assert (n_operands == 4); 1033 xcompare = gen_cmpqi3 (xop1[1], xop1[2]); 1034 } 1035 else 1036 { 1037 gcc_assert (n_operands == 5); 1038 rtx (*gen_cmp)(rtx,rtx,rtx) 1039 = mode == HImode ? gen_gen_comparehi 1040 : mode == PSImode ? gen_gen_comparepsi 1041 : gen_gen_comparesi; // SImode 1042 xcompare = gen_cmp (xop1[1], xop1[2], xop1[4]); 1043 } 1044 1045 // Emit that stuff. 1046 1047 rtx_insn *cmp = emit_insn_before (xcompare, insn1); 1048 rtx_jump_insn *branch1 = emit_jump_insn_before (xpat1, insn1); 1049 rtx_jump_insn *branch2 = emit_jump_insn_before (xpat2, insn2); 1050 1051 JUMP_LABEL (branch1) = xop1[3]; 1052 JUMP_LABEL (branch2) = xop2[3]; 1053 // delete_insn() decrements LABEL_NUSES when deleting a JUMP_INSN, but 1054 // when we pop a new JUMP_INSN, do it by hand. 1055 ++LABEL_NUSES (xop1[3]); 1056 ++LABEL_NUSES (xop2[3]); 1057 1058 delete_insn (insn1); 1059 delete_insn (insn2); 1060 1061 // As a side effect, also recog the new insns. 1062 gcc_assert (valid_insn_p (cmp)); 1063 gcc_assert (valid_insn_p (branch1)); 1064 gcc_assert (valid_insn_p (branch2)); 1065 } // loop insns 1066 } 1067 1068 1069 /* Set `avr_arch' as specified by `-mmcu='. 1070 Return true on success. */ 1071 1072 static bool 1073 avr_set_core_architecture (void) 1074 { 1075 /* Search for mcu core architecture. */ 1076 1077 if (!avr_mmcu) 1078 avr_mmcu = AVR_MMCU_DEFAULT; 1079 1080 avr_arch = &avr_arch_types[0]; 1081 1082 for (const avr_mcu_t *mcu = avr_mcu_types; ; mcu++) 1083 { 1084 if (mcu->name == NULL) 1085 { 1086 /* Reached the end of `avr_mcu_types'. This should actually never 1087 happen as options are provided by device-specs. It could be a 1088 typo in a device-specs or calling the compiler proper directly 1089 with -mmcu=<device>. */ 1090 1091 error ("unknown core architecture %qs specified with %qs", 1092 avr_mmcu, "-mmcu="); 1093 avr_inform_core_architectures (); 1094 break; 1095 } 1096 else if (strcmp (mcu->name, avr_mmcu) == 0 1097 // Is this a proper architecture ? 1098 && mcu->macro == NULL) 1099 { 1100 avr_arch = &avr_arch_types[mcu->arch_id]; 1101 avr_arch_index = mcu->arch_id; 1102 if (avr_n_flash < 0) 1103 avr_n_flash = 1 + (mcu->flash_size - 1) / 0x10000; 1104 1105 return true; 1106 } 1107 } 1108 1109 return false; 1110 } 1111 1112 1113 /* Implement `TARGET_OPTION_OVERRIDE'. */ 1114 1115 static void 1116 avr_option_override (void) 1117 { 1118 /* caller-save.cc looks for call-clobbered hard registers that are assigned 1119 to pseudos that cross calls and tries so save-restore them around calls 1120 in order to reduce the number of stack slots needed. 1121 1122 This might lead to situations where reload is no more able to cope 1123 with the challenge of AVR's very few address registers and fails to 1124 perform the requested spills. */ 1125 1126 if (avr_strict_X) 1127 flag_caller_saves = 0; 1128 1129 /* Unwind tables currently require a frame pointer for correctness, 1130 see toplev.cc:process_options(). */ 1131 1132 if ((flag_unwind_tables 1133 || flag_non_call_exceptions 1134 || flag_asynchronous_unwind_tables) 1135 && !ACCUMULATE_OUTGOING_ARGS) 1136 { 1137 flag_omit_frame_pointer = 0; 1138 } 1139 1140 /* Disable flag_delete_null_pointer_checks if zero is a valid address. */ 1141 if (targetm.addr_space.zero_address_valid (ADDR_SPACE_GENERIC)) 1142 flag_delete_null_pointer_checks = 0; 1143 1144 /* PR ipa/92606: Inter-procedural analysis optimizes data across 1145 address-spaces and PROGMEM. As of v14, the PROGMEM part is 1146 still not fixed (and there is still no target hook as proposed 1147 in PR92932). Just disable respective bogus optimization. */ 1148 flag_ipa_icf_variables = 0; 1149 1150 if (flag_pic == 1) 1151 warning (OPT_fpic, "%<-fpic%> is not supported"); 1152 if (flag_pic == 2) 1153 warning (OPT_fPIC, "%<-fPIC%> is not supported"); 1154 if (flag_pie == 1) 1155 warning (OPT_fpie, "%<-fpie%> is not supported"); 1156 if (flag_pie == 2) 1157 warning (OPT_fPIE, "%<-fPIE%> is not supported"); 1158 1159 #if !defined (HAVE_AS_AVR_MGCCISR_OPTION) 1160 avr_gasisr_prologues = 0; 1161 #endif 1162 1163 if (!avr_set_core_architecture()) 1164 return; 1165 1166 /* Sould be set by avr-common.cc */ 1167 gcc_assert (avr_long_double >= avr_double && avr_double >= 32); 1168 1169 /* RAM addresses of some SFRs common to all devices in respective arch. */ 1170 1171 /* SREG: Status Register containing flags like I (global IRQ) */ 1172 avr_addr.sreg = 0x3F + avr_arch->sfr_offset; 1173 1174 /* RAMPZ: Address' high part when loading via ELPM */ 1175 avr_addr.rampz = 0x3B + avr_arch->sfr_offset; 1176 1177 avr_addr.rampy = 0x3A + avr_arch->sfr_offset; 1178 avr_addr.rampx = 0x39 + avr_arch->sfr_offset; 1179 avr_addr.rampd = 0x38 + avr_arch->sfr_offset; 1180 avr_addr.ccp = (AVR_TINY ? 0x3C : 0x34) + avr_arch->sfr_offset; 1181 1182 /* SP: Stack Pointer (SP_H:SP_L) */ 1183 avr_addr.sp_l = 0x3D + avr_arch->sfr_offset; 1184 avr_addr.sp_h = avr_addr.sp_l + 1; 1185 1186 init_machine_status = avr_init_machine_status; 1187 1188 avr_log_set_avr_log(); 1189 } 1190 1191 /* Function to set up the backend function structure. */ 1192 1193 static struct machine_function * 1194 avr_init_machine_status (void) 1195 { 1196 return ggc_cleared_alloc<machine_function> (); 1197 } 1198 1199 1200 /* Implement `INIT_EXPANDERS'. */ 1201 /* The function works like a singleton. */ 1202 1203 void 1204 avr_init_expanders (void) 1205 { 1206 for (int regno = REG_0; regno < REG_32; regno ++) 1207 all_regs_rtx[regno] = gen_rtx_REG (QImode, regno); 1208 1209 lpm_reg_rtx = all_regs_rtx[LPM_REGNO]; 1210 tmp_reg_rtx = all_regs_rtx[AVR_TMP_REGNO]; 1211 zero_reg_rtx = all_regs_rtx[AVR_ZERO_REGNO]; 1212 1213 cc_reg_rtx = gen_rtx_REG (CCmode, REG_CC); 1214 1215 lpm_addr_reg_rtx = gen_rtx_REG (HImode, REG_Z); 1216 1217 sreg_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.sreg)); 1218 rampd_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampd)); 1219 rampx_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampx)); 1220 rampy_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampy)); 1221 rampz_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampz)); 1222 1223 xstring_empty = gen_rtx_CONST_STRING (VOIDmode, ""); 1224 xstring_e = gen_rtx_CONST_STRING (VOIDmode, "e"); 1225 1226 /* TINY core does not have regs r10-r16, but avr-dimode.md expects them 1227 to be present */ 1228 if (AVR_TINY) 1229 avr_have_dimode = false; 1230 } 1231 1232 1233 /* Implement `REGNO_REG_CLASS'. */ 1234 /* Return register class for register R. */ 1235 1236 enum reg_class 1237 avr_regno_reg_class (int r) 1238 { 1239 static const enum reg_class reg_class_tab[] = 1240 { 1241 R0_REG, 1242 /* r1 - r15 */ 1243 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, 1244 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, 1245 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, 1246 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, 1247 /* r16 - r23 */ 1248 SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, 1249 SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, 1250 /* r24, r25 */ 1251 ADDW_REGS, ADDW_REGS, 1252 /* X: r26, 27 */ 1253 POINTER_X_REGS, POINTER_X_REGS, 1254 /* Y: r28, r29 */ 1255 POINTER_Y_REGS, POINTER_Y_REGS, 1256 /* Z: r30, r31 */ 1257 POINTER_Z_REGS, POINTER_Z_REGS, 1258 /* SP: SPL, SPH */ 1259 STACK_REG, STACK_REG 1260 }; 1261 1262 if (r <= 33) 1263 return reg_class_tab[r]; 1264 1265 if (r == REG_CC) 1266 return CC_REG; 1267 1268 return ALL_REGS; 1269 } 1270 1271 1272 /* Implement `TARGET_SCALAR_MODE_SUPPORTED_P'. */ 1273 1274 static bool 1275 avr_scalar_mode_supported_p (scalar_mode mode) 1276 { 1277 if (ALL_FIXED_POINT_MODE_P (mode)) 1278 return true; 1279 1280 if (PSImode == mode) 1281 return true; 1282 1283 return default_scalar_mode_supported_p (mode); 1284 } 1285 1286 1287 /* Return TRUE if DECL is a VAR_DECL located in flash and FALSE, otherwise. */ 1288 1289 static bool 1290 avr_decl_flash_p (tree decl) 1291 { 1292 if (TREE_CODE (decl) != VAR_DECL 1293 || TREE_TYPE (decl) == error_mark_node) 1294 { 1295 return false; 1296 } 1297 1298 return !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (decl))); 1299 } 1300 1301 1302 /* Return TRUE if DECL is a VAR_DECL located in the 24-bit flash 1303 address space and FALSE, otherwise. */ 1304 1305 static bool 1306 avr_decl_memx_p (tree decl) 1307 { 1308 if (TREE_CODE (decl) != VAR_DECL 1309 || TREE_TYPE (decl) == error_mark_node) 1310 { 1311 return false; 1312 } 1313 1314 return (ADDR_SPACE_MEMX == TYPE_ADDR_SPACE (TREE_TYPE (decl))); 1315 } 1316 1317 1318 /* Return TRUE if X is a MEM rtx located in flash and FALSE, otherwise. */ 1319 1320 bool 1321 avr_mem_flash_p (rtx x) 1322 { 1323 return (MEM_P (x) 1324 && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x))); 1325 } 1326 1327 1328 /* Return TRUE if X is a MEM rtx located in the 24-bit flash 1329 address space and FALSE, otherwise. */ 1330 1331 bool 1332 avr_mem_memx_p (rtx x) 1333 { 1334 return (MEM_P (x) 1335 && ADDR_SPACE_MEMX == MEM_ADDR_SPACE (x)); 1336 } 1337 1338 1339 /* A helper for the subsequent function attribute used to dig for 1340 attribute 'name' in a FUNCTION_DECL or FUNCTION_TYPE */ 1341 1342 static inline bool 1343 avr_lookup_function_attribute1 (const_tree func, const char *name) 1344 { 1345 if (FUNCTION_DECL == TREE_CODE (func)) 1346 { 1347 if (NULL_TREE != lookup_attribute (name, DECL_ATTRIBUTES (func))) 1348 { 1349 return true; 1350 } 1351 1352 func = TREE_TYPE (func); 1353 } 1354 1355 gcc_assert (FUNC_OR_METHOD_TYPE_P (func)); 1356 1357 return NULL_TREE != lookup_attribute (name, TYPE_ATTRIBUTES (func)); 1358 } 1359 1360 /* Return nonzero if FUNC is a naked function. */ 1361 1362 static bool 1363 avr_naked_function_p (tree func) 1364 { 1365 return avr_lookup_function_attribute1 (func, "naked"); 1366 } 1367 1368 /* Return nonzero if FUNC is an interrupt function as specified 1369 by the "interrupt" attribute. */ 1370 1371 static bool 1372 avr_interrupt_function_p (tree func) 1373 { 1374 return avr_lookup_function_attribute1 (func, "interrupt"); 1375 } 1376 1377 /* Return nonzero if FUNC is a signal function as specified 1378 by the "signal" attribute. */ 1379 1380 static bool 1381 avr_signal_function_p (tree func) 1382 { 1383 return avr_lookup_function_attribute1 (func, "signal"); 1384 } 1385 1386 /* Return nonzero if FUNC is an OS_task function. */ 1387 1388 static bool 1389 avr_OS_task_function_p (tree func) 1390 { 1391 return avr_lookup_function_attribute1 (func, "OS_task"); 1392 } 1393 1394 /* Return nonzero if FUNC is an OS_main function. */ 1395 1396 static bool 1397 avr_OS_main_function_p (tree func) 1398 { 1399 return avr_lookup_function_attribute1 (func, "OS_main"); 1400 } 1401 1402 1403 /* Return nonzero if FUNC is a no_gccisr function as specified 1404 by the "no_gccisr" attribute. */ 1405 1406 static bool 1407 avr_no_gccisr_function_p (tree func) 1408 { 1409 return avr_lookup_function_attribute1 (func, "no_gccisr"); 1410 } 1411 1412 1413 /* Implement `TARGET_CAN_INLINE_P'. */ 1414 /* Some options like -mgas_isr_prologues depend on optimization level, 1415 and the inliner might think that due to different options, inlining 1416 is not permitted; see PR104327. */ 1417 1418 static bool 1419 avr_can_inline_p (tree /* caller */, tree /* callee */) 1420 { 1421 // No restrictions whatsoever. 1422 return true; 1423 } 1424 1425 /* Implement `TARGET_SET_CURRENT_FUNCTION'. */ 1426 /* Sanity cheching for above function attributes. */ 1427 1428 static void 1429 avr_set_current_function (tree decl) 1430 { 1431 if (decl == NULL_TREE 1432 || current_function_decl == NULL_TREE 1433 || current_function_decl == error_mark_node 1434 || ! cfun->machine 1435 || cfun->machine->attributes_checked_p) 1436 return; 1437 1438 location_t loc = DECL_SOURCE_LOCATION (decl); 1439 1440 cfun->machine->is_naked = avr_naked_function_p (decl); 1441 cfun->machine->is_signal = avr_signal_function_p (decl); 1442 cfun->machine->is_interrupt = avr_interrupt_function_p (decl); 1443 cfun->machine->is_OS_task = avr_OS_task_function_p (decl); 1444 cfun->machine->is_OS_main = avr_OS_main_function_p (decl); 1445 cfun->machine->is_no_gccisr = avr_no_gccisr_function_p (decl); 1446 1447 const char *isr = cfun->machine->is_interrupt ? "interrupt" : "signal"; 1448 1449 /* Too much attributes make no sense as they request conflicting features. */ 1450 1451 if (cfun->machine->is_OS_task 1452 && (cfun->machine->is_signal || cfun->machine->is_interrupt)) 1453 error_at (loc, "function attributes %qs and %qs are mutually exclusive", 1454 "OS_task", isr); 1455 1456 if (cfun->machine->is_OS_main 1457 && (cfun->machine->is_signal || cfun->machine->is_interrupt)) 1458 error_at (loc, "function attributes %qs and %qs are mutually exclusive", 1459 "OS_main", isr); 1460 1461 if (cfun->machine->is_interrupt || cfun->machine->is_signal) 1462 { 1463 tree args = TYPE_ARG_TYPES (TREE_TYPE (decl)); 1464 tree ret = TREE_TYPE (TREE_TYPE (decl)); 1465 const char *name; 1466 1467 name = DECL_ASSEMBLER_NAME_SET_P (decl) 1468 ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)) 1469 : IDENTIFIER_POINTER (DECL_NAME (decl)); 1470 1471 /* Skip a leading '*' that might still prefix the assembler name, 1472 e.g. in non-LTO runs. */ 1473 1474 name = default_strip_name_encoding (name); 1475 1476 /* Interrupt handlers must be void __vector (void) functions. */ 1477 1478 if (args && TREE_CODE (TREE_VALUE (args)) != VOID_TYPE) 1479 error_at (loc, "%qs function cannot have arguments", isr); 1480 1481 if (TREE_CODE (ret) != VOID_TYPE) 1482 error_at (loc, "%qs function cannot return a value", isr); 1483 1484 #if defined WITH_AVRLIBC 1485 /* Silently ignore 'signal' if 'interrupt' is present. AVR-LibC startet 1486 using this when it switched from SIGNAL and INTERRUPT to ISR. */ 1487 1488 if (cfun->machine->is_interrupt) 1489 cfun->machine->is_signal = 0; 1490 1491 /* If the function has the 'signal' or 'interrupt' attribute, ensure 1492 that the name of the function is "__vector_NN" so as to catch 1493 when the user misspells the vector name. */ 1494 1495 if (!startswith (name, "__vector")) 1496 warning_at (loc, OPT_Wmisspelled_isr, "%qs appears to be a misspelled " 1497 "%qs handler, missing %<__vector%> prefix", name, isr); 1498 #endif // AVR-LibC naming conventions 1499 } 1500 1501 #if defined WITH_AVRLIBC 1502 // Common problem is using "ISR" without first including avr/interrupt.h. 1503 const char *name = IDENTIFIER_POINTER (DECL_NAME (decl)); 1504 name = default_strip_name_encoding (name); 1505 if (strcmp ("ISR", name) == 0) 1506 { 1507 warning_at (loc, OPT_Wmisspelled_isr, "%qs is a reserved identifier" 1508 " in AVR-LibC. Consider %<#include <avr/interrupt.h>%>" 1509 " before using the %qs macro", name, name); 1510 } 1511 if (strcmp ("INTERRUPT", name) == 0 1512 || strcmp ("SIGNAL", name) == 0) 1513 { 1514 warning_at (loc, OPT_Wmisspelled_isr, "%qs is a deprecated identifier" 1515 " in AVR-LibC. Consider %<#include <avr/interrupt.h>%>" 1516 " or %<#include <compat/deprecated.h>%>" 1517 " before using the %qs macro", name, name); 1518 } 1519 #endif // AVR-LibC naming conventions 1520 1521 /* Don't print the above diagnostics more than once. */ 1522 1523 cfun->machine->attributes_checked_p = 1; 1524 } 1525 1526 1527 /* Implement `ACCUMULATE_OUTGOING_ARGS'. */ 1528 1529 int 1530 avr_accumulate_outgoing_args (void) 1531 { 1532 if (!cfun) 1533 return TARGET_ACCUMULATE_OUTGOING_ARGS; 1534 1535 /* FIXME: For setjmp and in avr_builtin_setjmp_frame_value we don't know 1536 what offset is correct. In some cases it is relative to 1537 virtual_outgoing_args_rtx and in others it is relative to 1538 virtual_stack_vars_rtx. For example code see 1539 gcc.c-torture/execute/built-in-setjmp.c 1540 gcc.c-torture/execute/builtins/sprintf-chk.c */ 1541 1542 return (TARGET_ACCUMULATE_OUTGOING_ARGS 1543 && !(cfun->calls_setjmp 1544 || cfun->has_nonlocal_label)); 1545 } 1546 1547 1548 /* Report contribution of accumulated outgoing arguments to stack size. */ 1549 1550 static inline int 1551 avr_outgoing_args_size (void) 1552 { 1553 return (ACCUMULATE_OUTGOING_ARGS 1554 ? (HOST_WIDE_INT) crtl->outgoing_args_size : 0); 1555 } 1556 1557 1558 /* Implement `TARGET_STARTING_FRAME_OFFSET'. */ 1559 /* This is the offset from the frame pointer register to the first stack slot 1560 that contains a variable living in the frame. */ 1561 1562 static HOST_WIDE_INT 1563 avr_starting_frame_offset (void) 1564 { 1565 return 1 + avr_outgoing_args_size (); 1566 } 1567 1568 1569 /* Return the number of hard registers to push/pop in the prologue/epilogue 1570 of the current function, and optionally store these registers in SET. */ 1571 1572 static int 1573 avr_regs_to_save (HARD_REG_SET *set) 1574 { 1575 int count = 0; 1576 int int_or_sig_p = cfun->machine->is_interrupt || cfun->machine->is_signal; 1577 1578 if (set) 1579 CLEAR_HARD_REG_SET (*set); 1580 1581 /* No need to save any registers if the function never returns or 1582 has the "OS_task" or "OS_main" attribute. */ 1583 1584 if (TREE_THIS_VOLATILE (current_function_decl) 1585 || cfun->machine->is_OS_task 1586 || cfun->machine->is_OS_main) 1587 return 0; 1588 1589 for (int reg = REG_0; reg < REG_32; reg++) 1590 { 1591 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as 1592 any global register variables. */ 1593 1594 if (fixed_regs[reg]) 1595 continue; 1596 1597 if ((int_or_sig_p && !crtl->is_leaf && call_used_or_fixed_reg_p (reg)) 1598 || (df_regs_ever_live_p (reg) 1599 && (int_or_sig_p || !call_used_or_fixed_reg_p (reg)) 1600 /* Don't record frame pointer registers here. They are treated 1601 indivitually in prologue. */ 1602 && !(frame_pointer_needed 1603 && (reg == REG_Y || reg == REG_Y + 1)))) 1604 { 1605 if (set) 1606 SET_HARD_REG_BIT (*set, reg); 1607 count++; 1608 } 1609 } 1610 return count; 1611 } 1612 1613 1614 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */ 1615 1616 static bool 1617 avr_allocate_stack_slots_for_args (void) 1618 { 1619 return !cfun->machine->is_naked; 1620 } 1621 1622 1623 /* Implement `TARGET_CAN_ELIMINATE'. */ 1624 /* Return true if register FROM can be eliminated via register TO. */ 1625 1626 static bool 1627 avr_can_eliminate (const int /*from*/, const int to) 1628 { 1629 return ((frame_pointer_needed && to == FRAME_POINTER_REGNUM) 1630 || !frame_pointer_needed); 1631 } 1632 1633 1634 /* Implement `TARGET_WARN_FUNC_RETURN'. */ 1635 1636 static bool 1637 avr_warn_func_return (tree decl) 1638 { 1639 /* Naked functions are implemented entirely in assembly, including the 1640 return sequence, so suppress warnings about this. */ 1641 1642 return !avr_naked_function_p (decl); 1643 } 1644 1645 1646 /* Worker function for `INITIAL_ELIMINATION_OFFSET'. */ 1647 /* Compute offset between arg_pointer and frame_pointer. */ 1648 1649 int 1650 avr_initial_elimination_offset (int from, int to) 1651 { 1652 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM) 1653 return 0; 1654 else 1655 { 1656 int offset = frame_pointer_needed ? 2 : 0; 1657 int avr_pc_size = AVR_HAVE_EIJMP_EICALL ? 3 : 2; 1658 1659 // If FROM is ARG_POINTER_REGNUM, we are not in an ISR as ISRs 1660 // might not have arguments. Hence the following is not affected 1661 // by gasisr prologues. 1662 offset += avr_regs_to_save (NULL); 1663 return (get_frame_size () + avr_outgoing_args_size() 1664 + avr_pc_size + 1 + offset); 1665 } 1666 } 1667 1668 1669 /* Helper for the function below. */ 1670 1671 static void 1672 avr_adjust_type_node (tree *node, machine_mode mode, int sat_p) 1673 { 1674 *node = make_node (FIXED_POINT_TYPE); 1675 TYPE_SATURATING (*node) = sat_p; 1676 TYPE_UNSIGNED (*node) = UNSIGNED_FIXED_POINT_MODE_P (mode); 1677 TYPE_IBIT (*node) = GET_MODE_IBIT (mode); 1678 TYPE_FBIT (*node) = GET_MODE_FBIT (mode); 1679 TYPE_PRECISION (*node) = GET_MODE_BITSIZE (mode); 1680 SET_TYPE_ALIGN (*node, 8); 1681 SET_TYPE_MODE (*node, mode); 1682 1683 layout_type (*node); 1684 } 1685 1686 1687 /* Implement `TARGET_BUILD_BUILTIN_VA_LIST'. */ 1688 1689 static tree 1690 avr_build_builtin_va_list (void) 1691 { 1692 /* avr-modes.def adjusts [U]TA to be 64-bit modes with 48 fractional bits. 1693 This is more appropriate for the 8-bit machine AVR than 128-bit modes. 1694 The ADJUST_IBIT/FBIT are handled in toplev:init_adjust_machine_modes() 1695 which is auto-generated by genmodes, but the compiler assigns [U]DAmode 1696 to the long long accum modes instead of the desired [U]TAmode. 1697 1698 Fix this now, right after node setup in tree.cc:build_common_tree_nodes(). 1699 This must run before c-cppbuiltin.cc:builtin_define_fixed_point_constants() 1700 which built-in defines macros like __ULLACCUM_FBIT__ that are used by 1701 libgcc to detect IBIT and FBIT. */ 1702 1703 avr_adjust_type_node (&ta_type_node, TAmode, 0); 1704 avr_adjust_type_node (&uta_type_node, UTAmode, 0); 1705 avr_adjust_type_node (&sat_ta_type_node, TAmode, 1); 1706 avr_adjust_type_node (&sat_uta_type_node, UTAmode, 1); 1707 1708 unsigned_long_long_accum_type_node = uta_type_node; 1709 long_long_accum_type_node = ta_type_node; 1710 sat_unsigned_long_long_accum_type_node = sat_uta_type_node; 1711 sat_long_long_accum_type_node = sat_ta_type_node; 1712 1713 /* Dispatch to the default handler. */ 1714 1715 return std_build_builtin_va_list (); 1716 } 1717 1718 1719 /* Worker function for `INCOMING_RETURN_ADDR_RTX'. */ 1720 /* Return contents of MEM at frame pointer + stack size + 1 (+2 if 3-byte PC). 1721 This is return address of function. */ 1722 1723 rtx 1724 avr_return_addr_rtx (int count, rtx tem) 1725 { 1726 rtx r; 1727 1728 /* Can only return this function's return address. Others not supported. */ 1729 if (count) 1730 return NULL; 1731 1732 if (AVR_3_BYTE_PC) 1733 { 1734 r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+2"); 1735 warning (0, "%<builtin_return_address%> contains only 2 bytes" 1736 " of address"); 1737 } 1738 else 1739 r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+1"); 1740 1741 cfun->machine->use_L__stack_usage = 1; 1742 1743 r = gen_rtx_PLUS (Pmode, tem, r); 1744 r = gen_frame_mem (Pmode, memory_address (Pmode, r)); 1745 r = gen_rtx_ROTATE (HImode, r, GEN_INT (8)); 1746 return r; 1747 } 1748 1749 /* Return 1 if the function epilogue is just a single "ret". */ 1750 1751 int 1752 avr_simple_epilogue (void) 1753 { 1754 return (! frame_pointer_needed 1755 && get_frame_size () == 0 1756 && avr_outgoing_args_size() == 0 1757 && avr_regs_to_save (NULL) == 0 1758 && ! cfun->machine->is_interrupt 1759 && ! cfun->machine->is_signal 1760 && ! cfun->machine->is_naked 1761 && ! TREE_THIS_VOLATILE (current_function_decl)); 1762 } 1763 1764 /* This function checks sequence of live registers. */ 1765 1766 static int 1767 sequent_regs_live (void) 1768 { 1769 int live_seq = 0; 1770 int cur_seq = 0; 1771 1772 for (int reg = 0; reg <= LAST_CALLEE_SAVED_REG; ++reg) 1773 { 1774 if (fixed_regs[reg]) 1775 { 1776 /* Don't recognize sequences that contain global register 1777 variables. */ 1778 1779 if (live_seq != 0) 1780 return 0; 1781 else 1782 continue; 1783 } 1784 1785 if (!call_used_or_fixed_reg_p (reg)) 1786 { 1787 if (df_regs_ever_live_p (reg)) 1788 { 1789 ++live_seq; 1790 ++cur_seq; 1791 } 1792 else 1793 cur_seq = 0; 1794 } 1795 } 1796 1797 if (!frame_pointer_needed) 1798 { 1799 if (df_regs_ever_live_p (REG_Y)) 1800 { 1801 ++live_seq; 1802 ++cur_seq; 1803 } 1804 else 1805 cur_seq = 0; 1806 1807 if (df_regs_ever_live_p (REG_Y + 1)) 1808 { 1809 ++live_seq; 1810 ++cur_seq; 1811 } 1812 else 1813 cur_seq = 0; 1814 } 1815 else 1816 { 1817 cur_seq += 2; 1818 live_seq += 2; 1819 } 1820 return (cur_seq == live_seq) ? live_seq : 0; 1821 } 1822 1823 1824 namespace { 1825 static const pass_data avr_pass_data_fuse_add = 1826 { 1827 RTL_PASS, // type 1828 "", // name (will be patched) 1829 OPTGROUP_NONE, // optinfo_flags 1830 TV_DF_SCAN, // tv_id 1831 0, // properties_required 1832 0, // properties_provided 1833 0, // properties_destroyed 1834 0, // todo_flags_start 1835 TODO_df_finish // todo_flags_finish 1836 }; 1837 1838 1839 class avr_pass_fuse_add : public rtl_opt_pass 1840 { 1841 public: 1842 avr_pass_fuse_add (gcc::context *ctxt, const char *name) 1843 : rtl_opt_pass (avr_pass_data_fuse_add, ctxt) 1844 { 1845 this->name = name; 1846 } 1847 1848 virtual bool gate (function *) { return optimize && avr_fuse_add > 0; } 1849 1850 virtual unsigned int execute (function *); 1851 1852 struct Some_Insn 1853 { 1854 rtx_insn *insn = nullptr; 1855 rtx dest, src; 1856 bool valid () const { return insn != nullptr; } 1857 void set_deleted () 1858 { 1859 gcc_assert (insn); 1860 SET_INSN_DELETED (insn); 1861 insn = nullptr; 1862 } 1863 }; 1864 1865 // If .insn is not NULL, then this is a reg:HI += const_int 1866 // of an address register. 1867 struct Add_Insn : Some_Insn 1868 { 1869 rtx addend; 1870 int regno; 1871 Add_Insn () {} 1872 Add_Insn (rtx_insn *insn); 1873 }; 1874 1875 // If .insn is not NULL, then this sets an address register 1876 // to a constant value. 1877 struct Ldi_Insn : Some_Insn 1878 { 1879 int regno; 1880 Ldi_Insn () {} 1881 Ldi_Insn (rtx_insn *insn); 1882 }; 1883 1884 // If .insn is not NULL, then this is a load or store insn where the 1885 // address is REG or POST_INC with an address register. 1886 struct Mem_Insn : Some_Insn 1887 { 1888 rtx reg_or_0, mem, addr, addr_reg; 1889 int addr_regno; 1890 enum rtx_code addr_code; 1891 machine_mode mode; 1892 addr_space_t addr_space; 1893 bool store_p, volatile_p; 1894 Mem_Insn () {} 1895 Mem_Insn (rtx_insn *insn); 1896 }; 1897 1898 rtx_insn *fuse_ldi_add (Ldi_Insn &prev_ldi, Add_Insn &add); 1899 rtx_insn *fuse_add_add (Add_Insn &prev_add, Add_Insn &add); 1900 rtx_insn *fuse_add_mem (Add_Insn &prev_add, Mem_Insn &mem); 1901 rtx_insn *fuse_mem_add (Mem_Insn &prev_mem, Add_Insn &add); 1902 }; // avr_pass_fuse_add 1903 1904 } // anon namespace 1905 1906 rtl_opt_pass * 1907 make_avr_pass_fuse_add (gcc::context *ctxt) 1908 { 1909 return new avr_pass_fuse_add (ctxt, "avr-fuse-add"); 1910 } 1911 1912 /* Describe properties of AVR's indirect load and store instructions 1913 LD, LDD, ST, STD, LPM, ELPM depending on register number, volatility etc. 1914 Rules for "volatile" accesses are: 1915 1916 | Xmega | non-Xmega 1917 ------+-----------------+---------------- 1918 load | read LSB first | read LSB first 1919 store | write LSB first | write MSB first 1920 */ 1921 1922 struct AVR_LdSt_Props 1923 { 1924 bool has_postinc, has_predec, has_ldd; 1925 // The insn printers will use POST_INC or PRE_DEC addressing, no matter 1926 // what adressing modes we are feeding into them. 1927 bool want_postinc, want_predec; 1928 1929 AVR_LdSt_Props (int regno, bool store_p, bool volatile_p, addr_space_t as) 1930 { 1931 bool generic_p = ADDR_SPACE_GENERIC_P (as); 1932 bool flashx_p = ! generic_p && as != ADDR_SPACE_MEMX; 1933 has_postinc = generic_p || (flashx_p && regno == REG_Z); 1934 has_predec = generic_p; 1935 has_ldd = ! AVR_TINY && generic_p && (regno == REG_Y || regno == REG_Z); 1936 want_predec = volatile_p && generic_p && ! AVR_XMEGA && store_p; 1937 want_postinc = volatile_p && generic_p && (AVR_XMEGA || ! store_p); 1938 want_postinc |= flashx_p && regno == REG_Z; 1939 } 1940 1941 AVR_LdSt_Props (const avr_pass_fuse_add::Mem_Insn &m) 1942 : AVR_LdSt_Props (m.addr_regno, m.store_p, m.volatile_p, m.addr_space) 1943 { 1944 gcc_assert (m.valid ()); 1945 } 1946 }; 1947 1948 /* Emit a single_set that clobbers REG_CC. */ 1949 1950 static rtx_insn * 1951 emit_move_ccc (rtx dest, rtx src) 1952 { 1953 return emit_insn (gen_gen_move_clobbercc (dest, src)); 1954 } 1955 1956 /* Emit a single_set that clobbers REG_CC after insn AFTER. */ 1957 1958 static rtx_insn * 1959 emit_move_ccc_after (rtx dest, rtx src, rtx_insn *after) 1960 { 1961 return emit_insn_after (gen_gen_move_clobbercc (dest, src), after); 1962 } 1963 1964 static bool 1965 reg_seen_between_p (const_rtx reg, const rtx_insn *from, const rtx_insn *to) 1966 { 1967 return (reg_used_between_p (reg, from, to) 1968 || reg_set_between_p (reg, from, to)); 1969 } 1970 1971 1972 static void 1973 avr_maybe_adjust_cfa (rtx_insn *insn, rtx reg, int addend) 1974 { 1975 if (addend 1976 && frame_pointer_needed 1977 && REGNO (reg) == FRAME_POINTER_REGNUM 1978 && avr_fuse_add == 3) 1979 { 1980 rtx plus = plus_constant (Pmode, reg, addend); 1981 RTX_FRAME_RELATED_P (insn) = 1; 1982 add_reg_note (insn, REG_CFA_ADJUST_CFA, gen_rtx_SET (reg, plus)); 1983 } 1984 } 1985 1986 1987 // If successful, this represents a SET of a pointer register to a constant. 1988 avr_pass_fuse_add::Ldi_Insn::Ldi_Insn (rtx_insn *insn) 1989 { 1990 rtx set = single_set (insn); 1991 if (!set) 1992 return; 1993 1994 src = SET_SRC (set); 1995 dest = SET_DEST (set); 1996 1997 if (REG_P (dest) 1998 && GET_MODE (dest) == Pmode 1999 && IN_RANGE (regno = REGNO (dest), REG_X, REG_Z) 2000 && CONSTANT_P (src)) 2001 { 2002 this->insn = insn; 2003 } 2004 } 2005 2006 // If successful, this represents a PLUS with CONST_INT of a pointer 2007 // register X, Y or Z. Otherwise, the object is not valid(). 2008 avr_pass_fuse_add::Add_Insn::Add_Insn (rtx_insn *insn) 2009 { 2010 rtx set = single_set (insn); 2011 if (!set) 2012 return; 2013 2014 src = SET_SRC (set); 2015 dest = SET_DEST (set); 2016 if (REG_P (dest) 2017 // We are only interested in PLUSes that change address regs. 2018 && GET_MODE (dest) == Pmode 2019 && IN_RANGE (regno = REGNO (dest), REG_X, REG_Z) 2020 && PLUS == GET_CODE (src) 2021 && rtx_equal_p (XEXP (src, 0), dest) 2022 && CONST_INT_P (XEXP (src, 1))) 2023 { 2024 // This is reg:HI += const_int. 2025 addend = XEXP (src, 1); 2026 this->insn = insn; 2027 } 2028 } 2029 2030 // If successful, this represents a load or store insn where the addressing 2031 // mode uses pointer register X, Y or Z. Otherwise, the object is not valid(). 2032 avr_pass_fuse_add::Mem_Insn::Mem_Insn (rtx_insn *insn) 2033 { 2034 rtx set = single_set (insn); 2035 if (!set) 2036 return; 2037 2038 src = SET_SRC (set); 2039 dest = SET_DEST (set); 2040 mode = GET_MODE (dest); 2041 2042 if (MEM_P (dest) 2043 && (REG_P (src) || src == CONST0_RTX (mode))) 2044 { 2045 reg_or_0 = src; 2046 mem = dest; 2047 } 2048 else if (REG_P (dest) && MEM_P (src)) 2049 { 2050 reg_or_0 = dest; 2051 mem = src; 2052 } 2053 else 2054 return; 2055 2056 if (avr_mem_memx_p (mem) 2057 || avr_load_libgcc_p (mem)) 2058 return; 2059 2060 addr = XEXP (mem, 0); 2061 addr_code = GET_CODE (addr); 2062 2063 if (addr_code == REG) 2064 addr_reg = addr; 2065 else if (addr_code == POST_INC || addr_code == PRE_DEC) 2066 addr_reg = XEXP (addr, 0); 2067 else 2068 return; 2069 2070 addr_regno = REGNO (addr_reg); 2071 2072 if (avr_fuse_add == 2 2073 && frame_pointer_needed 2074 && addr_regno == FRAME_POINTER_REGNUM) 2075 MEM_VOLATILE_P (mem) = 0; 2076 2077 if (reg_overlap_mentioned_p (reg_or_0, addr) // Can handle CONSTANT_P. 2078 || addr_regno > REG_Z 2079 || avr_mem_memx_p (mem) 2080 // The following optimizations only handle REG and POST_INC, 2081 // so that's all what we allow here. 2082 || (addr_code != REG && addr_code != POST_INC)) 2083 return; 2084 2085 addr_space = MEM_ADDR_SPACE (mem); 2086 volatile_p = MEM_VOLATILE_P (mem); 2087 store_p = MEM_P (dest); 2088 2089 // Turn this "valid". 2090 this->insn = insn; 2091 } 2092 2093 /* Try to combine a Ldi insn with a PLUS CONST_INT addend to one Ldi insn. 2094 If LDI is valid, then it precedes ADD in the same block. 2095 When a replacement is found, a new insn is emitted and the old insns 2096 are pseudo-deleted. The returned insn is the point where the calling 2097 scanner should continue. When no replacement is found, nullptr is 2098 returned and nothing changed. */ 2099 2100 rtx_insn * 2101 avr_pass_fuse_add::fuse_ldi_add (Ldi_Insn &ldi, Add_Insn &add) 2102 { 2103 if (! ldi.valid () 2104 || reg_seen_between_p (ldi.dest, ldi.insn, add.insn)) 2105 { 2106 // If something is between the Ldi and the current insn, we can 2107 // set the Ldi invalid to speed future scans. 2108 return ldi.insn = nullptr; 2109 } 2110 2111 // Found a Ldi with const and a PLUS insns in the same BB, 2112 // and with no interfering insns between them. 2113 2114 // Emit new Ldi with the sum of the original offsets after the old Ldi. 2115 rtx xval = plus_constant (Pmode, ldi.src, INTVAL (add.addend)); 2116 2117 rtx_insn *insn = emit_move_ccc_after (ldi.dest, xval, ldi.insn); 2118 avr_dump (";; new Ldi[%d] insn %d after %d: R%d = %r\n\n", ldi.regno, 2119 INSN_UID (insn), INSN_UID (ldi.insn), ldi.regno, xval); 2120 2121 rtx_insn *next = NEXT_INSN (add.insn); 2122 ldi.set_deleted (); 2123 add.set_deleted (); 2124 2125 return next; 2126 } 2127 2128 /* Try to combine two PLUS insns with CONST_INT addend to one such insn. 2129 If PREV_ADD is valid, then it precedes ADD in the same basic block. 2130 When a replacement is found, a new insn is emitted and the old insns 2131 are pseudo-deleted. The returned insn is the point where the calling 2132 scanner should continue. When no replacement is found, nullptr is 2133 returned and nothing changed. */ 2134 2135 rtx_insn * 2136 avr_pass_fuse_add::fuse_add_add (Add_Insn &prev_add, Add_Insn &add) 2137 { 2138 if (! prev_add.valid () 2139 || reg_seen_between_p (add.dest, prev_add.insn, add.insn)) 2140 { 2141 // If something is between the previous Add and the current insn, 2142 // we can set the previous Add invalid to speed future scans. 2143 return prev_add.insn = nullptr; 2144 } 2145 2146 // Found two PLUS insns in the same BB, and with no interfering 2147 // insns between them. 2148 rtx plus = plus_constant (Pmode, add.src, INTVAL (prev_add.addend)); 2149 2150 rtx_insn *next; 2151 if (REG_P (plus)) 2152 { 2153 avr_dump (";; Add[%d] from %d annihilates %d\n\n", add.regno, 2154 INSN_UID (prev_add.insn), INSN_UID (add.insn)); 2155 next = NEXT_INSN (add.insn); 2156 } 2157 else 2158 { 2159 // Emit after the current insn, so that it will be picked 2160 // up as next valid Add insn. 2161 next = emit_move_ccc_after (add.dest, plus, add.insn); 2162 avr_dump (";; #1 new Add[%d] insn %d after %d: R%d += %d\n\n", 2163 add.regno, INSN_UID (next), INSN_UID (add.insn), 2164 add.regno, (int) INTVAL (XEXP (plus, 1))); 2165 gcc_assert (GET_CODE (plus) == PLUS); 2166 } 2167 2168 add.set_deleted (); 2169 prev_add.set_deleted (); 2170 2171 return next; 2172 } 2173 2174 /* Try to combine a PLUS of the address register with a load or store insn. 2175 If ADD is valid, then it precedes MEM in the same basic block. 2176 When a replacement is found, a new insn is emitted and the old insns 2177 are pseudo-deleted. The returned insn is the point where the calling 2178 scanner should continue. When no replacement is found, nullptr is 2179 returned and nothing changed. */ 2180 2181 rtx_insn * 2182 avr_pass_fuse_add::fuse_add_mem (Add_Insn &add, Mem_Insn &mem) 2183 { 2184 if (! add.valid () 2185 || reg_seen_between_p (add.dest, add.insn, mem.insn)) 2186 { 2187 // If something is between the Add and the current insn, we can 2188 // set the Add invalid to speed future scans. 2189 return add.insn = nullptr; 2190 } 2191 2192 AVR_LdSt_Props ap { mem }; 2193 2194 int msize = GET_MODE_SIZE (mem.mode); 2195 2196 // The mem insn really wants PRE_DEC. 2197 bool case1 = ((mem.addr_code == REG || mem.addr_code == POST_INC) 2198 && msize > 1 && ap.want_predec && ! ap.has_ldd); 2199 2200 // The offset can be consumed by a PRE_DEC. 2201 bool case2 = (- INTVAL (add.addend) == msize 2202 && (mem.addr_code == REG || mem.addr_code == POST_INC) 2203 && ap.has_predec && ! ap.want_postinc); 2204 2205 if (! case1 && ! case2) 2206 return nullptr; 2207 2208 // Change from REG or POST_INC to PRE_DEC. 2209 rtx xmem = change_address (mem.mem, mem.mode, 2210 gen_rtx_PRE_DEC (Pmode, mem.addr_reg)); 2211 rtx dest = mem.store_p ? xmem : mem.reg_or_0; 2212 rtx src = mem.store_p ? mem.reg_or_0 : xmem; 2213 2214 rtx_insn *next = emit_move_ccc_after (dest, src, mem.insn); 2215 add_reg_note (next, REG_INC, mem.addr_reg); 2216 avr_dump (";; new Mem[%d] insn %d after %d: %r = %r\n\n", mem.addr_regno, 2217 INSN_UID (next), INSN_UID (mem.insn), dest, src); 2218 2219 // Changing REG or POST_INC -> PRE_DEC means that the addend before 2220 // the memory access must be increased by the size of the access, 2221 rtx plus = plus_constant (Pmode, add.src, msize); 2222 if (! REG_P (plus)) 2223 { 2224 rtx_insn *insn = emit_move_ccc_after (add.dest, plus, add.insn); 2225 avr_dump (";; #2 new Add[%d] insn %d after %d: R%d += %d\n\n", 2226 add.regno, INSN_UID (insn), INSN_UID (add.insn), 2227 add.regno, (int) INTVAL (XEXP (plus, 1))); 2228 gcc_assert (GET_CODE (plus) == PLUS); 2229 } 2230 else 2231 avr_dump (";; Add[%d] insn %d consumed into %d\n\n", 2232 add.regno, INSN_UID (add.insn), INSN_UID (next)); 2233 2234 // Changing POST_INC -> PRE_DEC means that the addend after the mem has to be 2235 // the size of the access. The hope is that this new add insn may be unused. 2236 if (mem.addr_code == POST_INC) 2237 { 2238 plus = plus_constant (Pmode, add.dest, msize); 2239 rtx_insn *next2 = emit_move_ccc_after (add.dest, plus, next); 2240 avr_dump (";; #3 new Add[%d] insn %d after %d: R%d += %d\n\n", add.regno, 2241 INSN_UID (next2), INSN_UID (next), add.regno, msize); 2242 next = next2; 2243 } 2244 2245 add.set_deleted (); 2246 mem.set_deleted (); 2247 2248 return next; 2249 } 2250 2251 /* Try to combine a load or store insn with a PLUS of the address register. 2252 If MEM is valid, then it precedes ADD in the same basic block. 2253 When a replacement is found, a new insn is emitted and the old insns 2254 are pseudo-deleted. The returned insn is the point where the calling 2255 scanner should continue. When no replacement is found, nullptr is 2256 returned and nothing changed. */ 2257 2258 rtx_insn * 2259 avr_pass_fuse_add::fuse_mem_add (Mem_Insn &mem, Add_Insn &add) 2260 { 2261 if (! mem.valid () 2262 || reg_seen_between_p (add.dest, mem.insn, add.insn)) 2263 { 2264 // If something is between the Mem and the current insn, we can 2265 // set the Mem invalid to speed future scans. 2266 return mem.insn = nullptr; 2267 } 2268 2269 AVR_LdSt_Props ap { mem }; 2270 2271 int msize = GET_MODE_SIZE (mem.mode); 2272 2273 // The add insn can be consumed by a POST_INC. 2274 bool case1 = (mem.addr_code == REG 2275 && INTVAL (add.addend) == msize 2276 && ap.has_postinc && ! ap.want_predec); 2277 2278 // There are cases where even a partial consumption of the offset is better. 2279 // This are the cases where no LD+offset addressing is available, because 2280 // the address register is obviously used after the mem insn, and a mem insn 2281 // with REG addressing mode will have to restore the address. 2282 bool case2 = (mem.addr_code == REG 2283 && msize > 1 && ap.want_postinc && ! ap.has_ldd); 2284 2285 if (! case1 && ! case2) 2286 return nullptr; 2287 2288 // Change addressing mode from REG to POST_INC. 2289 rtx xmem = change_address (mem.mem, mem.mode, 2290 gen_rtx_POST_INC (Pmode, mem.addr_reg)); 2291 rtx dest = mem.store_p ? xmem : mem.reg_or_0; 2292 rtx src = mem.store_p ? mem.reg_or_0 : xmem; 2293 2294 rtx_insn *insn = emit_move_ccc_after (dest, src, mem.insn); 2295 add_reg_note (insn, REG_INC, mem.addr_reg); 2296 avr_dump (";; new Mem[%d] insn %d after %d: %r = %r\n\n", add.regno, 2297 INSN_UID (insn), INSN_UID (mem.insn), dest, src); 2298 2299 rtx_insn *next = NEXT_INSN (add.insn); 2300 2301 // Changing REG -> POST_INC means that the post addend must be 2302 // decreased by the size of the access. 2303 rtx plus = plus_constant (Pmode, add.src, -msize); 2304 if (! REG_P (plus)) 2305 { 2306 next = emit_move_ccc_after (mem.addr_reg, plus, add.insn); 2307 avr_dump (";; #4 new Add[%d] insn %d after %d: R%d += %d\n\n", 2308 add.regno, INSN_UID (next), INSN_UID (add.insn), 2309 add.regno, (int) INTVAL (XEXP (plus, 1))); 2310 gcc_assert (GET_CODE (plus) == PLUS); 2311 } 2312 else 2313 avr_dump (";; Add[%d] insn %d consumed into %d\n\n", 2314 add.regno, INSN_UID (add.insn), INSN_UID (insn)); 2315 2316 add.set_deleted (); 2317 mem.set_deleted (); 2318 2319 return next; 2320 } 2321 2322 /* Try to post-reload combine PLUS with CONST_INt of pointer registers with: 2323 - Sets to a constant address. 2324 - PLUS insn of that kind. 2325 - Indirect loads and stores. 2326 In almost all cases, combine opportunities arise from the preparation 2327 done by `avr_split_tiny_move', but in some rare cases combinations are 2328 found for the ordinary cores, too. 2329 As we consider at most one Mem insn per try, there may still be missed 2330 optimizations like POST_INC + PLUS + POST_INC might be performed 2331 as PRE_DEC + PRE_DEC for two adjacent locations. */ 2332 2333 unsigned int 2334 avr_pass_fuse_add::execute (function *func) 2335 { 2336 df_note_add_problem (); 2337 df_analyze (); 2338 2339 int n_add = 0, n_mem = 0, n_ldi = 0; 2340 basic_block bb; 2341 2342 FOR_EACH_BB_FN (bb, func) 2343 { 2344 Ldi_Insn prev_ldi_insns[REG_32]; 2345 Add_Insn prev_add_insns[REG_32]; 2346 Mem_Insn prev_mem_insns[REG_32]; 2347 rtx_insn *insn, *curr; 2348 2349 avr_dump ("\n;; basic block %d\n\n", bb->index); 2350 2351 FOR_BB_INSNS_SAFE (bb, insn, curr) 2352 { 2353 rtx_insn *next = nullptr; 2354 Ldi_Insn ldi_insn { insn }; 2355 Add_Insn add_insn { insn }; 2356 Mem_Insn mem_insn { insn }; 2357 2358 if (add_insn.valid ()) 2359 { 2360 // Found reg:HI += const_int 2361 avr_dump (";; insn %d: Add[%d]: R%d += %d\n\n", 2362 INSN_UID (add_insn.insn), add_insn.regno, 2363 add_insn.regno, (int) INTVAL (add_insn.addend)); 2364 Ldi_Insn &prev_ldi_insn = prev_ldi_insns[add_insn.regno]; 2365 Add_Insn &prev_add_insn = prev_add_insns[add_insn.regno]; 2366 Mem_Insn &prev_mem_insn = prev_mem_insns[add_insn.regno]; 2367 if ((next = fuse_ldi_add (prev_ldi_insn, add_insn))) 2368 curr = next, n_ldi += 1; 2369 else if ((next = fuse_add_add (prev_add_insn, add_insn))) 2370 curr = next, n_add += 1; 2371 else if ((next = fuse_mem_add (prev_mem_insn, add_insn))) 2372 curr = next, n_mem += 1; 2373 else 2374 prev_add_insn = add_insn; 2375 } 2376 else if (mem_insn.valid ()) 2377 { 2378 int addr_regno = REGNO (mem_insn.addr_reg); 2379 avr_dump (";; insn %d: Mem[%d]: %r = %r\n\n", 2380 INSN_UID (mem_insn.insn), addr_regno, 2381 mem_insn.dest, mem_insn.src); 2382 Add_Insn &prev_add_insn = prev_add_insns[addr_regno]; 2383 if ((next = fuse_add_mem (prev_add_insn, mem_insn))) 2384 curr = next, n_mem += 1; 2385 else 2386 prev_mem_insns[addr_regno] = mem_insn; 2387 } 2388 else if (ldi_insn.valid ()) 2389 { 2390 if (! CONST_INT_P (ldi_insn.src)) 2391 avr_dump (";; insn %d: Ldi[%d]: R%d = %r\n\n", 2392 INSN_UID (ldi_insn.insn), ldi_insn.regno, 2393 ldi_insn.regno, ldi_insn.src); 2394 prev_ldi_insns[ldi_insn.regno] = ldi_insn; 2395 } 2396 } // for insns 2397 } // for BBs 2398 2399 avr_dump (";; Function %f: Found %d changes: %d ldi, %d add, %d mem.\n", 2400 n_ldi + n_add + n_mem, n_ldi, n_add, n_mem); 2401 2402 return 0; 2403 } 2404 2405 2406 namespace { 2407 static const pass_data avr_pass_data_pre_proep = 2408 { 2409 RTL_PASS, // type 2410 "", // name (will be patched) 2411 OPTGROUP_NONE, // optinfo_flags 2412 TV_DF_SCAN, // tv_id 2413 0, // properties_required 2414 0, // properties_provided 2415 0, // properties_destroyed 2416 0, // todo_flags_start 2417 0 // todo_flags_finish 2418 }; 2419 2420 2421 class avr_pass_pre_proep : public rtl_opt_pass 2422 { 2423 public: 2424 avr_pass_pre_proep (gcc::context *ctxt, const char *name) 2425 : rtl_opt_pass (avr_pass_data_pre_proep, ctxt) 2426 { 2427 this->name = name; 2428 } 2429 2430 void compute_maybe_gasisr (function *); 2431 2432 virtual unsigned int execute (function *fun) 2433 { 2434 if (avr_gasisr_prologues 2435 // Whether this function is an ISR worth scanning at all. 2436 && !fun->machine->is_no_gccisr 2437 && (fun->machine->is_interrupt 2438 || fun->machine->is_signal) 2439 && !cfun->machine->is_naked 2440 // Paranoia: Non-local gotos and labels that might escape. 2441 && !cfun->calls_setjmp 2442 && !cfun->has_nonlocal_label 2443 && !cfun->has_forced_label_in_static) 2444 { 2445 compute_maybe_gasisr (fun); 2446 } 2447 2448 return 0; 2449 } 2450 2451 }; // avr_pass_pre_proep 2452 2453 } // anon namespace 2454 2455 rtl_opt_pass * 2456 make_avr_pass_pre_proep (gcc::context *ctxt) 2457 { 2458 return new avr_pass_pre_proep (ctxt, "avr-pre-proep"); 2459 } 2460 2461 2462 /* Set fun->machine->gasisr.maybe provided we don't find anything that 2463 prohibits GAS generating parts of ISR prologues / epilogues for us. */ 2464 2465 void 2466 avr_pass_pre_proep::compute_maybe_gasisr (function *fun) 2467 { 2468 // Don't use BB iterators so that we see JUMP_TABLE_DATA. 2469 2470 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn)) 2471 { 2472 // Transparent calls always use [R]CALL and are filtered out by GAS. 2473 // ISRs don't use -mcall-prologues, hence what remains to be filtered 2474 // out are open coded (tail) calls. 2475 2476 if (CALL_P (insn)) 2477 return; 2478 2479 // __tablejump2__ clobbers something and is targeted by JMP so 2480 // that GAS won't see its usage. 2481 2482 if (AVR_HAVE_JMP_CALL 2483 && JUMP_TABLE_DATA_P (insn)) 2484 return; 2485 2486 // Non-local gotos not seen in *FUN. 2487 2488 if (JUMP_P (insn) 2489 && find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX)) 2490 return; 2491 } 2492 2493 fun->machine->gasisr.maybe = 1; 2494 } 2495 2496 2497 /* Obtain the length sequence of insns. */ 2498 2499 int 2500 get_sequence_length (rtx_insn *insns) 2501 { 2502 int length = 0; 2503 2504 for (rtx_insn *insn = insns; insn; insn = NEXT_INSN (insn)) 2505 length += get_attr_length (insn); 2506 2507 return length; 2508 } 2509 2510 2511 /* Implement `INCOMING_RETURN_ADDR_RTX'. */ 2512 2513 rtx 2514 avr_incoming_return_addr_rtx (void) 2515 { 2516 /* The return address is at the top of the stack. Note that the push 2517 was via post-decrement, which means the actual address is off by one. */ 2518 return gen_frame_mem (HImode, plus_constant (Pmode, stack_pointer_rtx, 1)); 2519 } 2520 2521 2522 /* Unset a bit in *SET. If successful, return the respective bit number. 2523 Otherwise, return -1 and *SET is unaltered. */ 2524 2525 static int 2526 avr_hregs_split_reg (HARD_REG_SET *set) 2527 { 2528 for (int regno = REG_0; regno < REG_32; regno++) 2529 if (TEST_HARD_REG_BIT (*set, regno)) 2530 { 2531 // Don't remove a register from *SET which might indicate that 2532 // some RAMP* register might need ISR prologue / epilogue treatment. 2533 2534 if (AVR_HAVE_RAMPX 2535 && (REG_X == regno || REG_X + 1 == regno) 2536 && TEST_HARD_REG_BIT (*set, REG_X) 2537 && TEST_HARD_REG_BIT (*set, REG_X + 1)) 2538 continue; 2539 2540 if (AVR_HAVE_RAMPY 2541 && !frame_pointer_needed 2542 && (REG_Y == regno || REG_Y + 1 == regno) 2543 && TEST_HARD_REG_BIT (*set, REG_Y) 2544 && TEST_HARD_REG_BIT (*set, REG_Y + 1)) 2545 continue; 2546 2547 if (AVR_HAVE_RAMPZ 2548 && (REG_Z == regno || REG_Z + 1 == regno) 2549 && TEST_HARD_REG_BIT (*set, REG_Z) 2550 && TEST_HARD_REG_BIT (*set, REG_Z + 1)) 2551 continue; 2552 2553 CLEAR_HARD_REG_BIT (*set, regno); 2554 return regno; 2555 } 2556 2557 return -1; 2558 } 2559 2560 2561 /* Helper for expand_prologue. Emit a push of a byte register. */ 2562 2563 static void 2564 emit_push_byte (unsigned regno, bool frame_related_p) 2565 { 2566 rtx mem, reg; 2567 rtx_insn *insn; 2568 2569 mem = gen_rtx_POST_DEC (HImode, stack_pointer_rtx); 2570 mem = gen_frame_mem (QImode, mem); 2571 reg = gen_rtx_REG (QImode, regno); 2572 2573 insn = emit_insn (gen_rtx_SET (mem, reg)); 2574 if (frame_related_p) 2575 RTX_FRAME_RELATED_P (insn) = 1; 2576 2577 cfun->machine->stack_usage++; 2578 } 2579 2580 2581 /* Helper for expand_prologue. Emit a push of a SFR via register TREG. 2582 SFR is a MEM representing the memory location of the SFR. 2583 If CLR_P then clear the SFR after the push using zero_reg. */ 2584 2585 static void 2586 emit_push_sfr (rtx sfr, bool frame_related_p, bool clr_p, int treg) 2587 { 2588 gcc_assert (MEM_P (sfr)); 2589 2590 /* IN treg, IO(SFR) */ 2591 rtx_insn *insn = emit_move_insn (all_regs_rtx[treg], sfr); 2592 if (frame_related_p) 2593 RTX_FRAME_RELATED_P (insn) = 1; 2594 2595 /* PUSH treg */ 2596 emit_push_byte (treg, frame_related_p); 2597 2598 if (clr_p) 2599 { 2600 /* OUT IO(SFR), __zero_reg__ */ 2601 insn = emit_move_insn (sfr, const0_rtx); 2602 if (frame_related_p) 2603 RTX_FRAME_RELATED_P (insn) = 1; 2604 } 2605 } 2606 2607 static void 2608 avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set) 2609 { 2610 rtx_insn *insn; 2611 bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal; 2612 int live_seq = sequent_regs_live (); 2613 2614 HOST_WIDE_INT size_max 2615 = (HOST_WIDE_INT) GET_MODE_MASK (AVR_HAVE_8BIT_SP ? QImode : Pmode); 2616 2617 bool minimize = (TARGET_CALL_PROLOGUES 2618 && size < size_max 2619 && live_seq 2620 && !isr_p 2621 && !cfun->machine->is_OS_task 2622 && !cfun->machine->is_OS_main 2623 && !AVR_TINY); 2624 2625 if (minimize 2626 && (frame_pointer_needed 2627 || avr_outgoing_args_size() > 8 2628 || (AVR_2_BYTE_PC && live_seq > 6) 2629 || live_seq > 7)) 2630 { 2631 rtx pattern; 2632 int reg, offset; 2633 2634 emit_move_insn (gen_rtx_REG (HImode, REG_X), 2635 gen_int_mode (size, HImode)); 2636 2637 pattern = gen_call_prologue_saves (gen_int_mode (live_seq, HImode), 2638 gen_int_mode (live_seq+size, HImode)); 2639 insn = emit_insn (pattern); 2640 RTX_FRAME_RELATED_P (insn) = 1; 2641 2642 /* Describe the effect of the unspec_volatile call to prologue_saves. 2643 Note that this formulation assumes that add_reg_note pushes the 2644 notes to the front. Thus we build them in the reverse order of 2645 how we want dwarf2out to process them. */ 2646 2647 /* The function does always set frame_pointer_rtx, but whether that 2648 is going to be permanent in the function is frame_pointer_needed. */ 2649 2650 add_reg_note (insn, REG_CFA_ADJUST_CFA, 2651 gen_rtx_SET ((frame_pointer_needed 2652 ? frame_pointer_rtx 2653 : stack_pointer_rtx), 2654 plus_constant (Pmode, stack_pointer_rtx, 2655 -(size + live_seq)))); 2656 2657 /* Note that live_seq always contains r28+r29, but the other 2658 registers to be saved are all below 18. */ 2659 2660 int first_reg = (LAST_CALLEE_SAVED_REG + 1) - (live_seq - 2); 2661 2662 for (reg = REG_29, offset = -live_seq + 1; 2663 reg >= first_reg; 2664 reg = (reg == REG_28 ? LAST_CALLEE_SAVED_REG : reg - 1), ++offset) 2665 { 2666 rtx m, r; 2667 2668 m = gen_rtx_MEM (QImode, plus_constant (Pmode, stack_pointer_rtx, 2669 offset)); 2670 r = gen_rtx_REG (QImode, reg); 2671 add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (m, r)); 2672 } 2673 2674 cfun->machine->stack_usage += size + live_seq; 2675 } 2676 else /* !minimize */ 2677 { 2678 for (int reg = REG_0; reg < REG_32; ++reg) 2679 if (TEST_HARD_REG_BIT (set, reg)) 2680 emit_push_byte (reg, true); 2681 2682 if (frame_pointer_needed 2683 && (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))) 2684 { 2685 /* Push frame pointer. Always be consistent about the 2686 ordering of pushes -- epilogue_restores expects the 2687 register pair to be pushed low byte first. */ 2688 2689 emit_push_byte (REG_Y, true); 2690 emit_push_byte (REG_Y + 1, true); 2691 } 2692 2693 if (frame_pointer_needed 2694 && size == 0) 2695 { 2696 insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx); 2697 RTX_FRAME_RELATED_P (insn) = 1; 2698 } 2699 2700 if (size != 0) 2701 { 2702 /* Creating a frame can be done by direct manipulation of the 2703 stack or via the frame pointer. These two methods are: 2704 fp = sp 2705 fp -= size 2706 sp = fp 2707 or 2708 sp -= size 2709 fp = sp (*) 2710 the optimum method depends on function type, stack and 2711 frame size. To avoid a complex logic, both methods are 2712 tested and shortest is selected. 2713 2714 There is also the case where SIZE != 0 and no frame pointer is 2715 needed; this can occur if ACCUMULATE_OUTGOING_ARGS is on. 2716 In that case, insn (*) is not needed in that case. 2717 We use the X register as scratch. This is save because in X 2718 is call-clobbered. 2719 In an interrupt routine, the case of SIZE != 0 together with 2720 !frame_pointer_needed can only occur if the function is not a 2721 leaf function and thus X has already been saved. */ 2722 2723 int irq_state = -1; 2724 HOST_WIDE_INT size_cfa = size, neg_size; 2725 rtx_insn *fp_plus_insns; 2726 2727 gcc_assert (frame_pointer_needed 2728 || !isr_p 2729 || !crtl->is_leaf); 2730 2731 rtx my_fp = (frame_pointer_needed 2732 ? frame_pointer_rtx 2733 : gen_rtx_REG (Pmode, REG_X)); 2734 rtx fp = my_fp; 2735 2736 if (AVR_HAVE_8BIT_SP) 2737 { 2738 /* The high byte (r29) does not change: 2739 Prefer SUBI (1 cycle) over SBIW (2 cycles, same size). */ 2740 2741 my_fp = all_regs_rtx[FRAME_POINTER_REGNUM]; 2742 } 2743 2744 /* Cut down size and avoid size = 0 so that we don't run 2745 into ICE like PR52488 in the remainder. */ 2746 2747 if (size > size_max) 2748 { 2749 /* Don't error so that insane code from newlib still compiles 2750 and does not break building newlib. As PR51345 is implemented 2751 now, there are multilib variants with -msp8. 2752 2753 If user wants sanity checks he can use -Wstack-usage= 2754 or similar options. 2755 2756 For CFA we emit the original, non-saturated size so that 2757 the generic machinery is aware of the real stack usage and 2758 will print the above diagnostic as expected. */ 2759 2760 size = size_max; 2761 } 2762 2763 size = trunc_int_for_mode (size, GET_MODE (my_fp)); 2764 neg_size = trunc_int_for_mode (-size, GET_MODE (my_fp)); 2765 2766 /************ Method 1: Adjust frame pointer ************/ 2767 2768 start_sequence (); 2769 2770 /* Normally, the dwarf2out frame-related-expr interpreter does 2771 not expect to have the CFA change once the frame pointer is 2772 set up. Thus, we avoid marking the move insn below and 2773 instead indicate that the entire operation is complete after 2774 the frame pointer subtraction is done. */ 2775 2776 insn = emit_move_insn (fp, stack_pointer_rtx); 2777 if (frame_pointer_needed) 2778 { 2779 RTX_FRAME_RELATED_P (insn) = 1; 2780 add_reg_note (insn, REG_CFA_ADJUST_CFA, 2781 gen_rtx_SET (fp, stack_pointer_rtx)); 2782 } 2783 2784 insn = emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp), 2785 my_fp, neg_size)); 2786 2787 if (frame_pointer_needed) 2788 { 2789 RTX_FRAME_RELATED_P (insn) = 1; 2790 add_reg_note (insn, REG_CFA_ADJUST_CFA, 2791 gen_rtx_SET (fp, plus_constant (Pmode, fp, 2792 -size_cfa))); 2793 } 2794 2795 /* Copy to stack pointer. Note that since we've already 2796 changed the CFA to the frame pointer this operation 2797 need not be annotated if frame pointer is needed. 2798 Always move through unspec, see PR50063. 2799 For meaning of irq_state see movhi_sp_r insn. */ 2800 2801 if (cfun->machine->is_interrupt) 2802 irq_state = 1; 2803 2804 if (TARGET_NO_INTERRUPTS 2805 || cfun->machine->is_signal 2806 || cfun->machine->is_OS_main) 2807 irq_state = 0; 2808 2809 if (AVR_HAVE_8BIT_SP) 2810 irq_state = 2; 2811 2812 insn = emit_insn (gen_movhi_sp_r (stack_pointer_rtx, 2813 fp, GEN_INT (irq_state))); 2814 if (!frame_pointer_needed) 2815 { 2816 RTX_FRAME_RELATED_P (insn) = 1; 2817 add_reg_note (insn, REG_CFA_ADJUST_CFA, 2818 gen_rtx_SET (stack_pointer_rtx, 2819 plus_constant (Pmode, 2820 stack_pointer_rtx, 2821 -size_cfa))); 2822 } 2823 2824 fp_plus_insns = get_insns (); 2825 end_sequence (); 2826 2827 /************ Method 2: Adjust Stack pointer ************/ 2828 2829 /* Stack adjustment by means of RCALL . and/or PUSH __TMP_REG__ 2830 can only handle specific offsets. */ 2831 2832 int n_rcall = size / (AVR_3_BYTE_PC ? 3 : 2); 2833 2834 if (avr_sp_immediate_operand (gen_int_mode (-size, HImode), HImode) 2835 // Don't use more than 3 RCALLs. 2836 && n_rcall <= 3) 2837 { 2838 rtx_insn *sp_plus_insns; 2839 2840 start_sequence (); 2841 2842 insn = emit_move_insn (stack_pointer_rtx, 2843 plus_constant (Pmode, stack_pointer_rtx, 2844 -size)); 2845 RTX_FRAME_RELATED_P (insn) = 1; 2846 add_reg_note (insn, REG_CFA_ADJUST_CFA, 2847 gen_rtx_SET (stack_pointer_rtx, 2848 plus_constant (Pmode, 2849 stack_pointer_rtx, 2850 -size_cfa))); 2851 if (frame_pointer_needed) 2852 { 2853 insn = emit_move_insn (fp, stack_pointer_rtx); 2854 RTX_FRAME_RELATED_P (insn) = 1; 2855 } 2856 2857 sp_plus_insns = get_insns (); 2858 end_sequence (); 2859 2860 /************ Use shortest method ************/ 2861 2862 emit_insn (get_sequence_length (sp_plus_insns) 2863 < get_sequence_length (fp_plus_insns) 2864 ? sp_plus_insns 2865 : fp_plus_insns); 2866 } 2867 else 2868 { 2869 emit_insn (fp_plus_insns); 2870 } 2871 2872 cfun->machine->stack_usage += size_cfa; 2873 } /* !minimize && size != 0 */ 2874 } /* !minimize */ 2875 } 2876 2877 2878 /* Output function prologue. */ 2879 2880 void 2881 avr_expand_prologue (void) 2882 { 2883 HARD_REG_SET set; 2884 HOST_WIDE_INT size = get_frame_size() + avr_outgoing_args_size(); 2885 2886 cfun->machine->stack_usage = 0; 2887 2888 /* Prologue: naked. */ 2889 if (cfun->machine->is_naked) 2890 { 2891 return; 2892 } 2893 2894 avr_regs_to_save (&set); 2895 2896 if (cfun->machine->is_interrupt || cfun->machine->is_signal) 2897 { 2898 int treg = AVR_TMP_REGNO; 2899 /* Enable interrupts. */ 2900 if (cfun->machine->is_interrupt) 2901 emit_insn (gen_enable_interrupt ()); 2902 2903 if (cfun->machine->gasisr.maybe) 2904 { 2905 /* Let GAS PR21472 emit prologue preamble for us which handles SREG, 2906 ZERO_REG and TMP_REG and one additional, optional register for 2907 us in an optimal way. This even scans through inline asm. */ 2908 2909 cfun->machine->gasisr.yes = 1; 2910 2911 // The optional reg or TMP_REG if we don't need one. If we need one, 2912 // remove that reg from SET so that it's not puhed / popped twice. 2913 // We also use it below instead of TMP_REG in some places. 2914 2915 treg = avr_hregs_split_reg (&set); 2916 if (treg < 0) 2917 treg = AVR_TMP_REGNO; 2918 cfun->machine->gasisr.regno = treg; 2919 2920 // The worst case of pushes. The exact number can be inferred 2921 // at assembly time by magic expression __gcc_isr.n_pushed. 2922 cfun->machine->stack_usage += 3 + (treg != AVR_TMP_REGNO); 2923 2924 // Emit a Prologue chunk. Epilogue chunk(s) might follow. 2925 // The final Done chunk is emit by final postscan. 2926 emit_insn (gen_gasisr (GEN_INT (GASISR_Prologue), GEN_INT (treg))); 2927 } 2928 else // !TARGET_GASISR_PROLOGUES: Classic, dumb prologue preamble. 2929 { 2930 /* Push zero reg. */ 2931 emit_push_byte (AVR_ZERO_REGNO, true); 2932 2933 /* Push tmp reg. */ 2934 emit_push_byte (AVR_TMP_REGNO, true); 2935 2936 /* Push SREG. */ 2937 /* ??? There's no dwarf2 column reserved for SREG. */ 2938 emit_push_sfr (sreg_rtx, false, false /* clr */, AVR_TMP_REGNO); 2939 2940 /* Clear zero reg. */ 2941 emit_move_insn (zero_reg_rtx, const0_rtx); 2942 2943 /* Prevent any attempt to delete the setting of ZERO_REG! */ 2944 emit_use (zero_reg_rtx); 2945 } 2946 2947 /* Push and clear RAMPD/X/Y/Z if present and low-part register is used. 2948 ??? There are no dwarf2 columns reserved for RAMPD/X/Y/Z. */ 2949 2950 if (AVR_HAVE_RAMPD) 2951 emit_push_sfr (rampd_rtx, false /* frame */, true /* clr */, treg); 2952 2953 if (AVR_HAVE_RAMPX 2954 && TEST_HARD_REG_BIT (set, REG_X) 2955 && TEST_HARD_REG_BIT (set, REG_X + 1)) 2956 { 2957 emit_push_sfr (rampx_rtx, false /* frame */, true /* clr */, treg); 2958 } 2959 2960 if (AVR_HAVE_RAMPY 2961 && (frame_pointer_needed 2962 || (TEST_HARD_REG_BIT (set, REG_Y) 2963 && TEST_HARD_REG_BIT (set, REG_Y + 1)))) 2964 { 2965 emit_push_sfr (rampy_rtx, false /* frame */, true /* clr */, treg); 2966 } 2967 2968 if (AVR_HAVE_RAMPZ 2969 && TEST_HARD_REG_BIT (set, REG_Z) 2970 && TEST_HARD_REG_BIT (set, REG_Z + 1)) 2971 { 2972 emit_push_sfr (rampz_rtx, false /* frame */, AVR_HAVE_RAMPD, treg); 2973 } 2974 } /* is_interrupt is_signal */ 2975 2976 avr_prologue_setup_frame (size, set); 2977 2978 if (flag_stack_usage_info) 2979 current_function_static_stack_size 2980 = cfun->machine->stack_usage + INCOMING_FRAME_SP_OFFSET; 2981 } 2982 2983 2984 /* Implement `TARGET_ASM_FUNCTION_END_PROLOGUE'. */ 2985 /* Output summary at end of function prologue. */ 2986 2987 static void 2988 avr_asm_function_end_prologue (FILE *file) 2989 { 2990 if (cfun->machine->is_naked) 2991 { 2992 fputs ("/* prologue: naked */\n", file); 2993 } 2994 else 2995 { 2996 if (cfun->machine->is_interrupt) 2997 { 2998 fputs ("/* prologue: Interrupt */\n", file); 2999 } 3000 else if (cfun->machine->is_signal) 3001 { 3002 fputs ("/* prologue: Signal */\n", file); 3003 } 3004 else 3005 fputs ("/* prologue: function */\n", file); 3006 } 3007 3008 if (ACCUMULATE_OUTGOING_ARGS) 3009 fprintf (file, "/* outgoing args size = %d */\n", 3010 avr_outgoing_args_size()); 3011 3012 fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n", 3013 (HOST_WIDE_INT) get_frame_size()); 3014 3015 if (!cfun->machine->gasisr.yes) 3016 { 3017 fprintf (file, "/* stack size = %d */\n", cfun->machine->stack_usage); 3018 // Create symbol stack offset so all functions have it. Add 1 to stack 3019 // usage for offset so that SP + .L__stack_offset = return address. 3020 fprintf (file, ".L__stack_usage = %d\n", cfun->machine->stack_usage); 3021 } 3022 else 3023 { 3024 int used_by_gasisr = 3 + (cfun->machine->gasisr.regno != AVR_TMP_REGNO); 3025 int to = cfun->machine->stack_usage; 3026 int from = to - used_by_gasisr; 3027 // Number of pushed regs is only known at assembly-time. 3028 fprintf (file, "/* stack size = %d...%d */\n", from , to); 3029 fprintf (file, ".L__stack_usage = %d + __gcc_isr.n_pushed\n", from); 3030 } 3031 } 3032 3033 3034 /* Worker function for `EPILOGUE_USES'. */ 3035 3036 int 3037 avr_epilogue_uses (int /*regno*/) 3038 { 3039 if (reload_completed 3040 && cfun->machine 3041 && (cfun->machine->is_interrupt || cfun->machine->is_signal)) 3042 return 1; 3043 return 0; 3044 } 3045 3046 /* Helper for avr_expand_epilogue. Emit a pop of a byte register. */ 3047 3048 static void 3049 emit_pop_byte (unsigned regno) 3050 { 3051 rtx mem = gen_rtx_PRE_INC (HImode, stack_pointer_rtx); 3052 mem = gen_frame_mem (QImode, mem); 3053 rtx reg = gen_rtx_REG (QImode, regno); 3054 3055 emit_insn (gen_rtx_SET (reg, mem)); 3056 } 3057 3058 /* Output RTL epilogue. */ 3059 3060 void 3061 avr_expand_epilogue (bool sibcall_p) 3062 { 3063 HARD_REG_SET set; 3064 bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal; 3065 3066 HOST_WIDE_INT size = get_frame_size() + avr_outgoing_args_size(); 3067 3068 /* epilogue: naked */ 3069 if (cfun->machine->is_naked) 3070 { 3071 gcc_assert (!sibcall_p); 3072 3073 emit_jump_insn (gen_return ()); 3074 return; 3075 } 3076 3077 avr_regs_to_save (&set); 3078 int live_seq = sequent_regs_live (); 3079 3080 bool minimize = (TARGET_CALL_PROLOGUES 3081 && live_seq 3082 && !isr_p 3083 && !cfun->machine->is_OS_task 3084 && !cfun->machine->is_OS_main 3085 && !AVR_TINY); 3086 3087 if (minimize 3088 && (live_seq > 4 3089 || frame_pointer_needed 3090 || size)) 3091 { 3092 /* Get rid of frame. */ 3093 3094 if (!frame_pointer_needed) 3095 { 3096 emit_move_insn (frame_pointer_rtx, stack_pointer_rtx); 3097 } 3098 3099 if (size) 3100 { 3101 emit_move_insn (frame_pointer_rtx, 3102 plus_constant (Pmode, frame_pointer_rtx, size)); 3103 } 3104 3105 emit_insn (gen_epilogue_restores (gen_int_mode (live_seq, HImode))); 3106 return; 3107 } 3108 3109 if (size) 3110 { 3111 /* Try two methods to adjust stack and select shortest. */ 3112 3113 int irq_state = -1; 3114 3115 gcc_assert (frame_pointer_needed 3116 || !isr_p 3117 || !crtl->is_leaf); 3118 3119 rtx my_fp = (frame_pointer_needed 3120 ? frame_pointer_rtx 3121 : gen_rtx_REG (Pmode, REG_X)); 3122 rtx fp = my_fp; 3123 3124 if (AVR_HAVE_8BIT_SP) 3125 { 3126 /* The high byte (r29) does not change: 3127 Prefer SUBI (1 cycle) over SBIW (2 cycles). */ 3128 3129 my_fp = all_regs_rtx[FRAME_POINTER_REGNUM]; 3130 } 3131 3132 /* For rationale see comment in prologue generation. */ 3133 3134 HOST_WIDE_INT size_max = (HOST_WIDE_INT) GET_MODE_MASK (GET_MODE (my_fp)); 3135 if (size > size_max) 3136 size = size_max; 3137 size = trunc_int_for_mode (size, GET_MODE (my_fp)); 3138 3139 /********** Method 1: Adjust fp register **********/ 3140 3141 start_sequence (); 3142 3143 if (!frame_pointer_needed) 3144 emit_move_insn (fp, stack_pointer_rtx); 3145 3146 emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp), my_fp, size)); 3147 3148 /* Copy to stack pointer. */ 3149 3150 if (TARGET_NO_INTERRUPTS) 3151 irq_state = 0; 3152 3153 if (AVR_HAVE_8BIT_SP) 3154 irq_state = 2; 3155 3156 emit_insn (gen_movhi_sp_r (stack_pointer_rtx, fp, 3157 GEN_INT (irq_state))); 3158 3159 rtx_insn *fp_plus_insns = get_insns (); 3160 end_sequence (); 3161 3162 /********** Method 2: Adjust Stack pointer **********/ 3163 3164 if (avr_sp_immediate_operand (gen_int_mode (size, HImode), HImode)) 3165 { 3166 start_sequence (); 3167 3168 emit_move_insn (stack_pointer_rtx, 3169 plus_constant (Pmode, stack_pointer_rtx, size)); 3170 3171 rtx_insn *sp_plus_insns = get_insns (); 3172 end_sequence (); 3173 3174 /************ Use shortest method ************/ 3175 3176 emit_insn (get_sequence_length (sp_plus_insns) 3177 < get_sequence_length (fp_plus_insns) 3178 ? sp_plus_insns 3179 : fp_plus_insns); 3180 } 3181 else 3182 emit_insn (fp_plus_insns); 3183 } /* size != 0 */ 3184 3185 if (frame_pointer_needed 3186 && !(cfun->machine->is_OS_task || cfun->machine->is_OS_main)) 3187 { 3188 /* Restore previous frame_pointer. See avr_expand_prologue for 3189 rationale for not using pophi. */ 3190 3191 emit_pop_byte (REG_Y + 1); 3192 emit_pop_byte (REG_Y); 3193 } 3194 3195 /* Restore used registers. */ 3196 3197 int treg = AVR_TMP_REGNO; 3198 3199 if (isr_p 3200 && cfun->machine->gasisr.yes) 3201 { 3202 treg = cfun->machine->gasisr.regno; 3203 CLEAR_HARD_REG_BIT (set, treg); 3204 } 3205 3206 for (int reg = REG_31; reg >= REG_0; --reg) 3207 if (TEST_HARD_REG_BIT (set, reg)) 3208 emit_pop_byte (reg); 3209 3210 if (isr_p) 3211 { 3212 /* Restore RAMPZ/Y/X/D using tmp_reg as scratch. 3213 The conditions to restore them must be tha same as in prologue. */ 3214 3215 if (AVR_HAVE_RAMPZ 3216 && TEST_HARD_REG_BIT (set, REG_Z) 3217 && TEST_HARD_REG_BIT (set, REG_Z + 1)) 3218 { 3219 emit_pop_byte (treg); 3220 emit_move_insn (rampz_rtx, all_regs_rtx[treg]); 3221 } 3222 3223 if (AVR_HAVE_RAMPY 3224 && (frame_pointer_needed 3225 || (TEST_HARD_REG_BIT (set, REG_Y) 3226 && TEST_HARD_REG_BIT (set, REG_Y + 1)))) 3227 { 3228 emit_pop_byte (treg); 3229 emit_move_insn (rampy_rtx, all_regs_rtx[treg]); 3230 } 3231 3232 if (AVR_HAVE_RAMPX 3233 && TEST_HARD_REG_BIT (set, REG_X) 3234 && TEST_HARD_REG_BIT (set, REG_X + 1)) 3235 { 3236 emit_pop_byte (treg); 3237 emit_move_insn (rampx_rtx, all_regs_rtx[treg]); 3238 } 3239 3240 if (AVR_HAVE_RAMPD) 3241 { 3242 emit_pop_byte (treg); 3243 emit_move_insn (rampd_rtx, all_regs_rtx[treg]); 3244 } 3245 3246 if (cfun->machine->gasisr.yes) 3247 { 3248 // Emit an Epilogue chunk. 3249 emit_insn (gen_gasisr (GEN_INT (GASISR_Epilogue), 3250 GEN_INT (cfun->machine->gasisr.regno))); 3251 } 3252 else // !TARGET_GASISR_PROLOGUES 3253 { 3254 /* Restore SREG using tmp_reg as scratch. */ 3255 3256 emit_pop_byte (AVR_TMP_REGNO); 3257 emit_move_insn (sreg_rtx, tmp_reg_rtx); 3258 3259 /* Restore tmp REG. */ 3260 emit_pop_byte (AVR_TMP_REGNO); 3261 3262 /* Restore zero REG. */ 3263 emit_pop_byte (AVR_ZERO_REGNO); 3264 } 3265 } 3266 3267 if (!sibcall_p) 3268 emit_jump_insn (gen_return ()); 3269 } 3270 3271 3272 /* Implement `TARGET_ASM_FUNCTION_BEGIN_EPILOGUE'. */ 3273 3274 static void 3275 avr_asm_function_begin_epilogue (FILE *file) 3276 { 3277 app_disable(); 3278 fprintf (file, "/* epilogue start */\n"); 3279 } 3280 3281 3282 /* Implement `TARGET_CANNOT_MODITY_JUMPS_P'. */ 3283 3284 static bool 3285 avr_cannot_modify_jumps_p (void) 3286 { 3287 /* Naked Functions must not have any instructions after 3288 their epilogue, see PR42240 */ 3289 3290 return (reload_completed 3291 && cfun->machine 3292 && cfun->machine->is_naked); 3293 } 3294 3295 3296 /* Implement `TARGET_MODE_DEPENDENT_ADDRESS_P'. */ 3297 3298 static bool 3299 avr_mode_dependent_address_p (const_rtx /*addr*/, addr_space_t as) 3300 { 3301 /* FIXME: Non-generic addresses are not mode-dependent in themselves. 3302 This hook just serves to hack around PR rtl-optimization/52543 by 3303 claiming that non-generic addresses were mode-dependent so that 3304 lower-subreg.cc will skip these addresses. lower-subreg.cc sets up fake 3305 RTXes to probe SET and MEM costs and assumes that MEM is always in the 3306 generic address space which is not true. */ 3307 3308 return !ADDR_SPACE_GENERIC_P (as); 3309 } 3310 3311 3312 /* Return true if rtx X is a CONST_INT, CONST or SYMBOL_REF 3313 address with the `absdata' variable attribute, i.e. respective 3314 data can be read / written by LDS / STS instruction. 3315 This is used only for AVR_TINY. */ 3316 3317 static bool 3318 avr_address_tiny_absdata_p (rtx x, machine_mode mode) 3319 { 3320 if (CONST == GET_CODE (x)) 3321 x = XEXP (XEXP (x, 0), 0); 3322 3323 if (SYMBOL_REF_P (x)) 3324 return SYMBOL_REF_FLAGS (x) & AVR_SYMBOL_FLAG_TINY_ABSDATA; 3325 3326 if (CONST_INT_P (x) 3327 && IN_RANGE (INTVAL (x), 0, 0xc0 - GET_MODE_SIZE (mode))) 3328 return true; 3329 3330 return false; 3331 } 3332 3333 3334 /* Helper function for `avr_legitimate_address_p'. */ 3335 3336 static inline bool 3337 avr_reg_ok_for_addr_p (rtx reg, addr_space_t as, 3338 RTX_CODE outer_code, bool strict) 3339 { 3340 return (REG_P (reg) 3341 && (avr_regno_mode_code_ok_for_base_p (REGNO (reg), QImode, 3342 as, outer_code, UNKNOWN) 3343 || (!strict 3344 && REGNO (reg) >= FIRST_PSEUDO_REGISTER))); 3345 } 3346 3347 3348 /* Return nonzero if X (an RTX) is a legitimate memory address on the target 3349 machine for a memory operand of mode MODE. */ 3350 3351 static bool 3352 avr_legitimate_address_p (machine_mode mode, rtx x, bool strict) 3353 { 3354 bool ok = CONSTANT_ADDRESS_P (x); 3355 3356 switch (GET_CODE (x)) 3357 { 3358 case REG: 3359 ok = avr_reg_ok_for_addr_p (x, ADDR_SPACE_GENERIC, 3360 MEM, strict); 3361 3362 if (strict 3363 && GET_MODE_SIZE (mode) > 4 3364 && REG_X == REGNO (x)) 3365 { 3366 ok = false; 3367 } 3368 break; 3369 3370 case POST_INC: 3371 case PRE_DEC: 3372 ok = avr_reg_ok_for_addr_p (XEXP (x, 0), ADDR_SPACE_GENERIC, 3373 GET_CODE (x), strict); 3374 break; 3375 3376 case PLUS: 3377 { 3378 rtx reg = XEXP (x, 0); 3379 rtx op1 = XEXP (x, 1); 3380 3381 if (REG_P (reg) 3382 && CONST_INT_P (op1) 3383 && INTVAL (op1) >= 0) 3384 { 3385 bool fit = (IN_RANGE (INTVAL (op1), 0, MAX_LD_OFFSET (mode)) 3386 // Reduced Tiny does not support PLUS addressing 3387 // anyway, so we are not restricted to LD offset. 3388 || AVR_TINY); 3389 3390 if (fit) 3391 { 3392 ok = (! strict 3393 || avr_reg_ok_for_addr_p (reg, ADDR_SPACE_GENERIC, 3394 PLUS, strict)); 3395 3396 if (reg == frame_pointer_rtx 3397 || reg == arg_pointer_rtx) 3398 { 3399 ok = true; 3400 } 3401 } 3402 else if (frame_pointer_needed 3403 && reg == frame_pointer_rtx) 3404 { 3405 ok = true; 3406 } 3407 } 3408 } 3409 break; 3410 3411 default: 3412 break; 3413 } 3414 3415 if (AVR_TINY 3416 && CONSTANT_ADDRESS_P (x)) 3417 { 3418 /* avrtiny's load / store instructions only cover addresses 0..0xbf: 3419 IN / OUT range is 0..0x3f and LDS / STS can access 0x40..0xbf. */ 3420 3421 ok = avr_address_tiny_absdata_p (x, mode); 3422 } 3423 3424 if (avr_log.legitimate_address_p) 3425 { 3426 avr_edump ("\n%?: ret=%d, mode=%m strict=%d " 3427 "reload_completed=%d reload_in_progress=%d %s:", 3428 ok, mode, strict, reload_completed, reload_in_progress, 3429 reg_renumber ? "(reg_renumber)" : ""); 3430 3431 if (GET_CODE (x) == PLUS 3432 && REG_P (XEXP (x, 0)) 3433 && CONST_INT_P (XEXP (x, 1)) 3434 && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode)) 3435 && reg_renumber) 3436 { 3437 avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)), 3438 true_regnum (XEXP (x, 0))); 3439 } 3440 3441 avr_edump ("\n%r\n", x); 3442 } 3443 3444 return ok; 3445 } 3446 3447 3448 /* Former implementation of TARGET_LEGITIMIZE_ADDRESS, 3449 now only a helper for avr_addr_space_legitimize_address. */ 3450 /* Attempts to replace X with a valid 3451 memory address for an operand of mode MODE */ 3452 3453 static rtx 3454 avr_legitimize_address (rtx x, rtx oldx, machine_mode mode) 3455 { 3456 bool big_offset_p = false; 3457 3458 x = oldx; 3459 3460 if (AVR_TINY) 3461 { 3462 if (CONSTANT_ADDRESS_P (x) 3463 && ! avr_address_tiny_absdata_p (x, mode)) 3464 { 3465 x = force_reg (Pmode, x); 3466 } 3467 } 3468 3469 if (GET_CODE (oldx) == PLUS 3470 && REG_P (XEXP (oldx, 0))) 3471 { 3472 if (REG_P (XEXP (oldx, 1))) 3473 x = force_reg (GET_MODE (oldx), oldx); 3474 else if (CONST_INT_P (XEXP (oldx, 1))) 3475 { 3476 int offs = INTVAL (XEXP (oldx, 1)); 3477 if (frame_pointer_rtx != XEXP (oldx, 0) 3478 && offs > MAX_LD_OFFSET (mode)) 3479 { 3480 big_offset_p = true; 3481 x = force_reg (GET_MODE (oldx), oldx); 3482 } 3483 } 3484 } 3485 3486 if (avr_log.legitimize_address) 3487 { 3488 avr_edump ("\n%?: mode=%m\n %r\n", mode, oldx); 3489 3490 if (x != oldx) 3491 avr_edump (" %s --> %r\n", big_offset_p ? "(big offset)" : "", x); 3492 } 3493 3494 return x; 3495 } 3496 3497 3498 /* Implement `LEGITIMIZE_RELOAD_ADDRESS'. */ 3499 /* This will allow register R26/27 to be used where it is no worse than normal 3500 base pointers R28/29 or R30/31. For example, if base offset is greater 3501 than 63 bytes or for R++ or --R addressing. */ 3502 3503 rtx 3504 avr_legitimize_reload_address (rtx *px, machine_mode mode, int opnum, 3505 int type, int addr_type, int /*ind_levels*/, 3506 rtx (*mk_memloc)(rtx,int)) 3507 { 3508 rtx x = *px; 3509 3510 if (avr_log.legitimize_reload_address) 3511 avr_edump ("\n%?:%m %r\n", mode, x); 3512 3513 if (1 && (GET_CODE (x) == POST_INC 3514 || GET_CODE (x) == PRE_DEC)) 3515 { 3516 push_reload (XEXP (x, 0), XEXP (x, 0), &XEXP (x, 0), &XEXP (x, 0), 3517 POINTER_REGS, GET_MODE (x), GET_MODE (x), 0, 0, 3518 opnum, RELOAD_OTHER); 3519 3520 if (avr_log.legitimize_reload_address) 3521 avr_edump (" RCLASS.1 = %R\n IN = %r\n OUT = %r\n", 3522 POINTER_REGS, XEXP (x, 0), XEXP (x, 0)); 3523 3524 return x; 3525 } 3526 3527 if (GET_CODE (x) == PLUS 3528 && REG_P (XEXP (x, 0)) 3529 && reg_equiv_constant (REGNO (XEXP (x, 0))) == 0 3530 && CONST_INT_P (XEXP (x, 1)) 3531 && INTVAL (XEXP (x, 1)) >= 1) 3532 { 3533 bool fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode); 3534 3535 if (fit) 3536 { 3537 if (reg_equiv_address (REGNO (XEXP (x, 0))) != 0) 3538 { 3539 int regno = REGNO (XEXP (x, 0)); 3540 rtx mem = mk_memloc (x, regno); 3541 3542 push_reload (XEXP (mem, 0), NULL_RTX, &XEXP (mem, 0), NULL, 3543 POINTER_REGS, Pmode, VOIDmode, 0, 0, 3544 1, (enum reload_type) addr_type); 3545 3546 if (avr_log.legitimize_reload_address) 3547 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n", 3548 POINTER_REGS, XEXP (mem, 0), NULL_RTX); 3549 3550 push_reload (mem, NULL_RTX, &XEXP (x, 0), NULL, 3551 BASE_POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0, 3552 opnum, (enum reload_type) type); 3553 3554 if (avr_log.legitimize_reload_address) 3555 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n", 3556 BASE_POINTER_REGS, mem, NULL_RTX); 3557 3558 return x; 3559 } 3560 } 3561 else if (! (frame_pointer_needed 3562 && XEXP (x, 0) == frame_pointer_rtx)) 3563 { 3564 push_reload (x, NULL_RTX, px, NULL, 3565 POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0, 3566 opnum, (enum reload_type) type); 3567 3568 if (avr_log.legitimize_reload_address) 3569 avr_edump (" RCLASS.3 = %R\n IN = %r\n OUT = %r\n", 3570 POINTER_REGS, x, NULL_RTX); 3571 3572 return x; 3573 } 3574 } 3575 3576 return NULL_RTX; 3577 } 3578 3579 3580 /* Helper function to print assembler resp. track instruction 3581 sequence lengths. Always return "". 3582 3583 If PLEN == NULL: 3584 Output assembler code from template TPL with operands supplied 3585 by OPERANDS. This is just forwarding to output_asm_insn. 3586 3587 If PLEN != NULL: 3588 If N_WORDS >= 0 Add N_WORDS to *PLEN. 3589 If N_WORDS < 0 Set *PLEN to -N_WORDS. 3590 Don't output anything. 3591 */ 3592 3593 static const char * 3594 avr_asm_len (const char *tpl, rtx *operands, int *plen, int n_words) 3595 { 3596 if (plen == NULL) 3597 output_asm_insn (tpl, operands); 3598 else 3599 { 3600 if (n_words < 0) 3601 *plen = -n_words; 3602 else 3603 *plen += n_words; 3604 } 3605 3606 return ""; 3607 } 3608 3609 3610 /* Return a pointer register name as a string. */ 3611 3612 static const char * 3613 ptrreg_to_str (int regno) 3614 { 3615 switch (regno) 3616 { 3617 case REG_X: return "X"; 3618 case REG_Y: return "Y"; 3619 case REG_Z: return "Z"; 3620 default: 3621 output_operand_lossage ("address operand requires constraint for" 3622 " X, Y, or Z register"); 3623 } 3624 return NULL; 3625 } 3626 3627 /* Return the condition name as a string. 3628 Used in conditional jump constructing */ 3629 3630 static const char * 3631 cond_string (enum rtx_code code) 3632 { 3633 bool cc_overflow_unusable = false; 3634 3635 switch (code) 3636 { 3637 case NE: 3638 return "ne"; 3639 case EQ: 3640 return "eq"; 3641 case GE: 3642 if (cc_overflow_unusable) 3643 return "pl"; 3644 else 3645 return "ge"; 3646 case LT: 3647 if (cc_overflow_unusable) 3648 return "mi"; 3649 else 3650 return "lt"; 3651 case GEU: 3652 return "sh"; 3653 case LTU: 3654 return "lo"; 3655 default: 3656 gcc_unreachable (); 3657 } 3658 3659 return ""; 3660 } 3661 3662 3663 /* Return true if rtx X is a CONST or SYMBOL_REF with progmem. 3664 This must be used for AVR_TINY only because on other cores 3665 the flash memory is not visible in the RAM address range and 3666 cannot be read by, say, LD instruction. */ 3667 3668 static bool 3669 avr_address_tiny_pm_p (rtx x) 3670 { 3671 if (CONST == GET_CODE (x)) 3672 x = XEXP (XEXP (x, 0), 0); 3673 3674 if (SYMBOL_REF_P (x)) 3675 return SYMBOL_REF_FLAGS (x) & AVR_SYMBOL_FLAG_TINY_PM; 3676 3677 return false; 3678 } 3679 3680 /* Implement `TARGET_PRINT_OPERAND_ADDRESS'. */ 3681 /* Output ADDR to FILE as address. */ 3682 3683 static void 3684 avr_print_operand_address (FILE *file, machine_mode /*mode*/, rtx addr) 3685 { 3686 if (AVR_TINY 3687 && avr_address_tiny_pm_p (addr)) 3688 { 3689 addr = plus_constant (Pmode, addr, avr_arch->flash_pm_offset); 3690 } 3691 3692 switch (GET_CODE (addr)) 3693 { 3694 case REG: 3695 fprintf (file, "%s", ptrreg_to_str (REGNO (addr))); 3696 break; 3697 3698 case PRE_DEC: 3699 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0)))); 3700 break; 3701 3702 case POST_INC: 3703 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0)))); 3704 break; 3705 3706 default: 3707 if (CONSTANT_ADDRESS_P (addr) 3708 && text_segment_operand (addr, VOIDmode)) 3709 { 3710 rtx x = addr; 3711 if (GET_CODE (x) == CONST) 3712 x = XEXP (x, 0); 3713 if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1))) 3714 { 3715 /* Assembler gs() will implant word address. Make offset 3716 a byte offset inside gs() for assembler. This is 3717 needed because the more logical (constant+gs(sym)) is not 3718 accepted by gas. For 128K and smaller devices this is ok. 3719 For large devices it will create a trampoline to offset 3720 from symbol which may not be what the user really wanted. */ 3721 3722 fprintf (file, "gs("); 3723 output_addr_const (file, XEXP (x, 0)); 3724 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC ")", 3725 2 * INTVAL (XEXP (x, 1))); 3726 if (AVR_3_BYTE_PC) 3727 if (warning (0, "pointer offset from symbol maybe incorrect")) 3728 { 3729 output_addr_const (stderr, addr); 3730 fprintf (stderr, "\n"); 3731 } 3732 } 3733 else 3734 { 3735 fprintf (file, "gs("); 3736 output_addr_const (file, addr); 3737 fprintf (file, ")"); 3738 } 3739 } 3740 else 3741 output_addr_const (file, addr); 3742 } 3743 } 3744 3745 3746 /* Implement `TARGET_PRINT_OPERAND_PUNCT_VALID_P'. */ 3747 3748 static bool 3749 avr_print_operand_punct_valid_p (unsigned char code) 3750 { 3751 return code == '~' || code == '!'; 3752 } 3753 3754 3755 /* Implement `TARGET_PRINT_OPERAND'. */ 3756 /* Output X as assembler operand to file FILE. 3757 For a description of supported %-codes, see top of avr.md. */ 3758 3759 static void 3760 avr_print_operand (FILE *file, rtx x, int code) 3761 { 3762 int abcd = 0, ef = 0, ij = 0; 3763 3764 if (code >= 'A' && code <= 'D') 3765 abcd = code - 'A'; 3766 else if (code == 'E' || code == 'F') 3767 ef = code - 'E'; 3768 else if (code == 'I' || code == 'J') 3769 ij = code - 'I'; 3770 3771 if (code == '~') 3772 { 3773 if (!AVR_HAVE_JMP_CALL) 3774 fputc ('r', file); 3775 } 3776 else if (code == '!') 3777 { 3778 if (AVR_HAVE_EIJMP_EICALL) 3779 fputc ('e', file); 3780 } 3781 else if (code == 't' 3782 || code == 'T') 3783 { 3784 static int t_regno = -1; 3785 static int t_nbits = -1; 3786 3787 if (REG_P (x) && t_regno < 0 && code == 'T') 3788 { 3789 t_regno = REGNO (x); 3790 t_nbits = GET_MODE_BITSIZE (GET_MODE (x)); 3791 } 3792 else if (CONST_INT_P (x) && t_regno >= 0 3793 && IN_RANGE (INTVAL (x), 0, t_nbits - 1)) 3794 { 3795 int bpos = INTVAL (x); 3796 3797 fprintf (file, "%s", reg_names[t_regno + bpos / 8]); 3798 if (code == 'T') 3799 fprintf (file, ",%d", bpos % 8); 3800 3801 t_regno = -1; 3802 } 3803 else 3804 fatal_insn ("operands to %T/%t must be reg + const_int:", x); 3805 } 3806 else if (code == 'E' || code == 'F') 3807 { 3808 rtx op = XEXP (x, 0); 3809 fprintf (file, "%s", reg_names[REGNO (op) + ef]); 3810 } 3811 else if (code == 'I' || code == 'J') 3812 { 3813 rtx op = XEXP (XEXP (x, 0), 0); 3814 fprintf (file, "%s", reg_names[REGNO (op) + ij]); 3815 } 3816 else if (code == 'i') 3817 { 3818 const int sfr0 = avr_arch->sfr_offset; 3819 bool lossage_p = false; 3820 3821 switch (GET_CODE (x)) 3822 { 3823 default: 3824 lossage_p = true; 3825 break; 3826 3827 case CONST_INT: 3828 { 3829 const auto ival = INTVAL (x); 3830 3831 if (io_address_operand (x, VOIDmode)) 3832 { 3833 if (AVR_HAVE_RAMPZ && ival == avr_addr.rampz) 3834 fprintf (file, "__RAMPZ__"); 3835 else if (AVR_HAVE_RAMPY && ival == avr_addr.rampy) 3836 fprintf (file, "__RAMPY__"); 3837 else if (AVR_HAVE_RAMPX && ival == avr_addr.rampx) 3838 fprintf (file, "__RAMPX__"); 3839 else if (AVR_HAVE_RAMPD && ival == avr_addr.rampd) 3840 fprintf (file, "__RAMPD__"); 3841 else if ((AVR_XMEGA || AVR_TINY) && ival == avr_addr.ccp) 3842 fprintf (file, "__CCP__"); 3843 else if (ival == avr_addr.sreg) fprintf (file, "__SREG__"); 3844 else if (ival == avr_addr.sp_l) fprintf (file, "__SP_L__"); 3845 else if (ival == avr_addr.sp_h) fprintf (file, "__SP_H__"); 3846 else 3847 fprintf (file, HOST_WIDE_INT_PRINT_HEX, ival - sfr0); 3848 } 3849 else 3850 output_operand_lossage 3851 ("bad I/O address 0x" HOST_WIDE_INT_PRINT_HEX_PURE 3852 " outside of valid range [0x%x, 0x%x] for %%i operand", 3853 ival, sfr0, sfr0 + 0x3f); 3854 } 3855 break; // CONST_INT 3856 3857 case MEM: 3858 if (io_address_operand (XEXP (x, 0), VOIDmode)) 3859 avr_print_operand (file, XEXP (x, 0), 'i'); 3860 else 3861 lossage_p = true; 3862 break; 3863 3864 case SYMBOL_REF: 3865 if (io_address_operand (x, VOIDmode)) 3866 { 3867 rtx addr = plus_constant (HImode, x, -sfr0); 3868 avr_print_operand_address (file, VOIDmode, addr); 3869 } 3870 else 3871 lossage_p = true; 3872 break; 3873 } // switch code 3874 3875 if (lossage_p) 3876 output_operand_lossage ("%s operand cannot be used as %%i I/O " 3877 "address operand", rtx_name[GET_CODE (x)]); 3878 } // code = i 3879 else if (REG_P (x)) 3880 { 3881 if (x == zero_reg_rtx) 3882 fprintf (file, "__zero_reg__"); 3883 else if (code == 'r' && REGNO (x) < REG_32) 3884 fprintf (file, "%d", (int) REGNO (x)); 3885 else 3886 fprintf (file, "%s", reg_names[REGNO (x) + abcd]); 3887 } 3888 else if (CONST_INT_P (x)) 3889 { 3890 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd); 3891 } 3892 else if (MEM_P (x)) 3893 { 3894 rtx addr = XEXP (x, 0); 3895 3896 if (code == 'm') 3897 { 3898 if (!CONSTANT_P (addr)) 3899 fatal_insn ("bad address, not a constant:", addr); 3900 /* Assembler template with m-code is data - not progmem section */ 3901 if (text_segment_operand (addr, VOIDmode)) 3902 if (warning (0, "accessing data memory with" 3903 " program memory address")) 3904 { 3905 output_addr_const (stderr, addr); 3906 fprintf(stderr,"\n"); 3907 } 3908 output_addr_const (file, addr); 3909 } 3910 else if (code == 'o') 3911 { 3912 if (GET_CODE (addr) != PLUS) 3913 fatal_insn ("bad address, not (reg+disp):", addr); 3914 3915 avr_print_operand (file, XEXP (addr, 1), 0); 3916 } 3917 else if (code == 'b') 3918 { 3919 if (GET_CODE (addr) != PLUS) 3920 fatal_insn ("bad address, not (reg+disp):", addr); 3921 3922 avr_print_operand_address (file, VOIDmode, XEXP (addr, 0)); 3923 } 3924 else if (code == 'p' || code == 'r') 3925 { 3926 if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC) 3927 fatal_insn ("bad address, not post_inc or pre_dec:", addr); 3928 3929 if (code == 'p') 3930 /* X, Y, Z */ 3931 avr_print_operand_address (file, VOIDmode, XEXP (addr, 0)); 3932 else 3933 avr_print_operand (file, XEXP (addr, 0), 0); /* r26, r28, r30 */ 3934 } 3935 else if (GET_CODE (addr) == PLUS) 3936 { 3937 avr_print_operand_address (file, VOIDmode, XEXP (addr, 0)); 3938 if (REGNO (XEXP (addr, 0)) == REG_X) 3939 fatal_insn ("internal compiler error. Bad address:" 3940 ,addr); 3941 fputc ('+', file); 3942 avr_print_operand (file, XEXP (addr, 1), code); 3943 } 3944 else 3945 avr_print_operand_address (file, VOIDmode, addr); 3946 } 3947 else if (code == 'x') 3948 { 3949 /* Constant progmem address - like used in jmp or call */ 3950 if (text_segment_operand (x, VOIDmode) == 0) 3951 if (warning (0, "accessing program memory" 3952 " with data memory address")) 3953 { 3954 output_addr_const (stderr, x); 3955 fprintf(stderr,"\n"); 3956 } 3957 /* Use normal symbol for direct address no linker trampoline needed */ 3958 output_addr_const (file, x); 3959 } 3960 else if (CONST_FIXED_P (x)) 3961 { 3962 HOST_WIDE_INT ival = INTVAL (avr_to_int_mode (x)); 3963 if (code != 0) 3964 output_operand_lossage ("Unsupported code '%c' for fixed-point:", 3965 code); 3966 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival); 3967 } 3968 else if (CONST_DOUBLE_P (x)) 3969 { 3970 if (GET_MODE (x) == SFmode) 3971 { 3972 long val; 3973 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), val); 3974 fprintf (file, "0x%lx", val); 3975 } 3976 else if (GET_MODE (x) == DFmode) 3977 { 3978 long l[2]; 3979 REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x), l); 3980 fprintf (file, "0x%lx%08lx", l[1] & 0xffffffff, l[0] & 0xffffffff); 3981 } 3982 else 3983 fatal_insn ("internal compiler error. Unknown mode:", x); 3984 } 3985 else if (GET_CODE (x) == CONST_STRING) 3986 fputs (XSTR (x, 0), file); 3987 else if (code == 'j') 3988 fputs (cond_string (GET_CODE (x)), file); 3989 else if (code == 'k') 3990 fputs (cond_string (reverse_condition (GET_CODE (x))), file); 3991 else 3992 avr_print_operand_address (file, VOIDmode, x); 3993 } 3994 3995 3996 /* Implement `TARGET_USE_BY_PIECES_INFRASTRUCTURE_P'. */ 3997 /* Prefer sequence of loads/stores for moves of size upto 3998 two - two pairs of load/store instructions are always better 3999 than the 5 instruction sequence for a loop (1 instruction 4000 for loop counter setup, and 4 for the body of the loop). */ 4001 4002 static bool 4003 avr_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size, 4004 unsigned int align, 4005 enum by_pieces_operation op, bool speed_p) 4006 { 4007 if (op != MOVE_BY_PIECES 4008 || (speed_p && size > MOVE_MAX_PIECES)) 4009 return default_use_by_pieces_infrastructure_p (size, align, op, speed_p); 4010 4011 return size <= MOVE_MAX_PIECES; 4012 } 4013 4014 /* Choose mode for jump insn: 4015 1 - relative jump in range -63 <= x <= 62 ; 4016 2 - relative jump in range -2046 <= x <= 2045 ; 4017 3 - absolute jump (only when we have JMP / CALL). 4018 4019 When jumping backwards, assume the jump offset is EXTRA words 4020 bigger than inferred from insn addresses. */ 4021 4022 int 4023 avr_jump_mode (rtx x, rtx_insn *insn, int extra) 4024 { 4025 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_CODE (x) == LABEL_REF 4026 ? XEXP (x, 0) : x)); 4027 int cur_addr = INSN_ADDRESSES (INSN_UID (insn)); 4028 int jump_distance = cur_addr - dest_addr; 4029 4030 if (IN_RANGE (jump_distance, -63, 62 - extra)) 4031 return 1; 4032 else if (IN_RANGE (jump_distance, -2046, 2045 - extra)) 4033 return 2; 4034 else if (AVR_HAVE_JMP_CALL) 4035 return 3; 4036 4037 return 2; 4038 } 4039 4040 /* Return an AVR condition jump commands. 4041 X is a comparison RTX. 4042 LEN is a number returned by avr_jump_mode function. 4043 If REVERSE nonzero then condition code in X must be reversed. */ 4044 4045 const char * 4046 ret_cond_branch (rtx x, int len, int reverse) 4047 { 4048 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x); 4049 bool cc_overflow_unusable = false; 4050 4051 switch (cond) 4052 { 4053 case GT: 4054 if (cc_overflow_unusable) 4055 return (len == 1 ? ("breq .+2" CR_TAB 4056 "brpl %0") : 4057 len == 2 ? ("breq .+4" CR_TAB 4058 "brmi .+2" CR_TAB 4059 "rjmp %0") : 4060 ("breq .+6" CR_TAB 4061 "brmi .+4" CR_TAB 4062 "jmp %0")); 4063 4064 else 4065 return (len == 1 ? ("breq .+2" CR_TAB 4066 "brge %0") : 4067 len == 2 ? ("breq .+4" CR_TAB 4068 "brlt .+2" CR_TAB 4069 "rjmp %0") : 4070 ("breq .+6" CR_TAB 4071 "brlt .+4" CR_TAB 4072 "jmp %0")); 4073 case GTU: 4074 return (len == 1 ? ("breq .+2" CR_TAB 4075 "brsh %0") : 4076 len == 2 ? ("breq .+4" CR_TAB 4077 "brlo .+2" CR_TAB 4078 "rjmp %0") : 4079 ("breq .+6" CR_TAB 4080 "brlo .+4" CR_TAB 4081 "jmp %0")); 4082 case LE: 4083 if (cc_overflow_unusable) 4084 return (len == 1 ? ("breq %0" CR_TAB 4085 "brmi %0") : 4086 len == 2 ? ("breq .+2" CR_TAB 4087 "brpl .+2" CR_TAB 4088 "rjmp %0") : 4089 ("breq .+2" CR_TAB 4090 "brpl .+4" CR_TAB 4091 "jmp %0")); 4092 else 4093 return (len == 1 ? ("breq %0" CR_TAB 4094 "brlt %0") : 4095 len == 2 ? ("breq .+2" CR_TAB 4096 "brge .+2" CR_TAB 4097 "rjmp %0") : 4098 ("breq .+2" CR_TAB 4099 "brge .+4" CR_TAB 4100 "jmp %0")); 4101 case LEU: 4102 return (len == 1 ? ("breq %0" CR_TAB 4103 "brlo %0") : 4104 len == 2 ? ("breq .+2" CR_TAB 4105 "brsh .+2" CR_TAB 4106 "rjmp %0") : 4107 ("breq .+2" CR_TAB 4108 "brsh .+4" CR_TAB 4109 "jmp %0")); 4110 default: 4111 if (reverse) 4112 { 4113 switch (len) 4114 { 4115 case 1: 4116 return "br%k1 %0"; 4117 case 2: 4118 return ("br%j1 .+2" CR_TAB 4119 "rjmp %0"); 4120 default: 4121 return ("br%j1 .+4" CR_TAB 4122 "jmp %0"); 4123 } 4124 } 4125 else 4126 { 4127 switch (len) 4128 { 4129 case 1: 4130 return "br%j1 %0"; 4131 case 2: 4132 return ("br%k1 .+2" CR_TAB 4133 "rjmp %0"); 4134 default: 4135 return ("br%k1 .+4" CR_TAB 4136 "jmp %0"); 4137 } 4138 } 4139 } 4140 return ""; 4141 } 4142 4143 4144 /* Worker function for `FINAL_PRESCAN_INSN'. */ 4145 /* Output insn cost for next insn. */ 4146 4147 void 4148 avr_final_prescan_insn (rtx_insn *insn, rtx * /*operands*/, 4149 int /*num_operands*/) 4150 { 4151 if (avr_log.rtx_costs) 4152 { 4153 rtx set = single_set (insn); 4154 4155 if (set) 4156 fprintf (asm_out_file, "/* DEBUG: cost = %d. */\n", 4157 set_src_cost (SET_SRC (set), GET_MODE (SET_DEST (set)), 4158 optimize_insn_for_speed_p ())); 4159 else 4160 fprintf (asm_out_file, "/* DEBUG: pattern-cost = %d. */\n", 4161 rtx_cost (PATTERN (insn), VOIDmode, INSN, 0, 4162 optimize_insn_for_speed_p())); 4163 } 4164 4165 if (avr_log.insn_addresses) 4166 fprintf (asm_out_file, ";; ADDR = %d\n", 4167 (int) INSN_ADDRESSES (INSN_UID (insn))); 4168 } 4169 4170 4171 /* Implement `TARGET_ASM_FINAL_POSTSCAN_INSN'. */ 4172 /* When GAS generates (parts of) ISR prologue / epilogue for us, we must 4173 hint GAS about the end of the code to scan. There migh be code located 4174 after the last epilogue. */ 4175 4176 static void 4177 avr_asm_final_postscan_insn (FILE *stream, rtx_insn *insn, rtx *, int) 4178 { 4179 if (cfun->machine->gasisr.yes 4180 && !next_real_insn (insn)) 4181 { 4182 app_disable(); 4183 fprintf (stream, "\t__gcc_isr %d,r%d\n", GASISR_Done, 4184 cfun->machine->gasisr.regno); 4185 } 4186 } 4187 4188 4189 /* Worker function for `FUNCTION_ARG_REGNO_P'. */ 4190 /* Returns nonzero if REGNO is the number of a hard 4191 register in which function arguments are sometimes passed. */ 4192 4193 int 4194 avr_function_arg_regno_p (int r) 4195 { 4196 return AVR_TINY 4197 ? IN_RANGE (r, REG_20, REG_25) 4198 : IN_RANGE (r, REG_8, REG_25); 4199 } 4200 4201 4202 /* Worker function for `INIT_CUMULATIVE_ARGS'. */ 4203 /* Initializing the variable cum for the state at the beginning 4204 of the argument list. */ 4205 4206 void 4207 avr_init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname, 4208 tree /*fndecl*/) 4209 { 4210 cum->nregs = AVR_TINY ? 1 + REG_25 - REG_20 : 1 + REG_25 - REG_8; 4211 cum->regno = FIRST_CUM_REG; 4212 cum->has_stack_args = 0; 4213 if (!libname && stdarg_p (fntype)) 4214 cum->nregs = 0; 4215 4216 /* Assume the calle may be tail called */ 4217 4218 cfun->machine->sibcall_fails = 0; 4219 } 4220 4221 /* Returns the number of registers to allocate for a function argument. */ 4222 4223 static int 4224 avr_num_arg_regs (machine_mode mode, const_tree type) 4225 { 4226 int size = (mode == BLKmode 4227 ? int_size_in_bytes (type) 4228 : GET_MODE_SIZE (mode)); 4229 4230 /* Align all function arguments to start in even-numbered registers. 4231 Odd-sized arguments leave holes above them. */ 4232 4233 return (size + 1) & ~1; 4234 } 4235 4236 4237 /* Implement `TARGET_FUNCTION_ARG'. */ 4238 /* Controls whether a function argument is passed 4239 in a register, and which register. */ 4240 4241 static rtx 4242 avr_function_arg (cumulative_args_t cum_v, const function_arg_info &arg) 4243 { 4244 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 4245 int bytes = avr_num_arg_regs (arg.mode, arg.type); 4246 4247 if (cum->nregs && bytes <= cum->nregs) 4248 return gen_rtx_REG (arg.mode, cum->regno - bytes); 4249 4250 cum->has_stack_args = 1; 4251 4252 return NULL_RTX; 4253 } 4254 4255 4256 /* Implement `TARGET_FUNCTION_ARG_ADVANCE'. */ 4257 /* Update the summarizer variable CUM to advance past an argument 4258 in the argument list. */ 4259 4260 static void 4261 avr_function_arg_advance (cumulative_args_t cum_v, const function_arg_info &arg) 4262 { 4263 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 4264 int bytes = avr_num_arg_regs (arg.mode, arg.type); 4265 4266 cum->nregs -= bytes; 4267 cum->regno -= bytes; 4268 4269 /* A parameter is being passed in a call-saved register. As the original 4270 contents of these regs has to be restored before leaving the function, 4271 a function must not pass arguments in call-saved regs in order to get 4272 tail-called. */ 4273 4274 if (cum->regno >= REG_8 4275 && cum->nregs >= 0 4276 && !call_used_or_fixed_reg_p (cum->regno)) 4277 { 4278 /* FIXME: We ship info on failing tail-call in struct machine_function. 4279 This uses internals of calls.cc:expand_call() and the way args_so_far 4280 is used. targetm.function_ok_for_sibcall() needs to be extended to 4281 pass &args_so_far, too. At present, CUMULATIVE_ARGS is target 4282 dependent so that such an extension is not wanted. */ 4283 4284 cfun->machine->sibcall_fails = 1; 4285 } 4286 4287 /* Test if all registers needed by the ABI are actually available. If the 4288 user has fixed a GPR needed to pass an argument, an (implicit) function 4289 call will clobber that fixed register. See PR45099 for an example. */ 4290 4291 if (cum->regno >= REG_8 4292 && cum->nregs >= 0) 4293 { 4294 for (int regno = cum->regno; regno < cum->regno + bytes; regno++) 4295 if (fixed_regs[regno]) 4296 warning (0, "fixed register %s used to pass parameter to function", 4297 reg_names[regno]); 4298 } 4299 4300 if (cum->nregs <= 0) 4301 { 4302 cum->nregs = 0; 4303 cum->regno = FIRST_CUM_REG; 4304 } 4305 } 4306 4307 /* Implement `TARGET_FUNCTION_OK_FOR_SIBCALL' */ 4308 /* Decide whether we can make a sibling call to a function. DECL is the 4309 declaration of the function being targeted by the call and EXP is the 4310 CALL_EXPR representing the call. */ 4311 4312 static bool 4313 avr_function_ok_for_sibcall (tree decl_callee, tree exp_callee) 4314 { 4315 /* Tail-calling must fail if callee-saved regs are used to pass 4316 function args. We must not tail-call when `epilogue_restores' 4317 is used. Unfortunately, we cannot tell at this point if that 4318 actually will happen or not, and we cannot step back from 4319 tail-calling. Thus, we inhibit tail-calling with -mcall-prologues. */ 4320 4321 if (cfun->machine->sibcall_fails 4322 || TARGET_CALL_PROLOGUES) 4323 { 4324 return false; 4325 } 4326 4327 tree fntype_callee = TREE_TYPE (CALL_EXPR_FN (exp_callee)); 4328 4329 if (decl_callee) 4330 { 4331 decl_callee = TREE_TYPE (decl_callee); 4332 } 4333 else 4334 { 4335 decl_callee = fntype_callee; 4336 4337 while (FUNCTION_TYPE != TREE_CODE (decl_callee) 4338 && METHOD_TYPE != TREE_CODE (decl_callee)) 4339 { 4340 decl_callee = TREE_TYPE (decl_callee); 4341 } 4342 } 4343 4344 /* Ensure that caller and callee have compatible epilogues */ 4345 4346 if (cfun->machine->is_interrupt 4347 || cfun->machine->is_signal 4348 || cfun->machine->is_naked 4349 || avr_naked_function_p (decl_callee)) 4350 { 4351 return false; 4352 } 4353 4354 return true; 4355 } 4356 4357 /*********************************************************************** 4358 Functions for outputting various mov's for a various modes 4359 ************************************************************************/ 4360 4361 /* Return true if a value of mode MODE is read from flash by 4362 __load_* function from libgcc. */ 4363 4364 bool 4365 avr_load_libgcc_p (rtx op) 4366 { 4367 machine_mode mode = GET_MODE (op); 4368 int n_bytes = GET_MODE_SIZE (mode); 4369 4370 return (n_bytes > 2 4371 && !AVR_HAVE_LPMX 4372 && avr_mem_flash_p (op)); 4373 } 4374 4375 /* Return true if a value of mode MODE is read by __xload_* function. */ 4376 4377 bool 4378 avr_xload_libgcc_p (machine_mode mode) 4379 { 4380 int n_bytes = GET_MODE_SIZE (mode); 4381 4382 return (n_bytes > 1 4383 || avr_n_flash > 1); 4384 } 4385 4386 4387 /* Fixme: This is a hack because secondary reloads don't works as expected. 4388 4389 Find an unused d-register to be used as scratch in INSN. 4390 EXCLUDE is either NULL_RTX or some register. In the case where EXCLUDE 4391 is a register, skip all possible return values that overlap EXCLUDE. 4392 The policy for the returned register is similar to that of 4393 `reg_unused_after', i.e. the returned register may overlap the SET_DEST 4394 of INSN. 4395 4396 Return a QImode d-register or NULL_RTX if nothing found. */ 4397 4398 static rtx 4399 avr_find_unused_d_reg (rtx_insn *insn, rtx exclude) 4400 { 4401 bool isr_p = (avr_interrupt_function_p (current_function_decl) 4402 || avr_signal_function_p (current_function_decl)); 4403 4404 for (int regno = REG_16; regno < REG_32; regno++) 4405 { 4406 rtx reg = all_regs_rtx[regno]; 4407 4408 if ((exclude 4409 && reg_overlap_mentioned_p (exclude, reg)) 4410 || fixed_regs[regno]) 4411 { 4412 continue; 4413 } 4414 4415 /* Try non-live register */ 4416 4417 if (!df_regs_ever_live_p (regno) 4418 && (TREE_THIS_VOLATILE (current_function_decl) 4419 || cfun->machine->is_OS_task 4420 || cfun->machine->is_OS_main 4421 || (!isr_p && call_used_or_fixed_reg_p (regno)))) 4422 { 4423 return reg; 4424 } 4425 4426 /* Any live register can be used if it is unused after. 4427 Prologue/epilogue will care for it as needed. */ 4428 4429 if (df_regs_ever_live_p (regno) 4430 && reg_unused_after (insn, reg)) 4431 { 4432 return reg; 4433 } 4434 } 4435 4436 return NULL_RTX; 4437 } 4438 4439 4440 /* Helper function for the next function in the case where only restricted 4441 version of LPM instruction is available. */ 4442 4443 static const char * 4444 avr_out_lpm_no_lpmx (rtx_insn *insn, rtx *xop, int *plen) 4445 { 4446 rtx dest = xop[0]; 4447 rtx addr = xop[1]; 4448 int n_bytes = GET_MODE_SIZE (GET_MODE (dest)); 4449 int regno_dest; 4450 4451 regno_dest = REGNO (dest); 4452 4453 /* The implicit target register of LPM. */ 4454 xop[3] = lpm_reg_rtx; 4455 4456 switch (GET_CODE (addr)) 4457 { 4458 default: 4459 gcc_unreachable(); 4460 4461 case REG: 4462 4463 gcc_assert (REG_Z == REGNO (addr)); 4464 4465 switch (n_bytes) 4466 { 4467 default: 4468 gcc_unreachable(); 4469 4470 case 1: 4471 avr_asm_len ("%4lpm", xop, plen, 1); 4472 4473 if (regno_dest != LPM_REGNO) 4474 avr_asm_len ("mov %0,%3", xop, plen, 1); 4475 4476 return ""; 4477 4478 case 2: 4479 if (REGNO (dest) == REG_Z) 4480 return avr_asm_len ("%4lpm" CR_TAB 4481 "push %3" CR_TAB 4482 "adiw %2,1" CR_TAB 4483 "%4lpm" CR_TAB 4484 "mov %B0,%3" CR_TAB 4485 "pop %A0", xop, plen, 6); 4486 4487 avr_asm_len ("%4lpm" CR_TAB 4488 "mov %A0,%3" CR_TAB 4489 "adiw %2,1" CR_TAB 4490 "%4lpm" CR_TAB 4491 "mov %B0,%3", xop, plen, 5); 4492 4493 if (!reg_unused_after (insn, addr)) 4494 avr_asm_len ("sbiw %2,1", xop, plen, 1); 4495 4496 break; /* 2 */ 4497 } 4498 4499 break; /* REG */ 4500 4501 case POST_INC: 4502 4503 gcc_assert (REG_Z == REGNO (XEXP (addr, 0)) 4504 && n_bytes <= 4); 4505 4506 if (regno_dest == LPM_REGNO) 4507 avr_asm_len ("%4lpm" CR_TAB 4508 "adiw %2,1", xop, plen, 2); 4509 else 4510 avr_asm_len ("%4lpm" CR_TAB 4511 "mov %A0,%3" CR_TAB 4512 "adiw %2,1", xop, plen, 3); 4513 4514 if (n_bytes >= 2) 4515 avr_asm_len ("%4lpm" CR_TAB 4516 "mov %B0,%3" CR_TAB 4517 "adiw %2,1", xop, plen, 3); 4518 4519 if (n_bytes >= 3) 4520 avr_asm_len ("%4lpm" CR_TAB 4521 "mov %C0,%3" CR_TAB 4522 "adiw %2,1", xop, plen, 3); 4523 4524 if (n_bytes >= 4) 4525 avr_asm_len ("%4lpm" CR_TAB 4526 "mov %D0,%3" CR_TAB 4527 "adiw %2,1", xop, plen, 3); 4528 4529 break; /* POST_INC */ 4530 4531 } /* switch CODE (addr) */ 4532 4533 return ""; 4534 } 4535 4536 4537 /* If PLEN == NULL: Ouput instructions to load a value from a memory location 4538 OP[1] in AS1 to register OP[0]. 4539 If PLEN != 0 set *PLEN to the length in words of the instruction sequence. 4540 Return "". */ 4541 4542 const char * 4543 avr_out_lpm (rtx_insn *insn, rtx *op, int *plen) 4544 { 4545 rtx xop[7]; 4546 rtx dest = op[0]; 4547 rtx src = SET_SRC (single_set (insn)); 4548 int n_bytes = GET_MODE_SIZE (GET_MODE (dest)); 4549 addr_space_t as = MEM_ADDR_SPACE (src); 4550 4551 if (plen) 4552 *plen = 0; 4553 4554 if (MEM_P (dest)) 4555 { 4556 warning (0, "writing to address space %qs not supported", 4557 avr_addrspace[MEM_ADDR_SPACE (dest)].name); 4558 4559 return ""; 4560 } 4561 4562 rtx addr = XEXP (src, 0); 4563 RTX_CODE code = GET_CODE (addr); 4564 4565 gcc_assert (REG_P (dest)); 4566 gcc_assert (REG == code || POST_INC == code); 4567 4568 xop[0] = dest; 4569 xop[1] = addr; 4570 xop[2] = lpm_addr_reg_rtx; 4571 xop[4] = xstring_empty; 4572 xop[5] = tmp_reg_rtx; 4573 xop[6] = XEXP (rampz_rtx, 0); 4574 4575 int segment = avr_addrspace[as].segment; 4576 4577 /* Set RAMPZ as needed. */ 4578 4579 if (segment) 4580 { 4581 xop[4] = GEN_INT (segment); 4582 xop[3] = avr_find_unused_d_reg (insn, lpm_addr_reg_rtx); 4583 4584 if (xop[3] != NULL_RTX) 4585 { 4586 avr_asm_len ("ldi %3,%4" CR_TAB 4587 "out %i6,%3", xop, plen, 2); 4588 } 4589 else if (segment == 1) 4590 { 4591 avr_asm_len ("clr %5" CR_TAB 4592 "inc %5" CR_TAB 4593 "out %i6,%5", xop, plen, 3); 4594 } 4595 else 4596 { 4597 avr_asm_len ("mov %5,%2" CR_TAB 4598 "ldi %2,%4" CR_TAB 4599 "out %i6,%2" CR_TAB 4600 "mov %2,%5", xop, plen, 4); 4601 } 4602 4603 xop[4] = xstring_e; 4604 4605 if (!AVR_HAVE_ELPMX) 4606 return avr_out_lpm_no_lpmx (insn, xop, plen); 4607 } 4608 else if (!AVR_HAVE_LPMX) 4609 { 4610 return avr_out_lpm_no_lpmx (insn, xop, plen); 4611 } 4612 4613 /* We have [E]LPMX: Output reading from Flash the comfortable way. */ 4614 4615 switch (GET_CODE (addr)) 4616 { 4617 default: 4618 gcc_unreachable(); 4619 4620 case REG: 4621 4622 gcc_assert (REG_Z == REGNO (addr)); 4623 4624 switch (n_bytes) 4625 { 4626 default: 4627 gcc_unreachable(); 4628 4629 case 1: 4630 avr_asm_len ("%4lpm %0,%a2", xop, plen, 1); 4631 break; 4632 4633 case 2: 4634 if (REGNO (dest) == REG_Z) 4635 avr_asm_len ("%4lpm %5,%a2+" CR_TAB 4636 "%4lpm %B0,%a2" CR_TAB 4637 "mov %A0,%5", xop, plen, 3); 4638 else 4639 { 4640 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB 4641 "%4lpm %B0,%a2", xop, plen, 2); 4642 4643 if (!reg_unused_after (insn, addr)) 4644 avr_asm_len ("sbiw %2,1", xop, plen, 1); 4645 } 4646 4647 break; /* 2 */ 4648 4649 case 3: 4650 4651 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB 4652 "%4lpm %B0,%a2+" CR_TAB 4653 "%4lpm %C0,%a2", xop, plen, 3); 4654 4655 if (!reg_unused_after (insn, addr)) 4656 avr_asm_len ("sbiw %2,2", xop, plen, 1); 4657 4658 break; /* 3 */ 4659 4660 case 4: 4661 4662 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB 4663 "%4lpm %B0,%a2+", xop, plen, 2); 4664 4665 if (REGNO (dest) == REG_Z - 2) 4666 avr_asm_len ("%4lpm %5,%a2+" CR_TAB 4667 "%4lpm %C0,%a2" CR_TAB 4668 "mov %D0,%5", xop, plen, 3); 4669 else 4670 { 4671 avr_asm_len ("%4lpm %C0,%a2+" CR_TAB 4672 "%4lpm %D0,%a2", xop, plen, 2); 4673 4674 if (!reg_unused_after (insn, addr)) 4675 avr_asm_len ("sbiw %2,3", xop, plen, 1); 4676 } 4677 4678 break; /* 4 */ 4679 } /* n_bytes */ 4680 4681 break; /* REG */ 4682 4683 case POST_INC: 4684 4685 gcc_assert (REG_Z == REGNO (XEXP (addr, 0)) 4686 && n_bytes <= 4); 4687 4688 avr_asm_len ("%4lpm %A0,%a2+", xop, plen, 1); 4689 if (n_bytes >= 2) avr_asm_len ("%4lpm %B0,%a2+", xop, plen, 1); 4690 if (n_bytes >= 3) avr_asm_len ("%4lpm %C0,%a2+", xop, plen, 1); 4691 if (n_bytes >= 4) avr_asm_len ("%4lpm %D0,%a2+", xop, plen, 1); 4692 4693 break; /* POST_INC */ 4694 4695 } /* switch CODE (addr) */ 4696 4697 if (xop[4] == xstring_e && AVR_HAVE_RAMPD) 4698 { 4699 /* Reset RAMPZ to 0 so that EBI devices don't read garbage from RAM. */ 4700 4701 xop[0] = zero_reg_rtx; 4702 avr_asm_len ("out %i6,%0", xop, plen, 1); 4703 } 4704 4705 return ""; 4706 } 4707 4708 4709 /* Worker function for xload_8 insn. */ 4710 4711 const char * 4712 avr_out_xload (rtx_insn * /*insn*/, rtx *op, int *plen) 4713 { 4714 rtx xop[4]; 4715 4716 xop[0] = op[0]; 4717 xop[1] = op[1]; 4718 xop[2] = lpm_addr_reg_rtx; 4719 xop[3] = AVR_HAVE_LPMX ? op[0] : lpm_reg_rtx; 4720 4721 if (plen) 4722 *plen = 0; 4723 4724 if (reg_overlap_mentioned_p (xop[3], lpm_addr_reg_rtx)) 4725 avr_asm_len ("sbrs %1,7", xop, plen, 1); 4726 4727 avr_asm_len (AVR_HAVE_LPMX ? "lpm %3,%a2" : "lpm", xop, plen, 1); 4728 4729 avr_asm_len ("sbrc %1,7" CR_TAB 4730 "ld %3,%a2", xop, plen, 2); 4731 4732 if (REGNO (xop[0]) != REGNO (xop[3])) 4733 avr_asm_len ("mov %0,%3", xop, plen, 1); 4734 4735 return ""; 4736 } 4737 4738 4739 const char * 4740 output_movqi (rtx_insn *insn, rtx operands[], int *plen) 4741 { 4742 rtx dest = operands[0]; 4743 rtx src = operands[1]; 4744 4745 if (avr_mem_flash_p (src) 4746 || avr_mem_flash_p (dest)) 4747 { 4748 return avr_out_lpm (insn, operands, plen); 4749 } 4750 4751 gcc_assert (GET_MODE_SIZE (GET_MODE (dest)) == 1); 4752 4753 if (REG_P (dest)) 4754 { 4755 if (REG_P (src)) /* mov r,r */ 4756 { 4757 if (test_hard_reg_class (STACK_REG, dest)) 4758 return avr_asm_len ("out %0,%1", operands, plen, -1); 4759 else if (test_hard_reg_class (STACK_REG, src)) 4760 return avr_asm_len ("in %0,%1", operands, plen, -1); 4761 4762 return avr_asm_len ("mov %0,%1", operands, plen, -1); 4763 } 4764 else if (CONSTANT_P (src)) 4765 { 4766 output_reload_in_const (operands, NULL_RTX, plen, false); 4767 return ""; 4768 } 4769 else if (MEM_P (src)) 4770 return out_movqi_r_mr (insn, operands, plen); /* mov r,m */ 4771 } 4772 else if (MEM_P (dest)) 4773 { 4774 rtx xop[2]; 4775 4776 xop[0] = dest; 4777 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src; 4778 4779 return out_movqi_mr_r (insn, xop, plen); 4780 } 4781 4782 return ""; 4783 } 4784 4785 4786 const char * 4787 output_movhi (rtx_insn *insn, rtx xop[], int *plen) 4788 { 4789 rtx dest = xop[0]; 4790 rtx src = xop[1]; 4791 4792 gcc_assert (GET_MODE_SIZE (GET_MODE (dest)) == 2); 4793 4794 if (avr_mem_flash_p (src) 4795 || avr_mem_flash_p (dest)) 4796 { 4797 return avr_out_lpm (insn, xop, plen); 4798 } 4799 4800 if (REG_P (dest)) 4801 { 4802 if (REG_P (src)) /* mov r,r */ 4803 { 4804 if (test_hard_reg_class (STACK_REG, dest)) 4805 { 4806 if (AVR_HAVE_8BIT_SP) 4807 return avr_asm_len ("out __SP_L__,%A1", xop, plen, -1); 4808 4809 if (AVR_XMEGA) 4810 return avr_asm_len ("out __SP_L__,%A1" CR_TAB 4811 "out __SP_H__,%B1", xop, plen, -2); 4812 4813 /* Use simple load of SP if no interrupts are used. */ 4814 4815 return TARGET_NO_INTERRUPTS 4816 ? avr_asm_len ("out __SP_H__,%B1" CR_TAB 4817 "out __SP_L__,%A1", xop, plen, -2) 4818 : avr_asm_len ("in __tmp_reg__,__SREG__" CR_TAB 4819 "cli" CR_TAB 4820 "out __SP_H__,%B1" CR_TAB 4821 "out __SREG__,__tmp_reg__" CR_TAB 4822 "out __SP_L__,%A1", xop, plen, -5); 4823 } 4824 else if (test_hard_reg_class (STACK_REG, src)) 4825 { 4826 return !AVR_HAVE_SPH 4827 ? avr_asm_len ("in %A0,__SP_L__" CR_TAB 4828 "clr %B0", xop, plen, -2) 4829 4830 : avr_asm_len ("in %A0,__SP_L__" CR_TAB 4831 "in %B0,__SP_H__", xop, plen, -2); 4832 } 4833 4834 return AVR_HAVE_MOVW 4835 ? avr_asm_len ("movw %0,%1", xop, plen, -1) 4836 4837 : avr_asm_len ("mov %A0,%A1" CR_TAB 4838 "mov %B0,%B1", xop, plen, -2); 4839 } /* REG_P (src) */ 4840 else if (CONSTANT_P (src)) 4841 { 4842 return output_reload_inhi (xop, NULL, plen); 4843 } 4844 else if (MEM_P (src)) 4845 { 4846 return out_movhi_r_mr (insn, xop, plen); /* mov r,m */ 4847 } 4848 } 4849 else if (MEM_P (dest)) 4850 { 4851 rtx xop[2]; 4852 4853 xop[0] = dest; 4854 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src; 4855 4856 return out_movhi_mr_r (insn, xop, plen); 4857 } 4858 4859 fatal_insn ("invalid insn:", insn); 4860 4861 return ""; 4862 } 4863 4864 4865 /* Same as out_movqi_r_mr, but TINY does not have ADIW or SBIW */ 4866 4867 static const char * 4868 avr_out_movqi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen) 4869 { 4870 rtx dest = op[0]; 4871 rtx src = op[1]; 4872 rtx x = XEXP (src, 0); 4873 rtx base = XEXP (x, 0); 4874 4875 if (plen) 4876 *plen = 0; 4877 4878 if (!reg_overlap_mentioned_p (dest, base)) 4879 { 4880 avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB 4881 "ld %0,%b1", op, plen, 3); 4882 if (!reg_unused_after (insn, base)) 4883 avr_asm_len (TINY_SBIW (%I1, %J1, %o1), op, plen, 2); 4884 } 4885 else 4886 { 4887 // PR98762: The base register overlaps dest and is only partly clobbered. 4888 rtx base2 = all_regs_rtx[1 ^ REGNO (dest)]; 4889 4890 if (!reg_unused_after (insn, base2)) 4891 avr_asm_len ("mov __tmp_reg__,%0", &base2, plen, 1); 4892 avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB 4893 "ld %0,%b1", op, plen, 3); 4894 if (!reg_unused_after (insn, base2)) 4895 avr_asm_len ("mov %0,__tmp_reg__", &base2, plen, 1); 4896 } 4897 4898 return ""; 4899 } 4900 4901 static const char * 4902 out_movqi_r_mr (rtx_insn *insn, rtx op[], int *plen) 4903 { 4904 rtx dest = op[0]; 4905 rtx src = op[1]; 4906 rtx x = XEXP (src, 0); 4907 4908 if (CONSTANT_ADDRESS_P (x)) 4909 { 4910 int n_words = AVR_TINY ? 1 : 2; 4911 return io_address_operand (x, QImode) 4912 ? avr_asm_len ("in %0,%i1", op, plen, -1) 4913 : avr_asm_len ("lds %0,%m1", op, plen, -n_words); 4914 } 4915 4916 if (GET_CODE (x) == PLUS 4917 && REG_P (XEXP (x, 0)) 4918 && CONST_INT_P (XEXP (x, 1))) 4919 { 4920 /* memory access by reg+disp */ 4921 4922 if (AVR_TINY) 4923 return avr_out_movqi_r_mr_reg_disp_tiny (insn, op, plen); 4924 4925 if (plen) 4926 *plen = 0; 4927 4928 int disp = INTVAL (XEXP (x, 1)); 4929 rtx base = XEXP (x, 0); 4930 rtx base2 = all_regs_rtx[1 ^ REGNO (dest)]; 4931 bool partial_clobber = (reg_overlap_mentioned_p (dest, base) 4932 && ! reg_unused_after (insn, base2)); 4933 4934 if (disp - GET_MODE_SIZE (GET_MODE (src)) >= 63) 4935 { 4936 // PR117744: The base register overlaps dest and is 4937 // only partially clobbered. 4938 if (partial_clobber) 4939 avr_asm_len ("mov __tmp_reg__,%0", &base2, plen, 1); 4940 4941 if (REGNO (XEXP (x, 0)) != REG_Y) 4942 fatal_insn ("incorrect insn:",insn); 4943 4944 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src))) 4945 avr_asm_len ("adiw r28,%o1-63" CR_TAB 4946 "ldd %0,Y+63" CR_TAB 4947 "sbiw r28,%o1-63", op, plen, 3); 4948 else 4949 avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB 4950 "sbci r29,hi8(-%o1)" CR_TAB 4951 "ld %0,Y" CR_TAB 4952 "subi r28,lo8(%o1)" CR_TAB 4953 "sbci r29,hi8(%o1)", op, plen, 5); 4954 4955 if (partial_clobber) 4956 avr_asm_len ("mov __tmp_reg__,%0", &base2, plen, 1); 4957 4958 return ""; 4959 } 4960 else if (REGNO (XEXP (x, 0)) == REG_X) 4961 { 4962 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude 4963 it but I have this situation with extremal optimizing options. */ 4964 4965 // PR117744: The base register overlaps dest and is 4966 // only partially clobbered. 4967 bool clobber_r26 = (partial_clobber 4968 && REGNO (base) == (REGNO (base) & ~1)); 4969 if (partial_clobber 4970 && ! clobber_r26) 4971 avr_asm_len ("mov __tmp_reg__,%0", &base2, plen, 1); 4972 4973 avr_asm_len ("adiw r26,%o1" CR_TAB 4974 "ld %0,X", op, plen, 2); 4975 4976 if (clobber_r26) 4977 avr_asm_len ("subi r26,lo8(%o1)", op, plen, 1); 4978 else if (partial_clobber) 4979 avr_asm_len ("mov %0,__tmp_reg__", &base2, plen, 1); 4980 else if (! reg_unused_after (insn, base)) 4981 avr_asm_len ("sbiw r26,%o1", op, plen, 1); 4982 4983 return ""; 4984 } 4985 4986 return avr_asm_len ("ldd %0,%1", op, plen, -1); 4987 } 4988 4989 return avr_asm_len ("ld %0,%1", op, plen, -1); 4990 } 4991 4992 4993 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */ 4994 4995 static const char * 4996 avr_out_movhi_r_mr_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *plen) 4997 { 4998 rtx dest = op[0]; 4999 rtx src = op[1]; 5000 rtx base = XEXP (src, 0); 5001 5002 int reg_dest = true_regnum (dest); 5003 int reg_base = true_regnum (base); 5004 5005 if (reg_dest == reg_base) /* R = (R) */ 5006 return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB 5007 "ld %B0,%1" CR_TAB 5008 "mov %A0,__tmp_reg__", op, plen, -3); 5009 5010 avr_asm_len ("ld %A0,%1+" CR_TAB 5011 "ld %B0,%1", op, plen, -2); 5012 5013 if (!reg_unused_after (insn, base)) 5014 avr_asm_len (TINY_SBIW (%E1, %F1, 1), op, plen, 2); 5015 5016 return ""; 5017 } 5018 5019 5020 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */ 5021 5022 static const char * 5023 avr_out_movhi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen) 5024 { 5025 rtx dest = op[0]; 5026 rtx src = op[1]; 5027 rtx base = XEXP (src, 0); 5028 5029 int reg_dest = true_regnum (dest); 5030 int reg_base = true_regnum (XEXP (base, 0)); 5031 5032 if (reg_base == reg_dest) 5033 { 5034 return avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB 5035 "ld __tmp_reg__,%b1+" CR_TAB 5036 "ld %B0,%b1" CR_TAB 5037 "mov %A0,__tmp_reg__", op, plen, -5); 5038 } 5039 else 5040 { 5041 avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB 5042 "ld %A0,%b1+" CR_TAB 5043 "ld %B0,%b1", op, plen, -4); 5044 5045 if (!reg_unused_after (insn, XEXP (base, 0))) 5046 avr_asm_len (TINY_SBIW (%I1, %J1, %o1+1), op, plen, 2); 5047 5048 return ""; 5049 } 5050 } 5051 5052 5053 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */ 5054 5055 static const char * 5056 avr_out_movhi_r_mr_pre_dec_tiny (rtx_insn *insn, rtx op[], int *plen) 5057 { 5058 rtx dest = op[0]; 5059 rtx src = op[1]; 5060 rtx base = XEXP (src, 0); 5061 5062 /* "volatile" forces reading low byte first, even if less efficient, 5063 for correct operation with 16-bit I/O registers. */ 5064 bool mem_volatile_p = MEM_VOLATILE_P (src); 5065 5066 if (reg_overlap_mentioned_p (dest, XEXP (base, 0))) 5067 fatal_insn ("incorrect insn:", insn); 5068 5069 if (!mem_volatile_p) 5070 return avr_asm_len ("ld %B0,%1" CR_TAB 5071 "ld %A0,%1", op, plen, -2); 5072 5073 return avr_asm_len (TINY_SBIW (%I1, %J1, 2) CR_TAB 5074 "ld %A0,%p1+" CR_TAB 5075 "ld %B0,%p1" CR_TAB 5076 TINY_SBIW (%I1, %J1, 1), op, plen, -6); 5077 } 5078 5079 5080 static const char * 5081 out_movhi_r_mr (rtx_insn *insn, rtx op[], int *plen) 5082 { 5083 rtx dest = op[0]; 5084 rtx src = op[1]; 5085 rtx base = XEXP (src, 0); 5086 int reg_dest = true_regnum (dest); 5087 int reg_base = true_regnum (base); 5088 /* "volatile" forces reading low byte first, even if less efficient, 5089 for correct operation with 16-bit I/O registers. */ 5090 bool mem_volatile_p = MEM_VOLATILE_P (src); 5091 5092 if (reg_base > 0) 5093 { 5094 if (AVR_TINY) 5095 return avr_out_movhi_r_mr_reg_no_disp_tiny (insn, op, plen); 5096 5097 if (reg_dest == reg_base) /* R = (R) */ 5098 return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB 5099 "ld %B0,%1" CR_TAB 5100 "mov %A0,__tmp_reg__", op, plen, -3); 5101 5102 if (reg_base != REG_X) 5103 return avr_asm_len ("ld %A0,%1" CR_TAB 5104 "ldd %B0,%1+1", op, plen, -2); 5105 5106 avr_asm_len ("ld %A0,X+" CR_TAB 5107 "ld %B0,X", op, plen, -2); 5108 5109 if (!reg_unused_after (insn, base)) 5110 avr_asm_len ("sbiw r26,1", op, plen, 1); 5111 5112 return ""; 5113 } 5114 else if (GET_CODE (base) == PLUS) /* (R + i) */ 5115 { 5116 int disp = INTVAL (XEXP (base, 1)); 5117 int reg_base = true_regnum (XEXP (base, 0)); 5118 5119 if (AVR_TINY) 5120 return avr_out_movhi_r_mr_reg_disp_tiny (insn, op, plen); 5121 5122 if (disp > MAX_LD_OFFSET (GET_MODE (src))) 5123 { 5124 if (REGNO (XEXP (base, 0)) != REG_Y) 5125 fatal_insn ("incorrect insn:",insn); 5126 5127 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)) 5128 ? avr_asm_len ("adiw r28,%o1-62" CR_TAB 5129 "ldd %A0,Y+62" CR_TAB 5130 "ldd %B0,Y+63" CR_TAB 5131 "sbiw r28,%o1-62", op, plen, -4) 5132 5133 : avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB 5134 "sbci r29,hi8(-%o1)" CR_TAB 5135 "ld %A0,Y" CR_TAB 5136 "ldd %B0,Y+1" CR_TAB 5137 "subi r28,lo8(%o1)" CR_TAB 5138 "sbci r29,hi8(%o1)", op, plen, -6); 5139 } 5140 5141 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude 5142 it but I have this situation with extremal 5143 optimization options. */ 5144 5145 if (reg_base == REG_X) 5146 { 5147 if (reg_base == reg_dest) 5148 return avr_asm_len ("adiw r26,%o1" CR_TAB 5149 "ld __tmp_reg__,X+" CR_TAB 5150 "ld %B0,X" CR_TAB 5151 "mov %A0,__tmp_reg__", op, plen, -4); 5152 5153 avr_asm_len ("adiw r26,%o1" CR_TAB 5154 "ld %A0,X+" CR_TAB 5155 "ld %B0,X", op, plen, -3); 5156 5157 if (!reg_unused_after (insn, XEXP (base, 0))) 5158 avr_asm_len ("sbiw r26,%o1+1", op, plen, 1); 5159 5160 return ""; 5161 } 5162 5163 return reg_base == reg_dest 5164 ? avr_asm_len ("ldd __tmp_reg__,%A1" CR_TAB 5165 "ldd %B0,%B1" CR_TAB 5166 "mov %A0,__tmp_reg__", op, plen, -3) 5167 5168 : avr_asm_len ("ldd %A0,%A1" CR_TAB 5169 "ldd %B0,%B1", op, plen, -2); 5170 } 5171 else if (GET_CODE (base) == PRE_DEC) /* (--R) */ 5172 { 5173 if (AVR_TINY) 5174 return avr_out_movhi_r_mr_pre_dec_tiny (insn, op, plen); 5175 5176 if (reg_overlap_mentioned_p (dest, XEXP (base, 0))) 5177 fatal_insn ("incorrect insn:", insn); 5178 5179 if (!mem_volatile_p) 5180 return avr_asm_len ("ld %B0,%1" CR_TAB 5181 "ld %A0,%1", op, plen, -2); 5182 5183 return REGNO (XEXP (base, 0)) == REG_X 5184 ? avr_asm_len ("sbiw r26,2" CR_TAB 5185 "ld %A0,X+" CR_TAB 5186 "ld %B0,X" CR_TAB 5187 "sbiw r26,1", op, plen, -4) 5188 5189 : avr_asm_len ("sbiw %r1,2" CR_TAB 5190 "ld %A0,%p1" CR_TAB 5191 "ldd %B0,%p1+1", op, plen, -3); 5192 } 5193 else if (GET_CODE (base) == POST_INC) /* (R++) */ 5194 { 5195 if (reg_overlap_mentioned_p (dest, XEXP (base, 0))) 5196 fatal_insn ("incorrect insn:", insn); 5197 5198 return avr_asm_len ("ld %A0,%1" CR_TAB 5199 "ld %B0,%1", op, plen, -2); 5200 } 5201 else if (CONSTANT_ADDRESS_P (base)) 5202 { 5203 int n_words = AVR_TINY ? 2 : 4; 5204 return io_address_operand (base, HImode) 5205 ? avr_asm_len ("in %A0,%i1" CR_TAB 5206 "in %B0,%i1+1", op, plen, -2) 5207 5208 : avr_asm_len ("lds %A0,%m1" CR_TAB 5209 "lds %B0,%m1+1", op, plen, -n_words); 5210 } 5211 5212 fatal_insn ("unknown move insn:",insn); 5213 return ""; 5214 } 5215 5216 static const char * 5217 avr_out_movsi_r_mr_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *l) 5218 { 5219 rtx dest = op[0]; 5220 rtx src = op[1]; 5221 rtx base = XEXP (src, 0); 5222 int reg_dest = true_regnum (dest); 5223 int reg_base = true_regnum (base); 5224 5225 if (reg_dest == reg_base) 5226 { 5227 /* "ld r26,-X" is undefined */ 5228 return *l = 9, (TINY_ADIW (%E1, %F1, 3) CR_TAB 5229 "ld %D0,%1" CR_TAB 5230 "ld %C0,-%1" CR_TAB 5231 "ld __tmp_reg__,-%1" CR_TAB 5232 TINY_SBIW (%E1, %F1, 1) CR_TAB 5233 "ld %A0,%1" CR_TAB 5234 "mov %B0,__tmp_reg__"); 5235 } 5236 else if (reg_dest == reg_base - 2) 5237 { 5238 return *l = 5, ("ld %A0,%1+" CR_TAB 5239 "ld %B0,%1+" CR_TAB 5240 "ld __tmp_reg__,%1+" CR_TAB 5241 "ld %D0,%1" CR_TAB 5242 "mov %C0,__tmp_reg__"); 5243 } 5244 else if (reg_unused_after (insn, base)) 5245 { 5246 return *l = 4, ("ld %A0,%1+" CR_TAB 5247 "ld %B0,%1+" CR_TAB 5248 "ld %C0,%1+" CR_TAB 5249 "ld %D0,%1"); 5250 } 5251 else 5252 { 5253 return *l = 6, ("ld %A0,%1+" CR_TAB 5254 "ld %B0,%1+" CR_TAB 5255 "ld %C0,%1+" CR_TAB 5256 "ld %D0,%1" CR_TAB 5257 TINY_SBIW (%E1, %F1, 3)); 5258 } 5259 } 5260 5261 5262 static const char * 5263 avr_out_movsi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *l) 5264 { 5265 rtx dest = op[0]; 5266 rtx src = op[1]; 5267 rtx base = XEXP (src, 0); 5268 int reg_dest = true_regnum (dest); 5269 int reg_base = true_regnum (XEXP (base, 0)); 5270 5271 if (reg_dest == reg_base) 5272 { 5273 /* "ld r26,-X" is undefined */ 5274 return *l = 9, (TINY_ADIW (%I1, %J1, %o1+3) CR_TAB 5275 "ld %D0,%b1" CR_TAB 5276 "ld %C0,-%b1" CR_TAB 5277 "ld __tmp_reg__,-%b1" CR_TAB 5278 TINY_SBIW (%I1, %J1, 1) CR_TAB 5279 "ld %A0,%b1" CR_TAB 5280 "mov %B0,__tmp_reg__"); 5281 } 5282 else if (reg_dest == reg_base - 2) 5283 { 5284 return *l = 7, (TINY_ADIW (%I1, %J1, %o1) CR_TAB 5285 "ld %A0,%b1+" CR_TAB 5286 "ld %B0,%b1+" CR_TAB 5287 "ld __tmp_reg__,%b1+" CR_TAB 5288 "ld %D0,%b1" CR_TAB 5289 "mov %C0,__tmp_reg__"); 5290 } 5291 else if (reg_unused_after (insn, XEXP (base, 0))) 5292 { 5293 return *l = 6, (TINY_ADIW (%I1, %J1, %o1) CR_TAB 5294 "ld %A0,%b1+" CR_TAB 5295 "ld %B0,%b1+" CR_TAB 5296 "ld %C0,%b1+" CR_TAB 5297 "ld %D0,%b1"); 5298 } 5299 else 5300 { 5301 return *l = 8, (TINY_ADIW (%I1, %J1, %o1) CR_TAB 5302 "ld %A0,%b1+" CR_TAB 5303 "ld %B0,%b1+" CR_TAB 5304 "ld %C0,%b1+" CR_TAB 5305 "ld %D0,%b1" CR_TAB 5306 TINY_SBIW (%I1, %J1, %o1+3)); 5307 } 5308 } 5309 5310 static const char * 5311 out_movsi_r_mr (rtx_insn *insn, rtx op[], int *l) 5312 { 5313 rtx dest = op[0]; 5314 rtx src = op[1]; 5315 rtx base = XEXP (src, 0); 5316 int reg_dest = true_regnum (dest); 5317 int reg_base = true_regnum (base); 5318 int tmp; 5319 5320 if (!l) 5321 l = &tmp; 5322 5323 if (reg_base > 0) 5324 { 5325 if (AVR_TINY) 5326 return avr_out_movsi_r_mr_reg_no_disp_tiny (insn, op, l); 5327 5328 if (reg_base == REG_X) /* (R26) */ 5329 { 5330 if (reg_dest == REG_X) 5331 /* "ld r26,-X" is undefined */ 5332 return *l=7, ("adiw r26,3" CR_TAB 5333 "ld r29,X" CR_TAB 5334 "ld r28,-X" CR_TAB 5335 "ld __tmp_reg__,-X" CR_TAB 5336 "sbiw r26,1" CR_TAB 5337 "ld r26,X" CR_TAB 5338 "mov r27,__tmp_reg__"); 5339 else if (reg_dest == REG_X - 2) 5340 return *l=5, ("ld %A0,X+" CR_TAB 5341 "ld %B0,X+" CR_TAB 5342 "ld __tmp_reg__,X+" CR_TAB 5343 "ld %D0,X" CR_TAB 5344 "mov %C0,__tmp_reg__"); 5345 else if (reg_unused_after (insn, base)) 5346 return *l=4, ("ld %A0,X+" CR_TAB 5347 "ld %B0,X+" CR_TAB 5348 "ld %C0,X+" CR_TAB 5349 "ld %D0,X"); 5350 else 5351 return *l=5, ("ld %A0,X+" CR_TAB 5352 "ld %B0,X+" CR_TAB 5353 "ld %C0,X+" CR_TAB 5354 "ld %D0,X" CR_TAB 5355 "sbiw r26,3"); 5356 } 5357 else 5358 { 5359 if (reg_dest == reg_base) 5360 return *l=5, ("ldd %D0,%1+3" CR_TAB 5361 "ldd %C0,%1+2" CR_TAB 5362 "ldd __tmp_reg__,%1+1" CR_TAB 5363 "ld %A0,%1" CR_TAB 5364 "mov %B0,__tmp_reg__"); 5365 else if (reg_base == reg_dest + 2) 5366 return *l=5, ("ld %A0,%1" CR_TAB 5367 "ldd %B0,%1+1" CR_TAB 5368 "ldd __tmp_reg__,%1+2" CR_TAB 5369 "ldd %D0,%1+3" CR_TAB 5370 "mov %C0,__tmp_reg__"); 5371 else 5372 return *l=4, ("ld %A0,%1" CR_TAB 5373 "ldd %B0,%1+1" CR_TAB 5374 "ldd %C0,%1+2" CR_TAB 5375 "ldd %D0,%1+3"); 5376 } 5377 } 5378 else if (GET_CODE (base) == PLUS) /* (R + i) */ 5379 { 5380 int disp = INTVAL (XEXP (base, 1)); 5381 5382 if (AVR_TINY) 5383 return avr_out_movsi_r_mr_reg_disp_tiny (insn, op, l); 5384 5385 if (disp > MAX_LD_OFFSET (GET_MODE (src))) 5386 { 5387 if (REGNO (XEXP (base, 0)) != REG_Y) 5388 fatal_insn ("incorrect insn:",insn); 5389 5390 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src))) 5391 return *l = 6, ("adiw r28,%o1-60" CR_TAB 5392 "ldd %A0,Y+60" CR_TAB 5393 "ldd %B0,Y+61" CR_TAB 5394 "ldd %C0,Y+62" CR_TAB 5395 "ldd %D0,Y+63" CR_TAB 5396 "sbiw r28,%o1-60"); 5397 5398 return *l = 8, ("subi r28,lo8(-%o1)" CR_TAB 5399 "sbci r29,hi8(-%o1)" CR_TAB 5400 "ld %A0,Y" CR_TAB 5401 "ldd %B0,Y+1" CR_TAB 5402 "ldd %C0,Y+2" CR_TAB 5403 "ldd %D0,Y+3" CR_TAB 5404 "subi r28,lo8(%o1)" CR_TAB 5405 "sbci r29,hi8(%o1)"); 5406 } 5407 5408 reg_base = true_regnum (XEXP (base, 0)); 5409 if (reg_base == REG_X) 5410 { 5411 /* R = (X + d) */ 5412 if (reg_dest == REG_X) 5413 { 5414 *l = 7; 5415 /* "ld r26,-X" is undefined */ 5416 return ("adiw r26,%o1+3" CR_TAB 5417 "ld r29,X" CR_TAB 5418 "ld r28,-X" CR_TAB 5419 "ld __tmp_reg__,-X" CR_TAB 5420 "sbiw r26,1" CR_TAB 5421 "ld r26,X" CR_TAB 5422 "mov r27,__tmp_reg__"); 5423 } 5424 *l = 6; 5425 if (reg_dest == REG_X - 2) 5426 return ("adiw r26,%o1" CR_TAB 5427 "ld r24,X+" CR_TAB 5428 "ld r25,X+" CR_TAB 5429 "ld __tmp_reg__,X+" CR_TAB 5430 "ld r27,X" CR_TAB 5431 "mov r26,__tmp_reg__"); 5432 5433 return ("adiw r26,%o1" CR_TAB 5434 "ld %A0,X+" CR_TAB 5435 "ld %B0,X+" CR_TAB 5436 "ld %C0,X+" CR_TAB 5437 "ld %D0,X" CR_TAB 5438 "sbiw r26,%o1+3"); 5439 } 5440 if (reg_dest == reg_base) 5441 return *l=5, ("ldd %D0,%D1" CR_TAB 5442 "ldd %C0,%C1" CR_TAB 5443 "ldd __tmp_reg__,%B1" CR_TAB 5444 "ldd %A0,%A1" CR_TAB 5445 "mov %B0,__tmp_reg__"); 5446 else if (reg_dest == reg_base - 2) 5447 return *l=5, ("ldd %A0,%A1" CR_TAB 5448 "ldd %B0,%B1" CR_TAB 5449 "ldd __tmp_reg__,%C1" CR_TAB 5450 "ldd %D0,%D1" CR_TAB 5451 "mov %C0,__tmp_reg__"); 5452 return *l=4, ("ldd %A0,%A1" CR_TAB 5453 "ldd %B0,%B1" CR_TAB 5454 "ldd %C0,%C1" CR_TAB 5455 "ldd %D0,%D1"); 5456 } 5457 else if (GET_CODE (base) == PRE_DEC) /* (--R) */ 5458 return *l=4, ("ld %D0,%1" CR_TAB 5459 "ld %C0,%1" CR_TAB 5460 "ld %B0,%1" CR_TAB 5461 "ld %A0,%1"); 5462 else if (GET_CODE (base) == POST_INC) /* (R++) */ 5463 return *l=4, ("ld %A0,%1" CR_TAB 5464 "ld %B0,%1" CR_TAB 5465 "ld %C0,%1" CR_TAB 5466 "ld %D0,%1"); 5467 else if (CONSTANT_ADDRESS_P (base)) 5468 { 5469 if (io_address_operand (base, SImode)) 5470 { 5471 *l = 4; 5472 return ("in %A0,%i1" CR_TAB 5473 "in %B0,%i1+1" CR_TAB 5474 "in %C0,%i1+2" CR_TAB 5475 "in %D0,%i1+3"); 5476 } 5477 else 5478 { 5479 *l = AVR_TINY ? 4 : 8; 5480 return ("lds %A0,%m1" CR_TAB 5481 "lds %B0,%m1+1" CR_TAB 5482 "lds %C0,%m1+2" CR_TAB 5483 "lds %D0,%m1+3"); 5484 } 5485 } 5486 5487 fatal_insn ("unknown move insn:",insn); 5488 return ""; 5489 } 5490 5491 static const char * 5492 avr_out_movsi_mr_r_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *l) 5493 { 5494 rtx dest = op[0]; 5495 rtx src = op[1]; 5496 rtx base = XEXP (dest, 0); 5497 int reg_base = true_regnum (base); 5498 int reg_src = true_regnum (src); 5499 5500 if (reg_base == reg_src) 5501 { 5502 /* "ld r26,-X" is undefined */ 5503 if (reg_unused_after (insn, base)) 5504 { 5505 return *l = 7, ("mov __tmp_reg__, %B1" CR_TAB 5506 "st %0,%A1" CR_TAB 5507 TINY_ADIW (%E0, %F0, 1) CR_TAB 5508 "st %0+,__tmp_reg__" CR_TAB 5509 "st %0+,%C1" CR_TAB 5510 "st %0+,%D1"); 5511 } 5512 else 5513 { 5514 return *l = 9, ("mov __tmp_reg__, %B1" CR_TAB 5515 "st %0,%A1" CR_TAB 5516 TINY_ADIW (%E0, %F0, 1) CR_TAB 5517 "st %0+,__tmp_reg__" CR_TAB 5518 "st %0+,%C1" CR_TAB 5519 "st %0+,%D1" CR_TAB 5520 TINY_SBIW (%E0, %F0, 3)); 5521 } 5522 } 5523 else if (reg_base == reg_src + 2) 5524 { 5525 if (reg_unused_after (insn, base)) 5526 return *l = 7, ("mov __zero_reg__,%C1" CR_TAB 5527 "mov __tmp_reg__,%D1" CR_TAB 5528 "st %0+,%A1" CR_TAB 5529 "st %0+,%B1" CR_TAB 5530 "st %0+,__zero_reg__" CR_TAB 5531 "st %0,__tmp_reg__" CR_TAB 5532 "clr __zero_reg__"); 5533 else 5534 return *l = 9, ("mov __zero_reg__,%C1" CR_TAB 5535 "mov __tmp_reg__,%D1" CR_TAB 5536 "st %0+,%A1" CR_TAB 5537 "st %0+,%B1" CR_TAB 5538 "st %0+,__zero_reg__" CR_TAB 5539 "st %0,__tmp_reg__" CR_TAB 5540 "clr __zero_reg__" CR_TAB 5541 TINY_SBIW (%E0, %F0, 3)); 5542 } 5543 5544 return *l = 6, ("st %0+,%A1" CR_TAB 5545 "st %0+,%B1" CR_TAB 5546 "st %0+,%C1" CR_TAB 5547 "st %0,%D1" CR_TAB 5548 TINY_SBIW (%E0, %F0, 3)); 5549 } 5550 5551 static const char * 5552 avr_out_movsi_mr_r_reg_disp_tiny (rtx op[], int *l) 5553 { 5554 rtx dest = op[0]; 5555 rtx src = op[1]; 5556 rtx base = XEXP (dest, 0); 5557 int reg_base = REGNO (XEXP (base, 0)); 5558 int reg_src = true_regnum (src); 5559 5560 if (reg_base == reg_src) 5561 { 5562 *l = 11; 5563 return ("mov __tmp_reg__,%A1" CR_TAB 5564 "mov __zero_reg__,%B1" CR_TAB 5565 TINY_ADIW (%I0, %J0, %o0) CR_TAB 5566 "st %b0+,__tmp_reg__" CR_TAB 5567 "st %b0+,__zero_reg__" CR_TAB 5568 "st %b0+,%C1" CR_TAB 5569 "st %b0,%D1" CR_TAB 5570 "clr __zero_reg__" CR_TAB 5571 TINY_SBIW (%I0, %J0, %o0+3)); 5572 } 5573 else if (reg_src == reg_base - 2) 5574 { 5575 // This awkward case can occur when ext-dce turns zero-extend:SI(HI) 5576 // into a paradoxical subreg, which register allocation may turn into 5577 // something like *(R28:HI + 7) = R26:SI. There is actually no need 5578 // to store the upper 2 bytes of R26:SI as they are unused rubbish. 5579 // See PR116390. 5580 *l = 6; 5581 return (TINY_ADIW (%I0, %J0, %o0) CR_TAB 5582 "st %b0+,%A1" CR_TAB 5583 "st %b0,%B1" CR_TAB 5584 TINY_SBIW (%I0, %J0, %o0+1)); 5585 } 5586 *l = 8; 5587 return (TINY_ADIW (%I0, %J0, %o0) CR_TAB 5588 "st %b0+,%A1" CR_TAB 5589 "st %b0+,%B1" CR_TAB 5590 "st %b0+,%C1" CR_TAB 5591 "st %b0,%D1" CR_TAB 5592 TINY_SBIW (%I0, %J0, %o0+3)); 5593 } 5594 5595 static const char * 5596 out_movsi_mr_r (rtx_insn *insn, rtx op[], int *l) 5597 { 5598 rtx dest = op[0]; 5599 rtx src = op[1]; 5600 rtx base = XEXP (dest, 0); 5601 int reg_base = true_regnum (base); 5602 int reg_src = true_regnum (src); 5603 int tmp; 5604 5605 if (!l) 5606 l = &tmp; 5607 5608 if (CONSTANT_ADDRESS_P (base)) 5609 { 5610 if (io_address_operand (base, SImode)) 5611 { 5612 return *l=4,("out %i0, %A1" CR_TAB 5613 "out %i0+1,%B1" CR_TAB 5614 "out %i0+2,%C1" CR_TAB 5615 "out %i0+3,%D1"); 5616 } 5617 else 5618 { 5619 *l = AVR_TINY ? 4 : 8; 5620 return ("sts %m0,%A1" CR_TAB 5621 "sts %m0+1,%B1" CR_TAB 5622 "sts %m0+2,%C1" CR_TAB 5623 "sts %m0+3,%D1"); 5624 } 5625 } 5626 5627 if (reg_base > 0) /* (r) */ 5628 { 5629 if (AVR_TINY) 5630 return avr_out_movsi_mr_r_reg_no_disp_tiny (insn, op, l); 5631 5632 if (reg_base == REG_X) /* (R26) */ 5633 { 5634 if (reg_src == REG_X) 5635 { 5636 /* "st X+,r26" is undefined */ 5637 if (reg_unused_after (insn, base)) 5638 return *l=6, ("mov __tmp_reg__,r27" CR_TAB 5639 "st X,r26" CR_TAB 5640 "adiw r26,1" CR_TAB 5641 "st X+,__tmp_reg__" CR_TAB 5642 "st X+,r28" CR_TAB 5643 "st X,r29"); 5644 else 5645 return *l=7, ("mov __tmp_reg__,r27" CR_TAB 5646 "st X,r26" CR_TAB 5647 "adiw r26,1" CR_TAB 5648 "st X+,__tmp_reg__" CR_TAB 5649 "st X+,r28" CR_TAB 5650 "st X,r29" CR_TAB 5651 "sbiw r26,3"); 5652 } 5653 else if (reg_base == reg_src + 2) 5654 { 5655 if (reg_unused_after (insn, base)) 5656 return *l=7, ("mov __zero_reg__,%C1" CR_TAB 5657 "mov __tmp_reg__,%D1" CR_TAB 5658 "st %0+,%A1" CR_TAB 5659 "st %0+,%B1" CR_TAB 5660 "st %0+,__zero_reg__" CR_TAB 5661 "st %0,__tmp_reg__" CR_TAB 5662 "clr __zero_reg__"); 5663 else 5664 return *l=8, ("mov __zero_reg__,%C1" CR_TAB 5665 "mov __tmp_reg__,%D1" CR_TAB 5666 "st %0+,%A1" CR_TAB 5667 "st %0+,%B1" CR_TAB 5668 "st %0+,__zero_reg__" CR_TAB 5669 "st %0,__tmp_reg__" CR_TAB 5670 "clr __zero_reg__" CR_TAB 5671 "sbiw r26,3"); 5672 } 5673 return *l=5, ("st %0+,%A1" CR_TAB 5674 "st %0+,%B1" CR_TAB 5675 "st %0+,%C1" CR_TAB 5676 "st %0,%D1" CR_TAB 5677 "sbiw r26,3"); 5678 } 5679 else 5680 return *l=4, ("st %0,%A1" CR_TAB 5681 "std %0+1,%B1" CR_TAB 5682 "std %0+2,%C1" CR_TAB 5683 "std %0+3,%D1"); 5684 } 5685 else if (GET_CODE (base) == PLUS) /* (R + i) */ 5686 { 5687 int disp = INTVAL (XEXP (base, 1)); 5688 5689 if (AVR_TINY) 5690 return avr_out_movsi_mr_r_reg_disp_tiny (op, l); 5691 5692 reg_base = REGNO (XEXP (base, 0)); 5693 if (disp > MAX_LD_OFFSET (GET_MODE (dest))) 5694 { 5695 if (reg_base != REG_Y) 5696 fatal_insn ("incorrect insn:",insn); 5697 5698 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))) 5699 return *l = 6, ("adiw r28,%o0-60" CR_TAB 5700 "std Y+60,%A1" CR_TAB 5701 "std Y+61,%B1" CR_TAB 5702 "std Y+62,%C1" CR_TAB 5703 "std Y+63,%D1" CR_TAB 5704 "sbiw r28,%o0-60"); 5705 5706 return *l = 8, ("subi r28,lo8(-%o0)" CR_TAB 5707 "sbci r29,hi8(-%o0)" CR_TAB 5708 "st Y,%A1" CR_TAB 5709 "std Y+1,%B1" CR_TAB 5710 "std Y+2,%C1" CR_TAB 5711 "std Y+3,%D1" CR_TAB 5712 "subi r28,lo8(%o0)" CR_TAB 5713 "sbci r29,hi8(%o0)"); 5714 } 5715 if (reg_base == REG_X) 5716 { 5717 /* (X + d) = R */ 5718 if (reg_src == REG_X) 5719 { 5720 *l = 9; 5721 return ("mov __tmp_reg__,r26" CR_TAB 5722 "mov __zero_reg__,r27" CR_TAB 5723 "adiw r26,%o0" CR_TAB 5724 "st X+,__tmp_reg__" CR_TAB 5725 "st X+,__zero_reg__" CR_TAB 5726 "st X+,r28" CR_TAB 5727 "st X,r29" CR_TAB 5728 "clr __zero_reg__" CR_TAB 5729 "sbiw r26,%o0+3"); 5730 } 5731 else if (reg_src == REG_X - 2) 5732 { 5733 *l = 9; 5734 return ("mov __tmp_reg__,r26" CR_TAB 5735 "mov __zero_reg__,r27" CR_TAB 5736 "adiw r26,%o0" CR_TAB 5737 "st X+,r24" CR_TAB 5738 "st X+,r25" CR_TAB 5739 "st X+,__tmp_reg__" CR_TAB 5740 "st X,__zero_reg__" CR_TAB 5741 "clr __zero_reg__" CR_TAB 5742 "sbiw r26,%o0+3"); 5743 } 5744 *l = 6; 5745 return ("adiw r26,%o0" CR_TAB 5746 "st X+,%A1" CR_TAB 5747 "st X+,%B1" CR_TAB 5748 "st X+,%C1" CR_TAB 5749 "st X,%D1" CR_TAB 5750 "sbiw r26,%o0+3"); 5751 } 5752 return *l=4, ("std %A0,%A1" CR_TAB 5753 "std %B0,%B1" CR_TAB 5754 "std %C0,%C1" CR_TAB 5755 "std %D0,%D1"); 5756 } 5757 else if (GET_CODE (base) == PRE_DEC) /* (--R) */ 5758 return *l=4, ("st %0,%D1" CR_TAB 5759 "st %0,%C1" CR_TAB 5760 "st %0,%B1" CR_TAB 5761 "st %0,%A1"); 5762 else if (GET_CODE (base) == POST_INC) /* (R++) */ 5763 return *l=4, ("st %0,%A1" CR_TAB 5764 "st %0,%B1" CR_TAB 5765 "st %0,%C1" CR_TAB 5766 "st %0,%D1"); 5767 fatal_insn ("unknown move insn:",insn); 5768 return ""; 5769 } 5770 5771 const char * 5772 output_movsisf (rtx_insn *insn, rtx operands[], int *l) 5773 { 5774 int dummy; 5775 rtx dest = operands[0]; 5776 rtx src = operands[1]; 5777 int *real_l = l; 5778 5779 if (avr_mem_flash_p (src) 5780 || avr_mem_flash_p (dest)) 5781 { 5782 return avr_out_lpm (insn, operands, real_l); 5783 } 5784 5785 if (!l) 5786 l = &dummy; 5787 5788 gcc_assert (GET_MODE_SIZE (GET_MODE (dest)) == 4); 5789 5790 if (REG_P (dest)) 5791 { 5792 if (REG_P (src)) /* mov r,r */ 5793 { 5794 if (true_regnum (dest) > true_regnum (src)) 5795 { 5796 if (AVR_HAVE_MOVW) 5797 { 5798 *l = 2; 5799 return ("movw %C0,%C1" CR_TAB 5800 "movw %A0,%A1"); 5801 } 5802 *l = 4; 5803 return ("mov %D0,%D1" CR_TAB 5804 "mov %C0,%C1" CR_TAB 5805 "mov %B0,%B1" CR_TAB 5806 "mov %A0,%A1"); 5807 } 5808 else 5809 { 5810 if (AVR_HAVE_MOVW) 5811 { 5812 *l = 2; 5813 return ("movw %A0,%A1" CR_TAB 5814 "movw %C0,%C1"); 5815 } 5816 *l = 4; 5817 return ("mov %A0,%A1" CR_TAB 5818 "mov %B0,%B1" CR_TAB 5819 "mov %C0,%C1" CR_TAB 5820 "mov %D0,%D1"); 5821 } 5822 } 5823 else if (CONSTANT_P (src)) 5824 { 5825 return output_reload_insisf (operands, NULL_RTX, real_l); 5826 } 5827 else if (MEM_P (src)) 5828 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */ 5829 } 5830 else if (MEM_P (dest)) 5831 { 5832 const char *templ; 5833 5834 if (src == CONST0_RTX (GET_MODE (dest))) 5835 operands[1] = zero_reg_rtx; 5836 5837 templ = out_movsi_mr_r (insn, operands, real_l); 5838 5839 if (!real_l) 5840 output_asm_insn (templ, operands); 5841 5842 operands[1] = src; 5843 return ""; 5844 } 5845 fatal_insn ("invalid insn:", insn); 5846 return ""; 5847 } 5848 5849 5850 /* Handle loads of 24-bit types from memory to register. */ 5851 5852 static const char * 5853 avr_out_load_psi_reg_no_disp_tiny (rtx_insn *insn, rtx *op, int *plen) 5854 { 5855 rtx dest = op[0]; 5856 rtx src = op[1]; 5857 rtx base = XEXP (src, 0); 5858 int reg_dest = true_regnum (dest); 5859 int reg_base = true_regnum (base); 5860 5861 if (reg_base == reg_dest) 5862 { 5863 return avr_asm_len (TINY_ADIW (%E1, %F1, 2) CR_TAB 5864 "ld %C0,%1" CR_TAB 5865 "ld __tmp_reg__,-%1" CR_TAB 5866 TINY_SBIW (%E1, %F1, 1) CR_TAB 5867 "ld %A0,%1" CR_TAB 5868 "mov %B0,__tmp_reg__", op, plen, -8); 5869 } 5870 else 5871 { 5872 avr_asm_len ("ld %A0,%1+" CR_TAB 5873 "ld %B0,%1+" CR_TAB 5874 "ld %C0,%1", op, plen, -3); 5875 5876 if (reg_dest != reg_base - 2 5877 && !reg_unused_after (insn, base)) 5878 { 5879 avr_asm_len (TINY_SBIW (%E1, %F1, 2), op, plen, 2); 5880 } 5881 return ""; 5882 } 5883 } 5884 5885 static const char * 5886 avr_out_load_psi_reg_disp_tiny (rtx_insn *insn, rtx *op, int *plen) 5887 { 5888 rtx dest = op[0]; 5889 rtx src = op[1]; 5890 rtx base = XEXP (src, 0); 5891 int reg_dest = true_regnum (dest); 5892 int reg_base = true_regnum (base); 5893 5894 reg_base = true_regnum (XEXP (base, 0)); 5895 if (reg_base == reg_dest) 5896 { 5897 return avr_asm_len (TINY_ADIW (%I1, %J1, %o1+2) CR_TAB 5898 "ld %C0,%b1" CR_TAB 5899 "ld __tmp_reg__,-%b1" CR_TAB 5900 TINY_SBIW (%I1, %J1, 1) CR_TAB 5901 "ld %A0,%b1" CR_TAB 5902 "mov %B0,__tmp_reg__", op, plen, -8); 5903 } 5904 else 5905 { 5906 avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB 5907 "ld %A0,%b1+" CR_TAB 5908 "ld %B0,%b1+" CR_TAB 5909 "ld %C0,%b1", op, plen, -5); 5910 5911 if (reg_dest != reg_base - 2 5912 && !reg_unused_after (insn, XEXP (base, 0))) 5913 avr_asm_len (TINY_SBIW (%I1, %J1, %o1+2), op, plen, 2); 5914 5915 return ""; 5916 } 5917 } 5918 5919 static const char * 5920 avr_out_load_psi (rtx_insn *insn, rtx *op, int *plen) 5921 { 5922 rtx dest = op[0]; 5923 rtx src = op[1]; 5924 rtx base = XEXP (src, 0); 5925 int reg_dest = true_regnum (dest); 5926 int reg_base = true_regnum (base); 5927 5928 if (reg_base > 0) 5929 { 5930 if (AVR_TINY) 5931 return avr_out_load_psi_reg_no_disp_tiny (insn, op, plen); 5932 5933 if (reg_base == REG_X) /* (R26) */ 5934 { 5935 if (reg_dest == REG_X) 5936 /* "ld r26,-X" is undefined */ 5937 return avr_asm_len ("adiw r26,2" CR_TAB 5938 "ld r28,X" CR_TAB 5939 "ld __tmp_reg__,-X" CR_TAB 5940 "sbiw r26,1" CR_TAB 5941 "ld r26,X" CR_TAB 5942 "mov r27,__tmp_reg__", op, plen, -6); 5943 else 5944 { 5945 avr_asm_len ("ld %A0,X+" CR_TAB 5946 "ld %B0,X+" CR_TAB 5947 "ld %C0,X", op, plen, -3); 5948 5949 if (reg_dest != REG_X - 2 5950 && !reg_unused_after (insn, base)) 5951 { 5952 avr_asm_len ("sbiw r26,2", op, plen, 1); 5953 } 5954 5955 return ""; 5956 } 5957 } 5958 else /* reg_base != REG_X */ 5959 { 5960 if (reg_dest == reg_base) 5961 return avr_asm_len ("ldd %C0,%1+2" CR_TAB 5962 "ldd __tmp_reg__,%1+1" CR_TAB 5963 "ld %A0,%1" CR_TAB 5964 "mov %B0,__tmp_reg__", op, plen, -4); 5965 else 5966 return avr_asm_len ("ld %A0,%1" CR_TAB 5967 "ldd %B0,%1+1" CR_TAB 5968 "ldd %C0,%1+2", op, plen, -3); 5969 } 5970 } 5971 else if (GET_CODE (base) == PLUS) /* (R + i) */ 5972 { 5973 int disp = INTVAL (XEXP (base, 1)); 5974 5975 if (AVR_TINY) 5976 return avr_out_load_psi_reg_disp_tiny (insn, op, plen); 5977 5978 if (disp > MAX_LD_OFFSET (GET_MODE (src))) 5979 { 5980 if (REGNO (XEXP (base, 0)) != REG_Y) 5981 fatal_insn ("incorrect insn:",insn); 5982 5983 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src))) 5984 return avr_asm_len ("adiw r28,%o1-61" CR_TAB 5985 "ldd %A0,Y+61" CR_TAB 5986 "ldd %B0,Y+62" CR_TAB 5987 "ldd %C0,Y+63" CR_TAB 5988 "sbiw r28,%o1-61", op, plen, -5); 5989 5990 return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB 5991 "sbci r29,hi8(-%o1)" CR_TAB 5992 "ld %A0,Y" CR_TAB 5993 "ldd %B0,Y+1" CR_TAB 5994 "ldd %C0,Y+2" CR_TAB 5995 "subi r28,lo8(%o1)" CR_TAB 5996 "sbci r29,hi8(%o1)", op, plen, -7); 5997 } 5998 5999 reg_base = true_regnum (XEXP (base, 0)); 6000 if (reg_base == REG_X) 6001 { 6002 /* R = (X + d) */ 6003 if (reg_dest == REG_X) 6004 { 6005 /* "ld r26,-X" is undefined */ 6006 return avr_asm_len ("adiw r26,%o1+2" CR_TAB 6007 "ld r28,X" CR_TAB 6008 "ld __tmp_reg__,-X" CR_TAB 6009 "sbiw r26,1" CR_TAB 6010 "ld r26,X" CR_TAB 6011 "mov r27,__tmp_reg__", op, plen, -6); 6012 } 6013 6014 avr_asm_len ("adiw r26,%o1" CR_TAB 6015 "ld %A0,X+" CR_TAB 6016 "ld %B0,X+" CR_TAB 6017 "ld %C0,X", op, plen, -4); 6018 6019 if (reg_dest != REG_W 6020 && !reg_unused_after (insn, XEXP (base, 0))) 6021 avr_asm_len ("sbiw r26,%o1+2", op, plen, 1); 6022 6023 return ""; 6024 } 6025 6026 if (reg_dest == reg_base) 6027 return avr_asm_len ("ldd %C0,%C1" CR_TAB 6028 "ldd __tmp_reg__,%B1" CR_TAB 6029 "ldd %A0,%A1" CR_TAB 6030 "mov %B0,__tmp_reg__", op, plen, -4); 6031 6032 return avr_asm_len ("ldd %A0,%A1" CR_TAB 6033 "ldd %B0,%B1" CR_TAB 6034 "ldd %C0,%C1", op, plen, -3); 6035 } 6036 else if (GET_CODE (base) == PRE_DEC) /* (--R) */ 6037 return avr_asm_len ("ld %C0,%1" CR_TAB 6038 "ld %B0,%1" CR_TAB 6039 "ld %A0,%1", op, plen, -3); 6040 else if (GET_CODE (base) == POST_INC) /* (R++) */ 6041 return avr_asm_len ("ld %A0,%1" CR_TAB 6042 "ld %B0,%1" CR_TAB 6043 "ld %C0,%1", op, plen, -3); 6044 6045 else if (CONSTANT_ADDRESS_P (base)) 6046 { 6047 int n_words = AVR_TINY ? 3 : 6; 6048 return avr_asm_len ("lds %A0,%m1" CR_TAB 6049 "lds %B0,%m1+1" CR_TAB 6050 "lds %C0,%m1+2", op, plen , -n_words); 6051 } 6052 6053 fatal_insn ("unknown move insn:",insn); 6054 return ""; 6055 } 6056 6057 6058 static const char * 6059 avr_out_store_psi_reg_no_disp_tiny (rtx_insn *insn, rtx *op, int *plen) 6060 { 6061 rtx dest = op[0]; 6062 rtx src = op[1]; 6063 rtx base = XEXP (dest, 0); 6064 int reg_base = true_regnum (base); 6065 int reg_src = true_regnum (src); 6066 6067 if (reg_base == reg_src) 6068 { 6069 avr_asm_len ("st %0,%A1" CR_TAB 6070 "mov __tmp_reg__,%B1" CR_TAB 6071 TINY_ADIW (%E0, %F0, 1) CR_TAB /* st X+, r27 is undefined */ 6072 "st %0+,__tmp_reg__" CR_TAB 6073 "st %0,%C1", op, plen, -6); 6074 6075 } 6076 else if (reg_src == reg_base - 2) 6077 { 6078 avr_asm_len ("st %0,%A1" CR_TAB 6079 "mov __tmp_reg__,%C1" CR_TAB 6080 TINY_ADIW (%E0, %F0, 1) CR_TAB 6081 "st %0+,%B1" CR_TAB 6082 "st %0,__tmp_reg__", op, plen, 6); 6083 } 6084 else 6085 { 6086 avr_asm_len ("st %0+,%A1" CR_TAB 6087 "st %0+,%B1" CR_TAB 6088 "st %0,%C1", op, plen, -3); 6089 } 6090 6091 if (!reg_unused_after (insn, base)) 6092 avr_asm_len (TINY_SBIW (%E0, %F0, 2), op, plen, 2); 6093 6094 return ""; 6095 } 6096 6097 static const char * 6098 avr_out_store_psi_reg_disp_tiny (rtx_insn *insn, rtx *op, int *plen) 6099 { 6100 rtx dest = op[0]; 6101 rtx src = op[1]; 6102 rtx base = XEXP (dest, 0); 6103 int reg_base = REGNO (XEXP (base, 0)); 6104 int reg_src = true_regnum (src); 6105 6106 if (reg_src == reg_base) 6107 avr_asm_len ("mov __tmp_reg__,%A1" CR_TAB 6108 "mov __zero_reg__,%B1" CR_TAB 6109 TINY_ADIW (%I0, %J0, %o0) CR_TAB 6110 "st %b0+,__tmp_reg__" CR_TAB 6111 "st %b0+,__zero_reg__" CR_TAB 6112 "st %b0,%C1" CR_TAB 6113 "clr __zero_reg__", op, plen, -8); 6114 else if (reg_src == reg_base - 2) 6115 avr_asm_len ("mov __tmp_reg__,%C1" CR_TAB 6116 TINY_ADIW (%I0, %J0, %o0) CR_TAB 6117 "st %b0+,%A1" CR_TAB 6118 "st %b0+,%B1" CR_TAB 6119 "st %b0,__tmp_reg__", op, plen, -6); 6120 else 6121 avr_asm_len (TINY_ADIW (%I0, %J0, %o0) CR_TAB 6122 "st %b0+,%A1" CR_TAB 6123 "st %b0+,%B1" CR_TAB 6124 "st %b0,%C1", op, plen, -5); 6125 6126 if (!reg_unused_after (insn, XEXP (base, 0))) 6127 avr_asm_len (TINY_SBIW (%I0, %J0, %o0+2), op, plen, 2); 6128 6129 return ""; 6130 } 6131 6132 /* Handle store of 24-bit type from register or zero to memory. */ 6133 6134 static const char * 6135 avr_out_store_psi (rtx_insn *insn, rtx *op, int *plen) 6136 { 6137 rtx dest = op[0]; 6138 rtx src = op[1]; 6139 rtx base = XEXP (dest, 0); 6140 int reg_base = true_regnum (base); 6141 6142 if (CONSTANT_ADDRESS_P (base)) 6143 { 6144 int n_words = AVR_TINY ? 3 : 6; 6145 return avr_asm_len ("sts %m0,%A1" CR_TAB 6146 "sts %m0+1,%B1" CR_TAB 6147 "sts %m0+2,%C1", op, plen, -n_words); 6148 } 6149 6150 if (reg_base > 0) /* (r) */ 6151 { 6152 if (AVR_TINY) 6153 return avr_out_store_psi_reg_no_disp_tiny (insn, op, plen); 6154 6155 if (reg_base == REG_X) /* (R26) */ 6156 { 6157 gcc_assert (!reg_overlap_mentioned_p (base, src)); 6158 6159 avr_asm_len ("st %0+,%A1" CR_TAB 6160 "st %0+,%B1" CR_TAB 6161 "st %0,%C1", op, plen, -3); 6162 6163 if (!reg_unused_after (insn, base)) 6164 avr_asm_len ("sbiw r26,2", op, plen, 1); 6165 6166 return ""; 6167 } 6168 else 6169 return avr_asm_len ("st %0,%A1" CR_TAB 6170 "std %0+1,%B1" CR_TAB 6171 "std %0+2,%C1", op, plen, -3); 6172 } 6173 else if (GET_CODE (base) == PLUS) /* (R + i) */ 6174 { 6175 int disp = INTVAL (XEXP (base, 1)); 6176 6177 if (AVR_TINY) 6178 return avr_out_store_psi_reg_disp_tiny (insn, op, plen); 6179 6180 reg_base = REGNO (XEXP (base, 0)); 6181 6182 if (disp > MAX_LD_OFFSET (GET_MODE (dest))) 6183 { 6184 if (reg_base != REG_Y) 6185 fatal_insn ("incorrect insn:",insn); 6186 6187 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))) 6188 return avr_asm_len ("adiw r28,%o0-61" CR_TAB 6189 "std Y+61,%A1" CR_TAB 6190 "std Y+62,%B1" CR_TAB 6191 "std Y+63,%C1" CR_TAB 6192 "sbiw r28,%o0-61", op, plen, -5); 6193 6194 return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB 6195 "sbci r29,hi8(-%o0)" CR_TAB 6196 "st Y,%A1" CR_TAB 6197 "std Y+1,%B1" CR_TAB 6198 "std Y+2,%C1" CR_TAB 6199 "subi r28,lo8(%o0)" CR_TAB 6200 "sbci r29,hi8(%o0)", op, plen, -7); 6201 } 6202 if (reg_base == REG_X) 6203 { 6204 /* (X + d) = R */ 6205 gcc_assert (!reg_overlap_mentioned_p (XEXP (base, 0), src)); 6206 6207 avr_asm_len ("adiw r26,%o0" CR_TAB 6208 "st X+,%A1" CR_TAB 6209 "st X+,%B1" CR_TAB 6210 "st X,%C1", op, plen, -4); 6211 6212 if (!reg_unused_after (insn, XEXP (base, 0))) 6213 avr_asm_len ("sbiw r26,%o0+2", op, plen, 1); 6214 6215 return ""; 6216 } 6217 6218 return avr_asm_len ("std %A0,%A1" CR_TAB 6219 "std %B0,%B1" CR_TAB 6220 "std %C0,%C1", op, plen, -3); 6221 } 6222 else if (GET_CODE (base) == PRE_DEC) /* (--R) */ 6223 return avr_asm_len ("st %0,%C1" CR_TAB 6224 "st %0,%B1" CR_TAB 6225 "st %0,%A1", op, plen, -3); 6226 else if (GET_CODE (base) == POST_INC) /* (R++) */ 6227 return avr_asm_len ("st %0,%A1" CR_TAB 6228 "st %0,%B1" CR_TAB 6229 "st %0,%C1", op, plen, -3); 6230 6231 fatal_insn ("unknown move insn:",insn); 6232 return ""; 6233 } 6234 6235 6236 /* Move around 24-bit stuff. */ 6237 6238 const char * 6239 avr_out_movpsi (rtx_insn *insn, rtx *op, int *plen) 6240 { 6241 rtx dest = op[0]; 6242 rtx src = op[1]; 6243 6244 if (avr_mem_flash_p (src) 6245 || avr_mem_flash_p (dest)) 6246 { 6247 return avr_out_lpm (insn, op, plen); 6248 } 6249 6250 if (register_operand (dest, VOIDmode)) 6251 { 6252 if (register_operand (src, VOIDmode)) /* mov r,r */ 6253 { 6254 if (true_regnum (dest) > true_regnum (src)) 6255 { 6256 avr_asm_len ("mov %C0,%C1", op, plen, -1); 6257 6258 if (AVR_HAVE_MOVW) 6259 return avr_asm_len ("movw %A0,%A1", op, plen, 1); 6260 else 6261 return avr_asm_len ("mov %B0,%B1" CR_TAB 6262 "mov %A0,%A1", op, plen, 2); 6263 } 6264 else 6265 { 6266 if (AVR_HAVE_MOVW) 6267 avr_asm_len ("movw %A0,%A1", op, plen, -1); 6268 else 6269 avr_asm_len ("mov %A0,%A1" CR_TAB 6270 "mov %B0,%B1", op, plen, -2); 6271 6272 return avr_asm_len ("mov %C0,%C1", op, plen, 1); 6273 } 6274 } 6275 else if (CONSTANT_P (src)) 6276 { 6277 return avr_out_reload_inpsi (op, NULL_RTX, plen); 6278 } 6279 else if (MEM_P (src)) 6280 return avr_out_load_psi (insn, op, plen); /* mov r,m */ 6281 } 6282 else if (MEM_P (dest)) 6283 { 6284 rtx xop[2]; 6285 6286 xop[0] = dest; 6287 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src; 6288 6289 return avr_out_store_psi (insn, xop, plen); 6290 } 6291 6292 fatal_insn ("invalid insn:", insn); 6293 return ""; 6294 } 6295 6296 static const char * 6297 avr_out_movqi_mr_r_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen) 6298 { 6299 rtx dest = op[0]; 6300 rtx src = op[1]; 6301 rtx x = XEXP (dest, 0); 6302 6303 if (reg_overlap_mentioned_p (src, XEXP (x, 0))) 6304 { 6305 avr_asm_len ("mov __tmp_reg__,%1" CR_TAB 6306 TINY_ADIW (%I0, %J0, %o0) CR_TAB 6307 "st %b0,__tmp_reg__", op, plen, -4); 6308 } 6309 else 6310 { 6311 avr_asm_len (TINY_ADIW (%I0, %J0, %o0) CR_TAB 6312 "st %b0,%1", op, plen, -3); 6313 } 6314 6315 if (!reg_unused_after (insn, XEXP (x, 0))) 6316 avr_asm_len (TINY_SBIW (%I0, %J0, %o0), op, plen, 2); 6317 6318 return ""; 6319 } 6320 6321 static const char * 6322 out_movqi_mr_r (rtx_insn *insn, rtx op[], int *plen) 6323 { 6324 rtx dest = op[0]; 6325 rtx src = op[1]; 6326 rtx x = XEXP (dest, 0); 6327 6328 if (CONSTANT_ADDRESS_P (x)) 6329 { 6330 int n_words = AVR_TINY ? 1 : 2; 6331 return io_address_operand (x, QImode) 6332 ? avr_asm_len ("out %i0,%1", op, plen, -1) 6333 : avr_asm_len ("sts %m0,%1", op, plen, -n_words); 6334 } 6335 else if (GET_CODE (x) == PLUS 6336 && REG_P (XEXP (x, 0)) 6337 && CONST_INT_P (XEXP (x, 1))) 6338 { 6339 /* memory access by reg+disp */ 6340 6341 int disp = INTVAL (XEXP (x, 1)); 6342 6343 if (AVR_TINY) 6344 return avr_out_movqi_mr_r_reg_disp_tiny (insn, op, plen); 6345 6346 if (disp - GET_MODE_SIZE (GET_MODE (dest)) >= 63) 6347 { 6348 if (REGNO (XEXP (x, 0)) != REG_Y) 6349 fatal_insn ("incorrect insn:",insn); 6350 6351 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))) 6352 return avr_asm_len ("adiw r28,%o0-63" CR_TAB 6353 "std Y+63,%1" CR_TAB 6354 "sbiw r28,%o0-63", op, plen, -3); 6355 6356 return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB 6357 "sbci r29,hi8(-%o0)" CR_TAB 6358 "st Y,%1" CR_TAB 6359 "subi r28,lo8(%o0)" CR_TAB 6360 "sbci r29,hi8(%o0)", op, plen, -5); 6361 } 6362 else if (REGNO (XEXP (x, 0)) == REG_X) 6363 { 6364 if (reg_overlap_mentioned_p (src, XEXP (x, 0))) 6365 { 6366 avr_asm_len ("mov __tmp_reg__,%1" CR_TAB 6367 "adiw r26,%o0" CR_TAB 6368 "st X,__tmp_reg__", op, plen, -3); 6369 } 6370 else 6371 { 6372 avr_asm_len ("adiw r26,%o0" CR_TAB 6373 "st X,%1", op, plen, -2); 6374 } 6375 6376 if (!reg_unused_after (insn, XEXP (x, 0))) 6377 avr_asm_len ("sbiw r26,%o0", op, plen, 1); 6378 6379 return ""; 6380 } 6381 6382 return avr_asm_len ("std %0,%1", op, plen, -1); 6383 } 6384 6385 return avr_asm_len ("st %0,%1", op, plen, -1); 6386 } 6387 6388 6389 /* Helper for the next function for XMEGA. It does the same 6390 but with low byte first. */ 6391 6392 static const char * 6393 avr_out_movhi_mr_r_xmega (rtx_insn *insn, rtx op[], int *plen) 6394 { 6395 rtx dest = op[0]; 6396 rtx src = op[1]; 6397 rtx base = XEXP (dest, 0); 6398 int reg_base = true_regnum (base); 6399 int reg_src = true_regnum (src); 6400 6401 /* "volatile" forces writing low byte first, even if less efficient, 6402 for correct operation with 16-bit I/O registers like SP. */ 6403 bool mem_volatile_p = MEM_VOLATILE_P (dest); 6404 6405 if (CONSTANT_ADDRESS_P (base)) 6406 { 6407 return io_address_operand (base, HImode) 6408 ? avr_asm_len ("out %i0,%A1" CR_TAB 6409 "out %i0+1,%B1", op, plen, -2) 6410 6411 : avr_asm_len ("sts %m0,%A1" CR_TAB 6412 "sts %m0+1,%B1", op, plen, -4); 6413 } 6414 6415 if (reg_base > 0) 6416 { 6417 if (reg_base != REG_X) 6418 return avr_asm_len ("st %0,%A1" CR_TAB 6419 "std %0+1,%B1", op, plen, -2); 6420 6421 if (reg_src == REG_X) 6422 /* "st X+,r26" and "st -X,r26" are undefined. */ 6423 avr_asm_len ("mov __tmp_reg__,r27" CR_TAB 6424 "st X,r26" CR_TAB 6425 "adiw r26,1" CR_TAB 6426 "st X,__tmp_reg__", op, plen, -4); 6427 else 6428 avr_asm_len ("st X+,%A1" CR_TAB 6429 "st X,%B1", op, plen, -2); 6430 6431 return reg_unused_after (insn, base) 6432 ? "" 6433 : avr_asm_len ("sbiw r26,1", op, plen, 1); 6434 } 6435 else if (GET_CODE (base) == PLUS) 6436 { 6437 int disp = INTVAL (XEXP (base, 1)); 6438 reg_base = REGNO (XEXP (base, 0)); 6439 if (disp > MAX_LD_OFFSET (GET_MODE (dest))) 6440 { 6441 if (reg_base != REG_Y) 6442 fatal_insn ("incorrect insn:",insn); 6443 6444 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)) 6445 ? avr_asm_len ("adiw r28,%o0-62" CR_TAB 6446 "std Y+62,%A1" CR_TAB 6447 "std Y+63,%B1" CR_TAB 6448 "sbiw r28,%o0-62", op, plen, -4) 6449 6450 : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB 6451 "sbci r29,hi8(-%o0)" CR_TAB 6452 "st Y,%A1" CR_TAB 6453 "std Y+1,%B1" CR_TAB 6454 "subi r28,lo8(%o0)" CR_TAB 6455 "sbci r29,hi8(%o0)", op, plen, -6); 6456 } 6457 6458 if (reg_base != REG_X) 6459 return avr_asm_len ("std %A0,%A1" CR_TAB 6460 "std %B0,%B1", op, plen, -2); 6461 /* (X + d) = R */ 6462 return reg_src == REG_X 6463 ? avr_asm_len ("mov __tmp_reg__,r26" CR_TAB 6464 "mov __zero_reg__,r27" CR_TAB 6465 "adiw r26,%o0" CR_TAB 6466 "st X+,__tmp_reg__" CR_TAB 6467 "st X,__zero_reg__" CR_TAB 6468 "clr __zero_reg__" CR_TAB 6469 "sbiw r26,%o0+1", op, plen, -7) 6470 6471 : avr_asm_len ("adiw r26,%o0" CR_TAB 6472 "st X+,%A1" CR_TAB 6473 "st X,%B1" CR_TAB 6474 "sbiw r26,%o0+1", op, plen, -4); 6475 } 6476 else if (GET_CODE (base) == PRE_DEC) /* (--R) */ 6477 { 6478 if (!mem_volatile_p) 6479 return avr_asm_len ("st %0,%B1" CR_TAB 6480 "st %0,%A1", op, plen, -2); 6481 6482 return REGNO (XEXP (base, 0)) == REG_X 6483 ? avr_asm_len ("sbiw r26,2" CR_TAB 6484 "st X+,%A1" CR_TAB 6485 "st X,%B1" CR_TAB 6486 "sbiw r26,1", op, plen, -4) 6487 6488 : avr_asm_len ("sbiw %r0,2" CR_TAB 6489 "st %p0,%A1" CR_TAB 6490 "std %p0+1,%B1", op, plen, -3); 6491 } 6492 else if (GET_CODE (base) == POST_INC) /* (R++) */ 6493 { 6494 return avr_asm_len ("st %0,%A1" CR_TAB 6495 "st %0,%B1", op, plen, -2); 6496 6497 } 6498 fatal_insn ("unknown move insn:",insn); 6499 return ""; 6500 } 6501 6502 static const char * 6503 avr_out_movhi_mr_r_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *plen) 6504 { 6505 rtx dest = op[0]; 6506 rtx src = op[1]; 6507 rtx base = XEXP (dest, 0); 6508 int reg_base = true_regnum (base); 6509 int reg_src = true_regnum (src); 6510 bool mem_volatile_p = MEM_VOLATILE_P (dest); 6511 6512 if (reg_base == reg_src) 6513 { 6514 return !mem_volatile_p && reg_unused_after (insn, src) 6515 ? avr_asm_len ("mov __tmp_reg__,%B1" CR_TAB 6516 "st %0,%A1" CR_TAB 6517 TINY_ADIW (%E0, %F0, 1) CR_TAB 6518 "st %0,__tmp_reg__", op, plen, -5) 6519 : avr_asm_len ("mov __tmp_reg__,%B1" CR_TAB 6520 TINY_ADIW (%E0, %F0, 1) CR_TAB 6521 "st %0,__tmp_reg__" CR_TAB 6522 TINY_SBIW (%E0, %F0, 1) CR_TAB 6523 "st %0, %A1", op, plen, -7); 6524 } 6525 6526 return !mem_volatile_p && reg_unused_after (insn, base) 6527 ? avr_asm_len ("st %0+,%A1" CR_TAB 6528 "st %0,%B1", op, plen, -2) 6529 : avr_asm_len (TINY_ADIW (%E0, %F0, 1) CR_TAB 6530 "st %0,%B1" CR_TAB 6531 "st -%0,%A1", op, plen, -4); 6532 } 6533 6534 static const char * 6535 avr_out_movhi_mr_r_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen) 6536 { 6537 rtx dest = op[0]; 6538 rtx src = op[1]; 6539 rtx base = XEXP (dest, 0); 6540 int reg_base = REGNO (XEXP (base, 0)); 6541 int reg_src = true_regnum (src); 6542 6543 if (reg_src == reg_base) 6544 avr_asm_len ("mov __tmp_reg__,%A1" CR_TAB 6545 "mov __zero_reg__,%B1" CR_TAB 6546 TINY_ADIW (%I0, %J0, %o0+1) CR_TAB 6547 "st %b0,__zero_reg__" CR_TAB 6548 "st -%b0,__tmp_reg__" CR_TAB 6549 "clr __zero_reg__", op, plen, -7); 6550 else 6551 avr_asm_len (TINY_ADIW (%I0, %J0, %o0+1) CR_TAB 6552 "st %b0,%B1" CR_TAB 6553 "st -%b0,%A1", op, plen, -4); 6554 6555 if (!reg_unused_after (insn, XEXP (base, 0))) 6556 avr_asm_len (TINY_SBIW (%I0, %J0, %o0), op, plen, 2); 6557 6558 return ""; 6559 } 6560 6561 static const char * 6562 avr_out_movhi_mr_r_post_inc_tiny (rtx op[], int *plen) 6563 { 6564 return avr_asm_len (TINY_ADIW (%I0, %J0, 1) CR_TAB 6565 "st %p0,%B1" CR_TAB 6566 "st -%p0,%A1" CR_TAB 6567 TINY_ADIW (%I0, %J0, 2), op, plen, -6); 6568 } 6569 6570 static const char * 6571 out_movhi_mr_r (rtx_insn *insn, rtx op[], int *plen) 6572 { 6573 rtx dest = op[0]; 6574 rtx src = op[1]; 6575 rtx base = XEXP (dest, 0); 6576 int reg_base = true_regnum (base); 6577 int reg_src = true_regnum (src); 6578 6579 /* "volatile" forces writing high-byte first (no-xmega) resp. 6580 low-byte first (xmega) even if less efficient, for correct 6581 operation with 16-bit I/O registers like. */ 6582 6583 if (AVR_XMEGA) 6584 return avr_out_movhi_mr_r_xmega (insn, op, plen); 6585 6586 bool mem_volatile_p = MEM_VOLATILE_P (dest); 6587 6588 if (CONSTANT_ADDRESS_P (base)) 6589 { 6590 int n_words = AVR_TINY ? 2 : 4; 6591 return io_address_operand (base, HImode) 6592 ? avr_asm_len ("out %i0+1,%B1" CR_TAB 6593 "out %i0,%A1", op, plen, -2) 6594 6595 : avr_asm_len ("sts %m0+1,%B1" CR_TAB 6596 "sts %m0,%A1", op, plen, -n_words); 6597 } 6598 6599 if (reg_base > 0) 6600 { 6601 if (AVR_TINY) 6602 return avr_out_movhi_mr_r_reg_no_disp_tiny (insn, op, plen); 6603 6604 if (reg_base != REG_X) 6605 return avr_asm_len ("std %0+1,%B1" CR_TAB 6606 "st %0,%A1", op, plen, -2); 6607 6608 if (reg_src == REG_X) 6609 /* "st X+,r26" and "st -X,r26" are undefined. */ 6610 return !mem_volatile_p && reg_unused_after (insn, src) 6611 ? avr_asm_len ("mov __tmp_reg__,r27" CR_TAB 6612 "st X,r26" CR_TAB 6613 "adiw r26,1" CR_TAB 6614 "st X,__tmp_reg__", op, plen, -4) 6615 6616 : avr_asm_len ("mov __tmp_reg__,r27" CR_TAB 6617 "adiw r26,1" CR_TAB 6618 "st X,__tmp_reg__" CR_TAB 6619 "sbiw r26,1" CR_TAB 6620 "st X,r26", op, plen, -5); 6621 6622 return !mem_volatile_p && reg_unused_after (insn, base) 6623 ? avr_asm_len ("st X+,%A1" CR_TAB 6624 "st X,%B1", op, plen, -2) 6625 : avr_asm_len ("adiw r26,1" CR_TAB 6626 "st X,%B1" CR_TAB 6627 "st -X,%A1", op, plen, -3); 6628 } 6629 else if (GET_CODE (base) == PLUS) 6630 { 6631 int disp = INTVAL (XEXP (base, 1)); 6632 6633 if (AVR_TINY) 6634 return avr_out_movhi_mr_r_reg_disp_tiny (insn, op, plen); 6635 6636 reg_base = REGNO (XEXP (base, 0)); 6637 if (disp > MAX_LD_OFFSET (GET_MODE (dest))) 6638 { 6639 if (reg_base != REG_Y) 6640 fatal_insn ("incorrect insn:",insn); 6641 6642 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)) 6643 ? avr_asm_len ("adiw r28,%o0-62" CR_TAB 6644 "std Y+63,%B1" CR_TAB 6645 "std Y+62,%A1" CR_TAB 6646 "sbiw r28,%o0-62", op, plen, -4) 6647 6648 : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB 6649 "sbci r29,hi8(-%o0)" CR_TAB 6650 "std Y+1,%B1" CR_TAB 6651 "st Y,%A1" CR_TAB 6652 "subi r28,lo8(%o0)" CR_TAB 6653 "sbci r29,hi8(%o0)", op, plen, -6); 6654 } 6655 6656 if (reg_base != REG_X) 6657 return avr_asm_len ("std %B0,%B1" CR_TAB 6658 "std %A0,%A1", op, plen, -2); 6659 /* (X + d) = R */ 6660 return reg_src == REG_X 6661 ? avr_asm_len ("mov __tmp_reg__,r26" CR_TAB 6662 "mov __zero_reg__,r27" CR_TAB 6663 "adiw r26,%o0+1" CR_TAB 6664 "st X,__zero_reg__" CR_TAB 6665 "st -X,__tmp_reg__" CR_TAB 6666 "clr __zero_reg__" CR_TAB 6667 "sbiw r26,%o0", op, plen, -7) 6668 6669 : avr_asm_len ("adiw r26,%o0+1" CR_TAB 6670 "st X,%B1" CR_TAB 6671 "st -X,%A1" CR_TAB 6672 "sbiw r26,%o0", op, plen, -4); 6673 } 6674 else if (GET_CODE (base) == PRE_DEC) /* (--R) */ 6675 { 6676 return avr_asm_len ("st %0,%B1" CR_TAB 6677 "st %0,%A1", op, plen, -2); 6678 } 6679 else if (GET_CODE (base) == POST_INC) /* (R++) */ 6680 { 6681 if (!mem_volatile_p) 6682 return avr_asm_len ("st %0,%A1" CR_TAB 6683 "st %0,%B1", op, plen, -2); 6684 6685 if (AVR_TINY) 6686 return avr_out_movhi_mr_r_post_inc_tiny (op, plen); 6687 6688 return REGNO (XEXP (base, 0)) == REG_X 6689 ? avr_asm_len ("adiw r26,1" CR_TAB 6690 "st X,%B1" CR_TAB 6691 "st -X,%A1" CR_TAB 6692 "adiw r26,2", op, plen, -4) 6693 6694 : avr_asm_len ("std %p0+1,%B1" CR_TAB 6695 "st %p0,%A1" CR_TAB 6696 "adiw %r0,2", op, plen, -3); 6697 } 6698 fatal_insn ("unknown move insn:",insn); 6699 return ""; 6700 } 6701 6702 6703 /* During reload, we allow much more addresses than Reduced Tiny actually 6704 supports. Split them after reload in order to get closer to the 6705 core's capabilities. This sets the stage for pass .avr-fuse-add. */ 6706 6707 bool 6708 avr_split_tiny_move (rtx_insn * /*insn*/, rtx *xop) 6709 { 6710 bool store_p = false; 6711 rtx mem, reg_or_0; 6712 6713 if (REG_P (xop[0]) && MEM_P (xop[1])) 6714 { 6715 reg_or_0 = xop[0]; 6716 mem = xop[1]; 6717 } 6718 else if (MEM_P (xop[0]) 6719 && (REG_P (xop[1]) 6720 || xop[1] == CONST0_RTX (GET_MODE (xop[0])))) 6721 { 6722 mem = xop[0]; 6723 reg_or_0 = xop[1]; 6724 store_p = true; 6725 } 6726 else 6727 return false; 6728 6729 machine_mode mode = GET_MODE (mem); 6730 rtx base, addr = XEXP (mem, 0); 6731 enum rtx_code addr_code = GET_CODE (addr); 6732 6733 if (REG_P (reg_or_0) 6734 && reg_overlap_mentioned_p (reg_or_0, addr)) 6735 return false; 6736 else if (addr_code == PLUS || addr_code == PRE_DEC || addr_code == POST_INC) 6737 base = XEXP (addr, 0); 6738 else if (addr_code == REG) 6739 base = addr; 6740 else 6741 return false; 6742 6743 if (REGNO (base) > REG_Z) 6744 return false; 6745 6746 bool volatile_p = MEM_VOLATILE_P (mem); 6747 bool mem_volatile_p = false; 6748 if (frame_pointer_needed 6749 && REGNO (base) == FRAME_POINTER_REGNUM) 6750 { 6751 if (avr_fuse_add < 2 6752 // Be a projection (we always split PLUS). 6753 || (avr_fuse_add == 2 && volatile_p && addr_code != PLUS)) 6754 return false; 6755 6756 // Changing the frame pointer locally may confuse later passes 6757 // like .dse2 which don't track changes of FP, not even when 6758 // respective CFA notes are present. An example is pr22141-1.c. 6759 if (avr_fuse_add == 2) 6760 mem_volatile_p = true; 6761 } 6762 6763 enum rtx_code new_code = UNKNOWN; 6764 HOST_WIDE_INT add = 0, sub = 0; 6765 int msize = GET_MODE_SIZE (mode); 6766 6767 AVR_LdSt_Props ap { REGNO (base), store_p, volatile_p, ADDR_SPACE_GENERIC }; 6768 6769 switch (addr_code) 6770 { 6771 default: 6772 return false; 6773 6774 case PLUS: 6775 add = INTVAL (XEXP (addr, 1)); 6776 if (msize == 1) 6777 { 6778 new_code = REG; 6779 sub = -add; 6780 } 6781 else if (ap.want_predec) 6782 { 6783 // volatile stores prefer PRE_DEC (MSB first) 6784 sub = -add; 6785 add += msize; 6786 new_code = PRE_DEC; 6787 } 6788 else 6789 { 6790 new_code = POST_INC; 6791 sub = -add - msize; 6792 } 6793 break; 6794 6795 case POST_INC: 6796 // volatile stores prefer PRE_DEC (MSB first) 6797 if (msize > 1 && ap.want_predec) 6798 { 6799 add = msize; 6800 new_code = PRE_DEC; 6801 sub = msize; 6802 break; 6803 } 6804 return false; 6805 6806 case PRE_DEC: 6807 // volatile loads prefer POST_INC (LSB first) 6808 if (msize > 1 && ap.want_postinc) 6809 { 6810 add = -msize; 6811 new_code = POST_INC; 6812 sub = -msize; 6813 break; 6814 } 6815 return false; 6816 6817 case REG: 6818 if (msize == 1) 6819 return false; 6820 6821 if (ap.want_predec) 6822 { 6823 add = msize; 6824 new_code = PRE_DEC; 6825 sub = 0; 6826 } 6827 else 6828 { 6829 add = 0; 6830 new_code = POST_INC; 6831 sub = -msize; 6832 } 6833 break; 6834 } // switch addr_code 6835 6836 rtx_insn *insn; 6837 6838 if (add) 6839 { 6840 insn = emit_move_ccc (base, plus_constant (Pmode, base, add)); 6841 avr_maybe_adjust_cfa (insn, base, add); 6842 } 6843 6844 rtx new_addr = new_code == REG 6845 ? base 6846 : gen_rtx_fmt_e (new_code, Pmode, base); 6847 6848 rtx new_mem = change_address (mem, mode, new_addr); 6849 if (mem_volatile_p) 6850 MEM_VOLATILE_P (new_mem) = 1; 6851 6852 insn = emit_move_ccc (store_p ? new_mem : reg_or_0, 6853 store_p ? reg_or_0 : new_mem); 6854 if (auto_inc_p (new_addr)) 6855 { 6856 add_reg_note (insn, REG_INC, base); 6857 int off = new_code == POST_INC ? msize : -msize; 6858 avr_maybe_adjust_cfa (insn, base, off); 6859 } 6860 6861 if (sub) 6862 { 6863 insn = emit_move_ccc (base, plus_constant (Pmode, base, sub)); 6864 avr_maybe_adjust_cfa (insn, base, sub); 6865 } 6866 6867 return true; 6868 } 6869 6870 6871 /* Implement `TARGET_FRAME_POINTER_REQUIRED'. */ 6872 /* Return 1 if frame pointer for current function required. */ 6873 6874 static bool 6875 avr_frame_pointer_required_p (void) 6876 { 6877 return (cfun->calls_alloca 6878 || cfun->calls_setjmp 6879 || cfun->has_nonlocal_label 6880 || crtl->args.info.has_stack_args 6881 || get_frame_size () > 0); 6882 } 6883 6884 6885 /* Returns the condition of the branch following INSN, where INSN is some 6886 comparison. If the next insn is not a branch or the condition code set 6887 by INSN might be used by more insns than the next one, return UNKNOWN. 6888 For now, just look at the next insn, which misses some opportunities like 6889 following jumps. */ 6890 6891 static RTX_CODE 6892 compare_condition (rtx_insn *insn) 6893 { 6894 rtx set; 6895 rtx_insn *next = next_real_nondebug_insn (insn); 6896 6897 if (next 6898 && JUMP_P (next) 6899 // If SREG does not die in the next insn, it is used in more than one 6900 // branch. This can happen due to pass .avr-ifelse optimizations. 6901 && dead_or_set_regno_p (next, REG_CC) 6902 // Branches are (set (pc) (if_then_else (COND (...)))). 6903 && (set = single_set (next)) 6904 && GET_CODE (SET_SRC (set)) == IF_THEN_ELSE) 6905 { 6906 return GET_CODE (XEXP (SET_SRC (set), 0)); 6907 } 6908 6909 return UNKNOWN; 6910 } 6911 6912 6913 /* Returns true if INSN is a tst insn that only tests the sign. */ 6914 6915 static bool 6916 compare_sign_p (rtx_insn *insn) 6917 { 6918 RTX_CODE cond = compare_condition (insn); 6919 return (cond == GE || cond == LT); 6920 } 6921 6922 6923 /* Returns true if INSN is a compare insn with the EQ or NE condition. */ 6924 6925 static bool 6926 compare_eq_p (rtx_insn *insn) 6927 { 6928 RTX_CODE cond = compare_condition (insn); 6929 return (cond == EQ || cond == NE); 6930 } 6931 6932 6933 /* Implement `TARGET_CANONICALIZE_COMPARISON'. */ 6934 /* Basically tries to convert "difficult" comparisons like GT[U] 6935 and LE[U] to simple ones. Some asymmetric comparisons can be 6936 transformed to EQ or NE against zero. */ 6937 6938 static void 6939 avr_canonicalize_comparison (int *icode, rtx *op0, rtx *op1, bool op0_fixed) 6940 { 6941 enum rtx_code code = (enum rtx_code) *icode; 6942 machine_mode mode = GET_MODE (*op0); 6943 6944 bool signed_p = code == GT || code == LE; 6945 bool unsigned_p = code == GTU || code == LEU; 6946 bool difficult_p = signed_p || unsigned_p; 6947 6948 if (// Only do integers and fixed-points. 6949 (! SCALAR_INT_MODE_P (mode) 6950 && ! ALL_SCALAR_FIXED_POINT_MODE_P (mode)) 6951 // Only do comparisons against a register. 6952 || ! register_operand (*op0, mode)) 6953 return; 6954 6955 // Canonicalize "difficult" reg-reg comparisons. 6956 6957 if (! op0_fixed 6958 && difficult_p 6959 && register_operand (*op1, mode)) 6960 { 6961 std::swap (*op0, *op1); 6962 *icode = (int) swap_condition (code); 6963 return; 6964 } 6965 6966 // Canonicalize comparisons against compile-time constants. 6967 6968 if (CONST_INT_P (*op1) 6969 || CONST_FIXED_P (*op1)) 6970 { 6971 // INT_MODE of the same size. 6972 scalar_int_mode imode = int_mode_for_mode (mode).require (); 6973 6974 unsigned HOST_WIDE_INT mask = GET_MODE_MASK (imode); 6975 unsigned HOST_WIDE_INT maxval = signed_p ? mask >> 1 : mask; 6976 6977 // Convert value *op1 to imode. 6978 rtx xval = simplify_gen_subreg (imode, *op1, mode, 0); 6979 6980 // Canonicalize difficult comparisons against const. 6981 if (difficult_p 6982 && (UINTVAL (xval) & mask) != maxval) 6983 { 6984 // Convert *op0 > *op1 to *op0 >= 1 + *op1. 6985 // Convert *op0 <= *op1 to *op0 < 1 + *op1. 6986 xval = simplify_binary_operation (PLUS, imode, xval, const1_rtx); 6987 6988 // Convert value back to its original mode. 6989 *op1 = simplify_gen_subreg (mode, xval, imode, 0); 6990 6991 // Map > to >= and <= to <. 6992 *icode = (int) avr_normalize_condition (code); 6993 6994 return; 6995 } 6996 6997 // Some asymmetric comparisons can be turned into EQ or NE. 6998 if (code == LTU && xval == const1_rtx) 6999 { 7000 *icode = (int) EQ; 7001 *op1 = CONST0_RTX (mode); 7002 return; 7003 } 7004 7005 if (code == GEU && xval == const1_rtx) 7006 { 7007 *icode = (int) NE; 7008 *op1 = CONST0_RTX (mode); 7009 return; 7010 } 7011 } 7012 } 7013 7014 7015 /* Output compare instruction 7016 7017 compare (XOP[0], XOP[1]) 7018 7019 for a register XOP[0] and a compile-time constant XOP[1]. Return "". 7020 XOP[2] is an 8-bit scratch register as needed. 7021 7022 PLEN == NULL: Output instructions. 7023 PLEN != NULL: Set *PLEN to the length (in words) of the sequence. 7024 Don't output anything. */ 7025 7026 const char * 7027 avr_out_compare (rtx_insn *insn, rtx *xop, int *plen) 7028 { 7029 /* Register to compare and value to compare against. */ 7030 rtx xreg = xop[0]; 7031 rtx xval = xop[1]; 7032 7033 /* Number of bytes to operate on. */ 7034 int n_bytes = GET_MODE_SIZE (GET_MODE (xreg)); 7035 7036 /* Value (0..0xff) held in clobber register xop[2] or -1 if unknown. */ 7037 int clobber_val = -1; 7038 7039 /* Map fixed mode operands to integer operands with the same binary 7040 representation. They are easier to handle in the remainder. */ 7041 7042 if (CONST_FIXED_P (xval)) 7043 { 7044 xreg = avr_to_int_mode (xop[0]); 7045 xval = avr_to_int_mode (xop[1]); 7046 } 7047 7048 /* MODE of the comparison. */ 7049 machine_mode mode = GET_MODE (xreg); 7050 7051 gcc_assert (REG_P (xreg)); 7052 gcc_assert ((CONST_INT_P (xval) && n_bytes <= 4) 7053 || (const_double_operand (xval, VOIDmode) && n_bytes == 8)); 7054 7055 if (plen) 7056 *plen = 0; 7057 7058 /* Comparisons == +/-1 and != +/-1 can be done similar to camparing 7059 against 0 by ORing the bytes. This is one instruction shorter. 7060 Notice that 64-bit comparisons are always against reg:ALL8 18 (ACC_A) 7061 and therefore don't use this. */ 7062 7063 if (!test_hard_reg_class (LD_REGS, xreg) 7064 && compare_eq_p (insn) 7065 && reg_unused_after (insn, xreg)) 7066 { 7067 if (xval == const1_rtx) 7068 { 7069 avr_asm_len ("dec %A0" CR_TAB 7070 "or %A0,%B0", xop, plen, 2); 7071 7072 if (n_bytes >= 3) 7073 avr_asm_len ("or %A0,%C0", xop, plen, 1); 7074 7075 if (n_bytes >= 4) 7076 avr_asm_len ("or %A0,%D0", xop, plen, 1); 7077 7078 return ""; 7079 } 7080 else if (xval == constm1_rtx) 7081 { 7082 if (n_bytes >= 4) 7083 avr_asm_len ("and %A0,%D0", xop, plen, 1); 7084 7085 if (n_bytes >= 3) 7086 avr_asm_len ("and %A0,%C0", xop, plen, 1); 7087 7088 return avr_asm_len ("and %A0,%B0" CR_TAB 7089 "com %A0", xop, plen, 2); 7090 } 7091 } 7092 7093 /* Comparisons == -1 and != -1 of a d-register that's used after the 7094 comparison. (If it's unused after we use CPI / SBCI or ADIW sequence 7095 from below.) Instead of CPI Rlo,-1 / LDI Rx,-1 / CPC Rhi,Rx we can 7096 use CPI Rlo,-1 / CPC Rhi,Rlo which is 1 instruction shorter: 7097 If CPI is true then Rlo contains -1 and we can use Rlo instead of Rx 7098 when CPC'ing the high part. If CPI is false then CPC cannot render 7099 the result to true. This also works for the more generic case where 7100 the constant is of the form 0xabab. */ 7101 7102 if (n_bytes == 2 7103 && xval != const0_rtx 7104 && test_hard_reg_class (LD_REGS, xreg) 7105 && compare_eq_p (insn) 7106 && !reg_unused_after (insn, xreg)) 7107 { 7108 rtx xlo8 = simplify_gen_subreg (QImode, xval, mode, 0); 7109 rtx xhi8 = simplify_gen_subreg (QImode, xval, mode, 1); 7110 7111 if (INTVAL (xlo8) == INTVAL (xhi8)) 7112 { 7113 xop[0] = xreg; 7114 xop[1] = xlo8; 7115 7116 return avr_asm_len ("cpi %A0,%1" CR_TAB 7117 "cpc %B0,%A0", xop, plen, 2); 7118 } 7119 } 7120 7121 for (int i = 0; i < n_bytes; i++) 7122 { 7123 /* We compare byte-wise. */ 7124 rtx reg8 = simplify_gen_subreg (QImode, xreg, mode, i); 7125 rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i); 7126 7127 /* 8-bit value to compare with this byte. */ 7128 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode); 7129 7130 /* Registers R16..R31 can operate with immediate. */ 7131 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8); 7132 7133 xop[0] = reg8; 7134 xop[1] = gen_int_mode (val8, QImode); 7135 7136 /* Word registers >= R24 can use SBIW/ADIW with 0..63. */ 7137 7138 if (i == 0 7139 && avr_adiw_reg_p (reg8)) 7140 { 7141 int val16 = trunc_int_for_mode (INTVAL (xval), HImode); 7142 7143 if (IN_RANGE (val16, 0, 63) 7144 && (val8 == 0 7145 || reg_unused_after (insn, xreg))) 7146 { 7147 avr_asm_len ("sbiw %0,%1", xop, plen, 1); 7148 7149 i++; 7150 continue; 7151 } 7152 7153 if (n_bytes == 2 7154 && IN_RANGE (val16, -63, -1) 7155 && compare_eq_p (insn) 7156 && reg_unused_after (insn, xreg)) 7157 { 7158 return avr_asm_len ("adiw %0,%n1", xop, plen, 1); 7159 } 7160 } 7161 7162 /* Comparing against 0 is easy. */ 7163 7164 if (val8 == 0) 7165 { 7166 avr_asm_len (i == 0 7167 ? "cp %0,__zero_reg__" 7168 : "cpc %0,__zero_reg__", xop, plen, 1); 7169 continue; 7170 } 7171 7172 /* Upper registers can compare and subtract-with-carry immediates. 7173 Notice that compare instructions do the same as respective subtract 7174 instruction; the only difference is that comparisons don't write 7175 the result back to the target register. */ 7176 7177 if (ld_reg_p) 7178 { 7179 if (i == 0) 7180 { 7181 avr_asm_len ("cpi %0,%1", xop, plen, 1); 7182 continue; 7183 } 7184 else if (reg_unused_after (insn, xreg)) 7185 { 7186 avr_asm_len ("sbci %0,%1", xop, plen, 1); 7187 continue; 7188 } 7189 } 7190 7191 /* Must load the value into the scratch register. */ 7192 7193 gcc_assert (REG_P (xop[2])); 7194 7195 if (clobber_val != (int) val8) 7196 avr_asm_len ("ldi %2,%1", xop, plen, 1); 7197 clobber_val = (int) val8; 7198 7199 avr_asm_len (i == 0 7200 ? "cp %0,%2" 7201 : "cpc %0,%2", xop, plen, 1); 7202 } 7203 7204 return ""; 7205 } 7206 7207 7208 /* Prepare operands of compare_const_di2 to be used with avr_out_compare. */ 7209 7210 const char * 7211 avr_out_compare64 (rtx_insn *insn, rtx *op, int *plen) 7212 { 7213 rtx xop[3] = { gen_rtx_REG (DImode, ACC_A), op[0], op[1] }; 7214 7215 return avr_out_compare (insn, xop, plen); 7216 } 7217 7218 /* Output test instruction for HImode. */ 7219 7220 const char * 7221 avr_out_tsthi (rtx_insn *insn, rtx *op, int *plen) 7222 { 7223 if (compare_sign_p (insn)) 7224 { 7225 avr_asm_len ("tst %B0", op, plen, -1); 7226 } 7227 else if (reg_unused_after (insn, op[0]) 7228 && compare_eq_p (insn)) 7229 { 7230 /* Faster than sbiw if we can clobber the operand. */ 7231 avr_asm_len ("or %A0,%B0", op, plen, -1); 7232 } 7233 else 7234 { 7235 avr_out_compare (insn, op, plen); 7236 } 7237 7238 return ""; 7239 } 7240 7241 7242 /* Output test instruction for PSImode. */ 7243 7244 const char * 7245 avr_out_tstpsi (rtx_insn *insn, rtx *op, int *plen) 7246 { 7247 if (compare_sign_p (insn)) 7248 { 7249 avr_asm_len ("tst %C0", op, plen, -1); 7250 } 7251 else if (reg_unused_after (insn, op[0]) 7252 && compare_eq_p (insn)) 7253 { 7254 /* Faster than sbiw if we can clobber the operand. */ 7255 avr_asm_len ("or %A0,%B0" CR_TAB 7256 "or %A0,%C0", op, plen, -2); 7257 } 7258 else 7259 { 7260 avr_out_compare (insn, op, plen); 7261 } 7262 7263 return ""; 7264 } 7265 7266 7267 /* Output test instruction for SImode. */ 7268 7269 const char * 7270 avr_out_tstsi (rtx_insn *insn, rtx *op, int *plen) 7271 { 7272 if (compare_sign_p (insn)) 7273 { 7274 avr_asm_len ("tst %D0", op, plen, -1); 7275 } 7276 else if (reg_unused_after (insn, op[0]) 7277 && compare_eq_p (insn)) 7278 { 7279 /* Faster than sbiw if we can clobber the operand. */ 7280 avr_asm_len ("or %A0,%B0" CR_TAB 7281 "or %A0,%C0" CR_TAB 7282 "or %A0,%D0", op, plen, -3); 7283 } 7284 else 7285 { 7286 avr_out_compare (insn, op, plen); 7287 } 7288 7289 return ""; 7290 } 7291 7292 7293 /* Output a comparison of a zero- or sign-extended register against a 7294 plain register. CODE is SIGN_EXTEND or ZERO_EXTEND. Return "". 7295 7296 PLEN != 0: Set *PLEN to the code length in words. Don't output anything. 7297 PLEN == 0: Print instructions. */ 7298 7299 const char * 7300 avr_out_cmp_ext (rtx xop[], enum rtx_code code, int *plen) 7301 { 7302 // The smaller reg is the one that's to be extended. Get its index as z. 7303 int z = GET_MODE_SIZE (GET_MODE (xop[1])) < GET_MODE_SIZE (GET_MODE (xop[0])); 7304 rtx zreg = xop[z]; 7305 rtx reg = xop[1 - z]; 7306 machine_mode mode = GET_MODE (reg); 7307 machine_mode zmode = GET_MODE (zreg); 7308 rtx zex; 7309 7310 if (plen) 7311 *plen = 0; 7312 7313 // zex holds the extended bytes above zreg. This is 0 for ZERO_EXTEND, 7314 // and 0 or -1 for SIGN_EXTEND. 7315 7316 if (code == SIGN_EXTEND) 7317 { 7318 // Sign-extend the high-byte of zreg to tmp_reg. 7319 int zmsb = GET_MODE_SIZE (zmode) - 1; 7320 rtx xzmsb = simplify_gen_subreg (QImode, zreg, zmode, zmsb); 7321 7322 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB 7323 "rol __tmp_reg__" CR_TAB 7324 "sbc __tmp_reg__,__tmp_reg__", &xzmsb, plen, 3); 7325 zex = tmp_reg_rtx; 7326 } 7327 else if (code == ZERO_EXTEND) 7328 { 7329 zex = zero_reg_rtx; 7330 } 7331 else 7332 gcc_unreachable(); 7333 7334 // Now output n_bytes bytes of the very comparison. 7335 7336 int n_bytes = GET_MODE_SIZE (mode); 7337 7338 avr_asm_len ("cp %0,%1", xop, plen, 1); 7339 7340 for (int b = 1; b < n_bytes; ++b) 7341 { 7342 rtx regs[2]; 7343 regs[1 - z] = simplify_gen_subreg (QImode, reg, mode, b); 7344 regs[z] = (b < GET_MODE_SIZE (zmode) 7345 ? simplify_gen_subreg (QImode, zreg, zmode, b) 7346 : zex); 7347 7348 avr_asm_len ("cpc %0,%1", regs, plen, 1); 7349 } 7350 7351 return ""; 7352 } 7353 7354 7355 /* Generate asm equivalent for various shifts. This only handles cases 7356 that are not already carefully hand-optimized in ?sh??i3_out. 7357 7358 OPERANDS[0] resp. %0 in TEMPL is the operand to be shifted. 7359 OPERANDS[2] is the shift count as CONST_INT, MEM or REG. 7360 OPERANDS[3] is a QImode scratch register from LD regs if 7361 available and SCRATCH, otherwise (no scratch available) 7362 7363 TEMPL is an assembler template that shifts by one position. 7364 T_LEN is the length of this template. */ 7365 7366 void 7367 out_shift_with_cnt (const char *templ, rtx_insn *insn, rtx operands[], 7368 int *plen, int t_len) 7369 { 7370 bool second_label = true; 7371 bool saved_in_tmp = false; 7372 bool use_zero_reg = false; 7373 rtx op[5]; 7374 7375 op[0] = operands[0]; 7376 op[1] = operands[1]; 7377 op[2] = operands[2]; 7378 op[3] = operands[3]; 7379 7380 if (plen) 7381 *plen = 0; 7382 7383 if (CONST_INT_P (operands[2])) 7384 { 7385 /* Operand 3 is a scratch register if this is a 7386 parallel with three elements i.e. a set, 7387 a clobber of a scratch, and clobber of REG_CC. 7388 If a scratch reg is not available, then the parallel 7389 will contain only a set and clobber of REG_CC. */ 7390 bool scratch = (GET_CODE (PATTERN (insn)) == PARALLEL 7391 && XVECLEN (PATTERN (insn), 0) == 3 7392 && REG_P (operands[3])); 7393 int count = INTVAL (operands[2]); 7394 int max_len = 10; /* If larger than this, always use a loop. */ 7395 7396 if (count <= 0) 7397 return; 7398 7399 if (count < 8 && !scratch) 7400 use_zero_reg = true; 7401 7402 if (optimize_size) 7403 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5)); 7404 7405 if (t_len * count <= max_len) 7406 { 7407 /* Output shifts inline with no loop - faster. */ 7408 7409 while (count-- > 0) 7410 avr_asm_len (templ, op, plen, t_len); 7411 7412 return; 7413 } 7414 7415 if (scratch) 7416 { 7417 avr_asm_len ("ldi %3,%2", op, plen, 1); 7418 } 7419 else if (use_zero_reg) 7420 { 7421 /* Hack to save one word: use __zero_reg__ as loop counter. 7422 Set one bit, then shift in a loop until it is 0 again. */ 7423 7424 op[3] = zero_reg_rtx; 7425 7426 avr_asm_len ("set" CR_TAB 7427 "bld %3,%2-1", op, plen, 2); 7428 } 7429 else 7430 { 7431 /* No scratch register available, use one from LD_REGS (saved in 7432 __tmp_reg__) that doesn't overlap with registers to shift. */ 7433 7434 op[3] = all_regs_rtx[((REGNO (op[0]) - 1) & 15) + REG_16]; 7435 op[4] = tmp_reg_rtx; 7436 saved_in_tmp = true; 7437 7438 avr_asm_len ("mov %4,%3" CR_TAB 7439 "ldi %3,%2", op, plen, 2); 7440 } 7441 7442 second_label = false; 7443 } 7444 else if (MEM_P (op[2])) 7445 { 7446 rtx op_mov[2]; 7447 7448 op_mov[0] = op[3] = tmp_reg_rtx; 7449 op_mov[1] = op[2]; 7450 7451 out_movqi_r_mr (insn, op_mov, plen); 7452 } 7453 else if (register_operand (op[2], QImode)) 7454 { 7455 op[3] = op[2]; 7456 7457 if (!reg_unused_after (insn, op[2]) 7458 || reg_overlap_mentioned_p (op[0], op[2])) 7459 { 7460 op[3] = tmp_reg_rtx; 7461 avr_asm_len ("mov %3,%2", op, plen, 1); 7462 } 7463 } 7464 else 7465 fatal_insn ("bad shift insn:", insn); 7466 7467 if (second_label) 7468 avr_asm_len ("rjmp 2f", op, plen, 1); 7469 7470 avr_asm_len ("1:", op, plen, 0); 7471 avr_asm_len (templ, op, plen, t_len); 7472 7473 if (second_label) 7474 avr_asm_len ("2:", op, plen, 0); 7475 7476 avr_asm_len (use_zero_reg ? "lsr %3" : "dec %3", op, plen, 1); 7477 avr_asm_len (second_label ? "brpl 1b" : "brne 1b", op, plen, 1); 7478 7479 if (saved_in_tmp) 7480 avr_asm_len ("mov %3,%4", op, plen, 1); 7481 } 7482 7483 7484 /* 8bit shift left ((char)x << i) */ 7485 7486 const char * 7487 ashlqi3_out (rtx_insn *insn, rtx operands[], int *len) 7488 { 7489 if (CONST_INT_P (operands[2])) 7490 { 7491 int k; 7492 7493 if (!len) 7494 len = &k; 7495 7496 switch (INTVAL (operands[2])) 7497 { 7498 default: 7499 if (INTVAL (operands[2]) < 8) 7500 break; 7501 7502 *len = 1; 7503 return "clr %0"; 7504 7505 case 1: 7506 *len = 1; 7507 return "lsl %0"; 7508 7509 case 2: 7510 *len = 2; 7511 return ("lsl %0" CR_TAB 7512 "lsl %0"); 7513 7514 case 3: 7515 *len = 3; 7516 return ("lsl %0" CR_TAB 7517 "lsl %0" CR_TAB 7518 "lsl %0"); 7519 7520 case 4: 7521 if (test_hard_reg_class (LD_REGS, operands[0])) 7522 { 7523 *len = 2; 7524 return ("swap %0" CR_TAB 7525 "andi %0,0xf0"); 7526 } 7527 *len = 4; 7528 return ("lsl %0" CR_TAB 7529 "lsl %0" CR_TAB 7530 "lsl %0" CR_TAB 7531 "lsl %0"); 7532 7533 case 5: 7534 if (test_hard_reg_class (LD_REGS, operands[0])) 7535 { 7536 *len = 3; 7537 return ("swap %0" CR_TAB 7538 "lsl %0" CR_TAB 7539 "andi %0,0xe0"); 7540 } 7541 *len = 5; 7542 return ("lsl %0" CR_TAB 7543 "lsl %0" CR_TAB 7544 "lsl %0" CR_TAB 7545 "lsl %0" CR_TAB 7546 "lsl %0"); 7547 7548 case 6: 7549 if (test_hard_reg_class (LD_REGS, operands[0])) 7550 { 7551 *len = 4; 7552 return ("swap %0" CR_TAB 7553 "lsl %0" CR_TAB 7554 "lsl %0" CR_TAB 7555 "andi %0,0xc0"); 7556 } 7557 *len = 6; 7558 return ("lsl %0" CR_TAB 7559 "lsl %0" CR_TAB 7560 "lsl %0" CR_TAB 7561 "lsl %0" CR_TAB 7562 "lsl %0" CR_TAB 7563 "lsl %0"); 7564 7565 case 7: 7566 *len = 3; 7567 return ("ror %0" CR_TAB 7568 "clr %0" CR_TAB 7569 "ror %0"); 7570 } 7571 } 7572 else if (CONSTANT_P (operands[2])) 7573 fatal_insn ("internal compiler error. Incorrect shift:", insn); 7574 7575 out_shift_with_cnt ("lsl %0", 7576 insn, operands, len, 1); 7577 return ""; 7578 } 7579 7580 7581 /* 16bit shift left ((short)x << i) */ 7582 7583 const char * 7584 ashlhi3_out (rtx_insn *insn, rtx operands[], int *len) 7585 { 7586 if (CONST_INT_P (operands[2])) 7587 { 7588 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL 7589 && XVECLEN (PATTERN (insn), 0) == 3 7590 && REG_P (operands[3])); 7591 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]); 7592 int k; 7593 int *t = len; 7594 7595 if (!len) 7596 len = &k; 7597 7598 switch (INTVAL (operands[2])) 7599 { 7600 default: 7601 if (INTVAL (operands[2]) < 16) 7602 break; 7603 7604 *len = 2; 7605 return ("clr %B0" CR_TAB 7606 "clr %A0"); 7607 7608 case 4: 7609 if (optimize_size && scratch) 7610 break; /* 5 */ 7611 if (ldi_ok) 7612 { 7613 *len = 6; 7614 return ("swap %A0" CR_TAB 7615 "swap %B0" CR_TAB 7616 "andi %B0,0xf0" CR_TAB 7617 "eor %B0,%A0" CR_TAB 7618 "andi %A0,0xf0" CR_TAB 7619 "eor %B0,%A0"); 7620 } 7621 if (scratch) 7622 { 7623 *len = 7; 7624 return ("swap %A0" CR_TAB 7625 "swap %B0" CR_TAB 7626 "ldi %3,0xf0" CR_TAB 7627 "and %B0,%3" CR_TAB 7628 "eor %B0,%A0" CR_TAB 7629 "and %A0,%3" CR_TAB 7630 "eor %B0,%A0"); 7631 } 7632 break; /* optimize_size ? 6 : 8 */ 7633 7634 case 5: 7635 if (optimize_size) 7636 break; /* scratch ? 5 : 6 */ 7637 if (ldi_ok) 7638 { 7639 *len = 8; 7640 return ("lsl %A0" CR_TAB 7641 "rol %B0" CR_TAB 7642 "swap %A0" CR_TAB 7643 "swap %B0" CR_TAB 7644 "andi %B0,0xf0" CR_TAB 7645 "eor %B0,%A0" CR_TAB 7646 "andi %A0,0xf0" CR_TAB 7647 "eor %B0,%A0"); 7648 } 7649 if (scratch) 7650 { 7651 *len = 9; 7652 return ("lsl %A0" CR_TAB 7653 "rol %B0" CR_TAB 7654 "swap %A0" CR_TAB 7655 "swap %B0" CR_TAB 7656 "ldi %3,0xf0" CR_TAB 7657 "and %B0,%3" CR_TAB 7658 "eor %B0,%A0" CR_TAB 7659 "and %A0,%3" CR_TAB 7660 "eor %B0,%A0"); 7661 } 7662 break; /* 10 */ 7663 7664 case 6: 7665 if (optimize_size) 7666 break; /* scratch ? 5 : 6 */ 7667 *len = 9; 7668 return ("clr __tmp_reg__" CR_TAB 7669 "lsr %B0" CR_TAB 7670 "ror %A0" CR_TAB 7671 "ror __tmp_reg__" CR_TAB 7672 "lsr %B0" CR_TAB 7673 "ror %A0" CR_TAB 7674 "ror __tmp_reg__" CR_TAB 7675 "mov %B0,%A0" CR_TAB 7676 "mov %A0,__tmp_reg__"); 7677 7678 case 7: 7679 *len = 5; 7680 return ("lsr %B0" CR_TAB 7681 "mov %B0,%A0" CR_TAB 7682 "clr %A0" CR_TAB 7683 "ror %B0" CR_TAB 7684 "ror %A0"); 7685 7686 case 8: 7687 return *len = 2, ("mov %B0,%A1" CR_TAB 7688 "clr %A0"); 7689 7690 case 9: 7691 *len = 3; 7692 return ("mov %B0,%A0" CR_TAB 7693 "clr %A0" CR_TAB 7694 "lsl %B0"); 7695 7696 case 10: 7697 *len = 4; 7698 return ("mov %B0,%A0" CR_TAB 7699 "clr %A0" CR_TAB 7700 "lsl %B0" CR_TAB 7701 "lsl %B0"); 7702 7703 case 11: 7704 *len = 5; 7705 return ("mov %B0,%A0" CR_TAB 7706 "clr %A0" CR_TAB 7707 "lsl %B0" CR_TAB 7708 "lsl %B0" CR_TAB 7709 "lsl %B0"); 7710 7711 case 12: 7712 if (ldi_ok) 7713 { 7714 *len = 4; 7715 return ("mov %B0,%A0" CR_TAB 7716 "clr %A0" CR_TAB 7717 "swap %B0" CR_TAB 7718 "andi %B0,0xf0"); 7719 } 7720 if (scratch) 7721 { 7722 *len = 5; 7723 return ("mov %B0,%A0" CR_TAB 7724 "clr %A0" CR_TAB 7725 "swap %B0" CR_TAB 7726 "ldi %3,0xf0" CR_TAB 7727 "and %B0,%3"); 7728 } 7729 *len = 6; 7730 return ("mov %B0,%A0" CR_TAB 7731 "clr %A0" CR_TAB 7732 "lsl %B0" CR_TAB 7733 "lsl %B0" CR_TAB 7734 "lsl %B0" CR_TAB 7735 "lsl %B0"); 7736 7737 case 13: 7738 if (ldi_ok) 7739 { 7740 *len = 5; 7741 return ("mov %B0,%A0" CR_TAB 7742 "clr %A0" CR_TAB 7743 "swap %B0" CR_TAB 7744 "lsl %B0" CR_TAB 7745 "andi %B0,0xe0"); 7746 } 7747 if (AVR_HAVE_MUL && scratch) 7748 { 7749 *len = 5; 7750 return ("ldi %3,0x20" CR_TAB 7751 "mul %A0,%3" CR_TAB 7752 "mov %B0,r0" CR_TAB 7753 "clr %A0" CR_TAB 7754 "clr __zero_reg__"); 7755 } 7756 if (optimize_size && scratch) 7757 break; /* 5 */ 7758 if (scratch) 7759 { 7760 *len = 6; 7761 return ("mov %B0,%A0" CR_TAB 7762 "clr %A0" CR_TAB 7763 "swap %B0" CR_TAB 7764 "lsl %B0" CR_TAB 7765 "ldi %3,0xe0" CR_TAB 7766 "and %B0,%3"); 7767 } 7768 if (AVR_HAVE_MUL) 7769 { 7770 *len = 6; 7771 return ("set" CR_TAB 7772 "bld r1,5" CR_TAB 7773 "mul %A0,r1" CR_TAB 7774 "mov %B0,r0" CR_TAB 7775 "clr %A0" CR_TAB 7776 "clr __zero_reg__"); 7777 } 7778 *len = 7; 7779 return ("mov %B0,%A0" CR_TAB 7780 "clr %A0" CR_TAB 7781 "lsl %B0" CR_TAB 7782 "lsl %B0" CR_TAB 7783 "lsl %B0" CR_TAB 7784 "lsl %B0" CR_TAB 7785 "lsl %B0"); 7786 7787 case 14: 7788 if (AVR_HAVE_MUL && ldi_ok) 7789 { 7790 *len = 5; 7791 return ("ldi %B0,0x40" CR_TAB 7792 "mul %A0,%B0" CR_TAB 7793 "mov %B0,r0" CR_TAB 7794 "clr %A0" CR_TAB 7795 "clr __zero_reg__"); 7796 } 7797 if (AVR_HAVE_MUL && scratch) 7798 { 7799 *len = 5; 7800 return ("ldi %3,0x40" CR_TAB 7801 "mul %A0,%3" CR_TAB 7802 "mov %B0,r0" CR_TAB 7803 "clr %A0" CR_TAB 7804 "clr __zero_reg__"); 7805 } 7806 if (optimize_size && ldi_ok) 7807 { 7808 *len = 5; 7809 return ("mov %B0,%A0" CR_TAB 7810 "ldi %A0,6" "\n1:\t" 7811 "lsl %B0" CR_TAB 7812 "dec %A0" CR_TAB 7813 "brne 1b"); 7814 } 7815 if (optimize_size && scratch) 7816 break; /* 5 */ 7817 *len = 6; 7818 return ("clr %B0" CR_TAB 7819 "lsr %A0" CR_TAB 7820 "ror %B0" CR_TAB 7821 "lsr %A0" CR_TAB 7822 "ror %B0" CR_TAB 7823 "clr %A0"); 7824 7825 case 15: 7826 *len = 4; 7827 return ("clr %B0" CR_TAB 7828 "lsr %A0" CR_TAB 7829 "ror %B0" CR_TAB 7830 "clr %A0"); 7831 } 7832 len = t; 7833 } 7834 out_shift_with_cnt ("lsl %A0" CR_TAB 7835 "rol %B0", insn, operands, len, 2); 7836 return ""; 7837 } 7838 7839 7840 /* 24-bit shift left */ 7841 7842 const char * 7843 avr_out_ashlpsi3 (rtx_insn *insn, rtx *op, int *plen) 7844 { 7845 if (plen) 7846 *plen = 0; 7847 7848 if (CONST_INT_P (op[2])) 7849 { 7850 switch (INTVAL (op[2])) 7851 { 7852 default: 7853 if (INTVAL (op[2]) < 24) 7854 break; 7855 7856 return avr_asm_len ("clr %A0" CR_TAB 7857 "clr %B0" CR_TAB 7858 "clr %C0", op, plen, 3); 7859 7860 case 8: 7861 { 7862 int reg0 = REGNO (op[0]); 7863 int reg1 = REGNO (op[1]); 7864 7865 if (reg0 >= reg1) 7866 return avr_asm_len ("mov %C0,%B1" CR_TAB 7867 "mov %B0,%A1" CR_TAB 7868 "clr %A0", op, plen, 3); 7869 else 7870 return avr_asm_len ("clr %A0" CR_TAB 7871 "mov %B0,%A1" CR_TAB 7872 "mov %C0,%B1", op, plen, 3); 7873 } 7874 7875 case 16: 7876 { 7877 int reg0 = REGNO (op[0]); 7878 int reg1 = REGNO (op[1]); 7879 7880 if (reg0 + 2 != reg1) 7881 avr_asm_len ("mov %C0,%A1", op, plen, 1); 7882 7883 return avr_asm_len ("clr %B0" CR_TAB 7884 "clr %A0", op, plen, 2); 7885 } 7886 7887 case 23: 7888 return avr_asm_len ("clr %C0" CR_TAB 7889 "lsr %A0" CR_TAB 7890 "ror %C0" CR_TAB 7891 "clr %B0" CR_TAB 7892 "clr %A0", op, plen, 5); 7893 } 7894 } 7895 7896 out_shift_with_cnt ("lsl %A0" CR_TAB 7897 "rol %B0" CR_TAB 7898 "rol %C0", insn, op, plen, 3); 7899 return ""; 7900 } 7901 7902 7903 /* 32bit shift left ((long)x << i) */ 7904 7905 const char * 7906 ashlsi3_out (rtx_insn *insn, rtx operands[], int *len) 7907 { 7908 if (CONST_INT_P (operands[2])) 7909 { 7910 int k; 7911 int *t = len; 7912 7913 if (!len) 7914 len = &k; 7915 7916 switch (INTVAL (operands[2])) 7917 { 7918 default: 7919 if (INTVAL (operands[2]) < 32) 7920 break; 7921 7922 if (AVR_HAVE_MOVW) 7923 return *len = 3, ("clr %D0" CR_TAB 7924 "clr %C0" CR_TAB 7925 "movw %A0,%C0"); 7926 *len = 4; 7927 return ("clr %D0" CR_TAB 7928 "clr %C0" CR_TAB 7929 "clr %B0" CR_TAB 7930 "clr %A0"); 7931 7932 case 8: 7933 { 7934 int reg0 = true_regnum (operands[0]); 7935 int reg1 = true_regnum (operands[1]); 7936 *len = 4; 7937 if (reg0 >= reg1) 7938 return ("mov %D0,%C1" CR_TAB 7939 "mov %C0,%B1" CR_TAB 7940 "mov %B0,%A1" CR_TAB 7941 "clr %A0"); 7942 else 7943 return ("clr %A0" CR_TAB 7944 "mov %B0,%A1" CR_TAB 7945 "mov %C0,%B1" CR_TAB 7946 "mov %D0,%C1"); 7947 } 7948 7949 case 16: 7950 { 7951 int reg0 = true_regnum (operands[0]); 7952 int reg1 = true_regnum (operands[1]); 7953 if (reg0 + 2 == reg1) 7954 return *len = 2, ("clr %B0" CR_TAB 7955 "clr %A0"); 7956 if (AVR_HAVE_MOVW) 7957 return *len = 3, ("movw %C0,%A1" CR_TAB 7958 "clr %B0" CR_TAB 7959 "clr %A0"); 7960 else 7961 return *len = 4, ("mov %C0,%A1" CR_TAB 7962 "mov %D0,%B1" CR_TAB 7963 "clr %B0" CR_TAB 7964 "clr %A0"); 7965 } 7966 7967 case 24: 7968 *len = 4; 7969 return ("mov %D0,%A1" CR_TAB 7970 "clr %C0" CR_TAB 7971 "clr %B0" CR_TAB 7972 "clr %A0"); 7973 7974 case 31: 7975 *len = 6; 7976 return ("clr %D0" CR_TAB 7977 "lsr %A0" CR_TAB 7978 "ror %D0" CR_TAB 7979 "clr %C0" CR_TAB 7980 "clr %B0" CR_TAB 7981 "clr %A0"); 7982 } 7983 len = t; 7984 } 7985 out_shift_with_cnt ("lsl %A0" CR_TAB 7986 "rol %B0" CR_TAB 7987 "rol %C0" CR_TAB 7988 "rol %D0", insn, operands, len, 4); 7989 return ""; 7990 } 7991 7992 /* 8bit arithmetic shift right ((signed char)x >> i) */ 7993 7994 const char * 7995 ashrqi3_out (rtx_insn *insn, rtx operands[], int *len) 7996 { 7997 if (CONST_INT_P (operands[2])) 7998 { 7999 int k; 8000 8001 if (!len) 8002 len = &k; 8003 8004 switch (INTVAL (operands[2])) 8005 { 8006 case 1: 8007 *len = 1; 8008 return "asr %0"; 8009 8010 case 2: 8011 *len = 2; 8012 return ("asr %0" CR_TAB 8013 "asr %0"); 8014 8015 case 3: 8016 *len = 3; 8017 return ("asr %0" CR_TAB 8018 "asr %0" CR_TAB 8019 "asr %0"); 8020 8021 case 4: 8022 *len = 4; 8023 return ("asr %0" CR_TAB 8024 "asr %0" CR_TAB 8025 "asr %0" CR_TAB 8026 "asr %0"); 8027 8028 case 5: 8029 *len = 5; 8030 return ("asr %0" CR_TAB 8031 "asr %0" CR_TAB 8032 "asr %0" CR_TAB 8033 "asr %0" CR_TAB 8034 "asr %0"); 8035 8036 case 6: 8037 *len = 4; 8038 return ("bst %0,6" CR_TAB 8039 "lsl %0" CR_TAB 8040 "sbc %0,%0" CR_TAB 8041 "bld %0,0"); 8042 8043 default: 8044 if (INTVAL (operands[2]) < 8) 8045 break; 8046 8047 /* fall through */ 8048 8049 case 7: 8050 *len = 2; 8051 return ("lsl %0" CR_TAB 8052 "sbc %0,%0"); 8053 } 8054 } 8055 else if (CONSTANT_P (operands[2])) 8056 fatal_insn ("internal compiler error. Incorrect shift:", insn); 8057 8058 out_shift_with_cnt ("asr %0", 8059 insn, operands, len, 1); 8060 return ""; 8061 } 8062 8063 8064 /* 16bit arithmetic shift right ((signed short)x >> i) */ 8065 8066 const char * 8067 ashrhi3_out (rtx_insn *insn, rtx operands[], int *len) 8068 { 8069 if (CONST_INT_P (operands[2])) 8070 { 8071 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL 8072 && XVECLEN (PATTERN (insn), 0) == 3 8073 && REG_P (operands[3])); 8074 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]); 8075 int k; 8076 int *t = len; 8077 8078 if (!len) 8079 len = &k; 8080 8081 switch (INTVAL (operands[2])) 8082 { 8083 case 4: 8084 case 5: 8085 /* XXX try to optimize this too? */ 8086 break; 8087 8088 case 6: 8089 if (optimize_size) 8090 break; /* scratch ? 5 : 6 */ 8091 *len = 8; 8092 return ("mov __tmp_reg__,%A0" CR_TAB 8093 "mov %A0,%B0" CR_TAB 8094 "lsl __tmp_reg__" CR_TAB 8095 "rol %A0" CR_TAB 8096 "sbc %B0,%B0" CR_TAB 8097 "lsl __tmp_reg__" CR_TAB 8098 "rol %A0" CR_TAB 8099 "rol %B0"); 8100 8101 case 7: 8102 *len = 4; 8103 return ("lsl %A0" CR_TAB 8104 "mov %A0,%B0" CR_TAB 8105 "rol %A0" CR_TAB 8106 "sbc %B0,%B0"); 8107 8108 case 8: 8109 { 8110 int reg0 = true_regnum (operands[0]); 8111 int reg1 = true_regnum (operands[1]); 8112 8113 if (reg0 == reg1) 8114 return *len = 3, ("mov %A0,%B0" CR_TAB 8115 "lsl %B0" CR_TAB 8116 "sbc %B0,%B0"); 8117 else 8118 return *len = 4, ("mov %A0,%B1" CR_TAB 8119 "clr %B0" CR_TAB 8120 "sbrc %A0,7" CR_TAB 8121 "dec %B0"); 8122 } 8123 8124 case 9: 8125 *len = 4; 8126 return ("mov %A0,%B0" CR_TAB 8127 "lsl %B0" CR_TAB 8128 "sbc %B0,%B0" CR_TAB 8129 "asr %A0"); 8130 8131 case 10: 8132 *len = 5; 8133 return ("mov %A0,%B0" CR_TAB 8134 "lsl %B0" CR_TAB 8135 "sbc %B0,%B0" CR_TAB 8136 "asr %A0" CR_TAB 8137 "asr %A0"); 8138 8139 case 11: 8140 if (AVR_HAVE_MUL && ldi_ok) 8141 { 8142 *len = 5; 8143 return ("ldi %A0,0x20" CR_TAB 8144 "muls %B0,%A0" CR_TAB 8145 "mov %A0,r1" CR_TAB 8146 "sbc %B0,%B0" CR_TAB 8147 "clr __zero_reg__"); 8148 } 8149 if (optimize_size && scratch) 8150 break; /* 5 */ 8151 *len = 6; 8152 return ("mov %A0,%B0" CR_TAB 8153 "lsl %B0" CR_TAB 8154 "sbc %B0,%B0" CR_TAB 8155 "asr %A0" CR_TAB 8156 "asr %A0" CR_TAB 8157 "asr %A0"); 8158 8159 case 12: 8160 if (AVR_HAVE_MUL && ldi_ok) 8161 { 8162 *len = 5; 8163 return ("ldi %A0,0x10" CR_TAB 8164 "muls %B0,%A0" CR_TAB 8165 "mov %A0,r1" CR_TAB 8166 "sbc %B0,%B0" CR_TAB 8167 "clr __zero_reg__"); 8168 } 8169 if (optimize_size && scratch) 8170 break; /* 5 */ 8171 *len = 7; 8172 return ("mov %A0,%B0" CR_TAB 8173 "lsl %B0" CR_TAB 8174 "sbc %B0,%B0" CR_TAB 8175 "asr %A0" CR_TAB 8176 "asr %A0" CR_TAB 8177 "asr %A0" CR_TAB 8178 "asr %A0"); 8179 8180 case 13: 8181 if (AVR_HAVE_MUL && ldi_ok) 8182 { 8183 *len = 5; 8184 return ("ldi %A0,0x08" CR_TAB 8185 "muls %B0,%A0" CR_TAB 8186 "mov %A0,r1" CR_TAB 8187 "sbc %B0,%B0" CR_TAB 8188 "clr __zero_reg__"); 8189 } 8190 if (optimize_size) 8191 break; /* scratch ? 5 : 7 */ 8192 *len = 8; 8193 return ("mov %A0,%B0" CR_TAB 8194 "lsl %B0" CR_TAB 8195 "sbc %B0,%B0" CR_TAB 8196 "asr %A0" CR_TAB 8197 "asr %A0" CR_TAB 8198 "asr %A0" CR_TAB 8199 "asr %A0" CR_TAB 8200 "asr %A0"); 8201 8202 case 14: 8203 *len = 5; 8204 return ("lsl %B0" CR_TAB 8205 "sbc %A0,%A0" CR_TAB 8206 "lsl %B0" CR_TAB 8207 "mov %B0,%A0" CR_TAB 8208 "rol %A0"); 8209 8210 default: 8211 if (INTVAL (operands[2]) < 16) 8212 break; 8213 8214 /* fall through */ 8215 8216 case 15: 8217 return *len = 3, ("lsl %B0" CR_TAB 8218 "sbc %A0,%A0" CR_TAB 8219 "mov %B0,%A0"); 8220 } 8221 len = t; 8222 } 8223 out_shift_with_cnt ("asr %B0" CR_TAB 8224 "ror %A0", insn, operands, len, 2); 8225 return ""; 8226 } 8227 8228 8229 /* 24-bit arithmetic shift right */ 8230 8231 const char * 8232 avr_out_ashrpsi3 (rtx_insn *insn, rtx *op, int *plen) 8233 { 8234 int dest = REGNO (op[0]); 8235 int src = REGNO (op[1]); 8236 8237 if (CONST_INT_P (op[2])) 8238 { 8239 if (plen) 8240 *plen = 0; 8241 8242 switch (INTVAL (op[2])) 8243 { 8244 case 8: 8245 if (dest <= src) 8246 return avr_asm_len ("mov %A0,%B1" CR_TAB 8247 "mov %B0,%C1" CR_TAB 8248 "clr %C0" CR_TAB 8249 "sbrc %B0,7" CR_TAB 8250 "dec %C0", op, plen, 5); 8251 else 8252 return avr_asm_len ("clr %C0" CR_TAB 8253 "sbrc %C1,7" CR_TAB 8254 "dec %C0" CR_TAB 8255 "mov %B0,%C1" CR_TAB 8256 "mov %A0,%B1", op, plen, 5); 8257 8258 case 16: 8259 if (dest != src + 2) 8260 avr_asm_len ("mov %A0,%C1", op, plen, 1); 8261 8262 return avr_asm_len ("clr %B0" CR_TAB 8263 "sbrc %A0,7" CR_TAB 8264 "com %B0" CR_TAB 8265 "mov %C0,%B0", op, plen, 4); 8266 8267 default: 8268 if (INTVAL (op[2]) < 24) 8269 break; 8270 8271 /* fall through */ 8272 8273 case 23: 8274 return avr_asm_len ("lsl %C0" CR_TAB 8275 "sbc %A0,%A0" CR_TAB 8276 "mov %B0,%A0" CR_TAB 8277 "mov %C0,%A0", op, plen, 4); 8278 } /* switch */ 8279 } 8280 8281 out_shift_with_cnt ("asr %C0" CR_TAB 8282 "ror %B0" CR_TAB 8283 "ror %A0", insn, op, plen, 3); 8284 return ""; 8285 } 8286 8287 8288 /* 32-bit arithmetic shift right ((signed long)x >> i) */ 8289 8290 const char * 8291 ashrsi3_out (rtx_insn *insn, rtx operands[], int *len) 8292 { 8293 if (CONST_INT_P (operands[2])) 8294 { 8295 int k; 8296 int *t = len; 8297 8298 if (!len) 8299 len = &k; 8300 8301 switch (INTVAL (operands[2])) 8302 { 8303 case 8: 8304 { 8305 int reg0 = true_regnum (operands[0]); 8306 int reg1 = true_regnum (operands[1]); 8307 *len=6; 8308 if (reg0 <= reg1) 8309 return ("mov %A0,%B1" CR_TAB 8310 "mov %B0,%C1" CR_TAB 8311 "mov %C0,%D1" CR_TAB 8312 "clr %D0" CR_TAB 8313 "sbrc %C0,7" CR_TAB 8314 "dec %D0"); 8315 else 8316 return ("clr %D0" CR_TAB 8317 "sbrc %D1,7" CR_TAB 8318 "dec %D0" CR_TAB 8319 "mov %C0,%D1" CR_TAB 8320 "mov %B0,%C1" CR_TAB 8321 "mov %A0,%B1"); 8322 } 8323 8324 case 16: 8325 { 8326 int reg0 = true_regnum (operands[0]); 8327 int reg1 = true_regnum (operands[1]); 8328 8329 if (reg0 == reg1 + 2) 8330 return *len = 4, ("clr %D0" CR_TAB 8331 "sbrc %B0,7" CR_TAB 8332 "com %D0" CR_TAB 8333 "mov %C0,%D0"); 8334 if (AVR_HAVE_MOVW) 8335 return *len = 5, ("movw %A0,%C1" CR_TAB 8336 "clr %D0" CR_TAB 8337 "sbrc %B0,7" CR_TAB 8338 "com %D0" CR_TAB 8339 "mov %C0,%D0"); 8340 else 8341 return *len = 6, ("mov %B0,%D1" CR_TAB 8342 "mov %A0,%C1" CR_TAB 8343 "clr %D0" CR_TAB 8344 "sbrc %B0,7" CR_TAB 8345 "com %D0" CR_TAB 8346 "mov %C0,%D0"); 8347 } 8348 8349 case 24: 8350 return *len = 6, ("mov %A0,%D1" CR_TAB 8351 "clr %D0" CR_TAB 8352 "sbrc %A0,7" CR_TAB 8353 "com %D0" CR_TAB 8354 "mov %B0,%D0" CR_TAB 8355 "mov %C0,%D0"); 8356 8357 default: 8358 if (INTVAL (operands[2]) < 32) 8359 break; 8360 8361 /* fall through */ 8362 8363 case 31: 8364 if (AVR_HAVE_MOVW) 8365 return *len = 4, ("lsl %D0" CR_TAB 8366 "sbc %A0,%A0" CR_TAB 8367 "mov %B0,%A0" CR_TAB 8368 "movw %C0,%A0"); 8369 else 8370 return *len = 5, ("lsl %D0" CR_TAB 8371 "sbc %A0,%A0" CR_TAB 8372 "mov %B0,%A0" CR_TAB 8373 "mov %C0,%A0" CR_TAB 8374 "mov %D0,%A0"); 8375 } 8376 len = t; 8377 } 8378 out_shift_with_cnt ("asr %D0" CR_TAB 8379 "ror %C0" CR_TAB 8380 "ror %B0" CR_TAB 8381 "ror %A0", insn, operands, len, 4); 8382 return ""; 8383 } 8384 8385 /* 8-bit logic shift right ((unsigned char)x >> i) */ 8386 8387 const char * 8388 lshrqi3_out (rtx_insn *insn, rtx operands[], int *len) 8389 { 8390 if (CONST_INT_P (operands[2])) 8391 { 8392 int k; 8393 8394 if (!len) 8395 len = &k; 8396 8397 switch (INTVAL (operands[2])) 8398 { 8399 default: 8400 if (INTVAL (operands[2]) < 8) 8401 break; 8402 8403 *len = 1; 8404 return "clr %0"; 8405 8406 case 1: 8407 *len = 1; 8408 return "lsr %0"; 8409 8410 case 2: 8411 *len = 2; 8412 return ("lsr %0" CR_TAB 8413 "lsr %0"); 8414 case 3: 8415 *len = 3; 8416 return ("lsr %0" CR_TAB 8417 "lsr %0" CR_TAB 8418 "lsr %0"); 8419 8420 case 4: 8421 if (test_hard_reg_class (LD_REGS, operands[0])) 8422 { 8423 *len=2; 8424 return ("swap %0" CR_TAB 8425 "andi %0,0x0f"); 8426 } 8427 *len = 4; 8428 return ("lsr %0" CR_TAB 8429 "lsr %0" CR_TAB 8430 "lsr %0" CR_TAB 8431 "lsr %0"); 8432 8433 case 5: 8434 if (test_hard_reg_class (LD_REGS, operands[0])) 8435 { 8436 *len = 3; 8437 return ("swap %0" CR_TAB 8438 "lsr %0" CR_TAB 8439 "andi %0,0x7"); 8440 } 8441 *len = 5; 8442 return ("lsr %0" CR_TAB 8443 "lsr %0" CR_TAB 8444 "lsr %0" CR_TAB 8445 "lsr %0" CR_TAB 8446 "lsr %0"); 8447 8448 case 6: 8449 if (test_hard_reg_class (LD_REGS, operands[0])) 8450 { 8451 *len = 4; 8452 return ("swap %0" CR_TAB 8453 "lsr %0" CR_TAB 8454 "lsr %0" CR_TAB 8455 "andi %0,0x3"); 8456 } 8457 *len = 6; 8458 return ("lsr %0" CR_TAB 8459 "lsr %0" CR_TAB 8460 "lsr %0" CR_TAB 8461 "lsr %0" CR_TAB 8462 "lsr %0" CR_TAB 8463 "lsr %0"); 8464 8465 case 7: 8466 *len = 3; 8467 return ("bst %1,7" CR_TAB 8468 "clr %0" CR_TAB 8469 "bld %0,0"); 8470 } 8471 } 8472 else if (CONSTANT_P (operands[2])) 8473 fatal_insn ("internal compiler error. Incorrect shift:", insn); 8474 8475 out_shift_with_cnt ("lsr %0", 8476 insn, operands, len, 1); 8477 return ""; 8478 } 8479 8480 /* 16-bit logic shift right ((unsigned short)x >> i) */ 8481 8482 const char * 8483 lshrhi3_out (rtx_insn *insn, rtx operands[], int *len) 8484 { 8485 if (CONST_INT_P (operands[2])) 8486 { 8487 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL 8488 && XVECLEN (PATTERN (insn), 0) == 3 8489 && REG_P (operands[3])); 8490 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]); 8491 int k; 8492 int *t = len; 8493 8494 if (!len) 8495 len = &k; 8496 8497 switch (INTVAL (operands[2])) 8498 { 8499 default: 8500 if (INTVAL (operands[2]) < 16) 8501 break; 8502 8503 *len = 2; 8504 return ("clr %B0" CR_TAB 8505 "clr %A0"); 8506 8507 case 4: 8508 if (optimize_size && scratch) 8509 break; /* 5 */ 8510 if (ldi_ok) 8511 { 8512 *len = 6; 8513 return ("swap %B0" CR_TAB 8514 "swap %A0" CR_TAB 8515 "andi %A0,0x0f" CR_TAB 8516 "eor %A0,%B0" CR_TAB 8517 "andi %B0,0x0f" CR_TAB 8518 "eor %A0,%B0"); 8519 } 8520 if (scratch) 8521 { 8522 *len = 7; 8523 return ("swap %B0" CR_TAB 8524 "swap %A0" CR_TAB 8525 "ldi %3,0x0f" CR_TAB 8526 "and %A0,%3" CR_TAB 8527 "eor %A0,%B0" CR_TAB 8528 "and %B0,%3" CR_TAB 8529 "eor %A0,%B0"); 8530 } 8531 break; /* optimize_size ? 6 : 8 */ 8532 8533 case 5: 8534 if (optimize_size) 8535 break; /* scratch ? 5 : 6 */ 8536 if (ldi_ok) 8537 { 8538 *len = 8; 8539 return ("lsr %B0" CR_TAB 8540 "ror %A0" CR_TAB 8541 "swap %B0" CR_TAB 8542 "swap %A0" CR_TAB 8543 "andi %A0,0x0f" CR_TAB 8544 "eor %A0,%B0" CR_TAB 8545 "andi %B0,0x0f" CR_TAB 8546 "eor %A0,%B0"); 8547 } 8548 if (scratch) 8549 { 8550 *len = 9; 8551 return ("lsr %B0" CR_TAB 8552 "ror %A0" CR_TAB 8553 "swap %B0" CR_TAB 8554 "swap %A0" CR_TAB 8555 "ldi %3,0x0f" CR_TAB 8556 "and %A0,%3" CR_TAB 8557 "eor %A0,%B0" CR_TAB 8558 "and %B0,%3" CR_TAB 8559 "eor %A0,%B0"); 8560 } 8561 break; /* 10 */ 8562 8563 case 6: 8564 if (optimize_size) 8565 break; /* scratch ? 5 : 6 */ 8566 *len = 9; 8567 return ("clr __tmp_reg__" CR_TAB 8568 "lsl %A0" CR_TAB 8569 "rol %B0" CR_TAB 8570 "rol __tmp_reg__" CR_TAB 8571 "lsl %A0" CR_TAB 8572 "rol %B0" CR_TAB 8573 "rol __tmp_reg__" CR_TAB 8574 "mov %A0,%B0" CR_TAB 8575 "mov %B0,__tmp_reg__"); 8576 8577 case 7: 8578 *len = 5; 8579 return ("lsl %A0" CR_TAB 8580 "mov %A0,%B0" CR_TAB 8581 "rol %A0" CR_TAB 8582 "sbc %B0,%B0" CR_TAB 8583 "neg %B0"); 8584 8585 case 8: 8586 return *len = 2, ("mov %A0,%B1" CR_TAB 8587 "clr %B0"); 8588 8589 case 9: 8590 *len = 3; 8591 return ("mov %A0,%B0" CR_TAB 8592 "clr %B0" CR_TAB 8593 "lsr %A0"); 8594 8595 case 10: 8596 *len = 4; 8597 return ("mov %A0,%B0" CR_TAB 8598 "clr %B0" CR_TAB 8599 "lsr %A0" CR_TAB 8600 "lsr %A0"); 8601 8602 case 11: 8603 *len = 5; 8604 return ("mov %A0,%B0" CR_TAB 8605 "clr %B0" CR_TAB 8606 "lsr %A0" CR_TAB 8607 "lsr %A0" CR_TAB 8608 "lsr %A0"); 8609 8610 case 12: 8611 if (ldi_ok) 8612 { 8613 *len = 4; 8614 return ("mov %A0,%B0" CR_TAB 8615 "clr %B0" CR_TAB 8616 "swap %A0" CR_TAB 8617 "andi %A0,0x0f"); 8618 } 8619 if (scratch) 8620 { 8621 *len = 5; 8622 return ("mov %A0,%B0" CR_TAB 8623 "clr %B0" CR_TAB 8624 "swap %A0" CR_TAB 8625 "ldi %3,0x0f" CR_TAB 8626 "and %A0,%3"); 8627 } 8628 *len = 6; 8629 return ("mov %A0,%B0" CR_TAB 8630 "clr %B0" CR_TAB 8631 "lsr %A0" CR_TAB 8632 "lsr %A0" CR_TAB 8633 "lsr %A0" CR_TAB 8634 "lsr %A0"); 8635 8636 case 13: 8637 if (ldi_ok) 8638 { 8639 *len = 5; 8640 return ("mov %A0,%B0" CR_TAB 8641 "clr %B0" CR_TAB 8642 "swap %A0" CR_TAB 8643 "lsr %A0" CR_TAB 8644 "andi %A0,0x07"); 8645 } 8646 if (AVR_HAVE_MUL && scratch) 8647 { 8648 *len = 5; 8649 return ("ldi %3,0x08" CR_TAB 8650 "mul %B0,%3" CR_TAB 8651 "mov %A0,r1" CR_TAB 8652 "clr %B0" CR_TAB 8653 "clr __zero_reg__"); 8654 } 8655 if (optimize_size && scratch) 8656 break; /* 5 */ 8657 if (scratch) 8658 { 8659 *len = 6; 8660 return ("mov %A0,%B0" CR_TAB 8661 "clr %B0" CR_TAB 8662 "swap %A0" CR_TAB 8663 "lsr %A0" CR_TAB 8664 "ldi %3,0x07" CR_TAB 8665 "and %A0,%3"); 8666 } 8667 if (AVR_HAVE_MUL) 8668 { 8669 *len = 6; 8670 return ("set" CR_TAB 8671 "bld r1,3" CR_TAB 8672 "mul %B0,r1" CR_TAB 8673 "mov %A0,r1" CR_TAB 8674 "clr %B0" CR_TAB 8675 "clr __zero_reg__"); 8676 } 8677 *len = 7; 8678 return ("mov %A0,%B0" CR_TAB 8679 "clr %B0" CR_TAB 8680 "lsr %A0" CR_TAB 8681 "lsr %A0" CR_TAB 8682 "lsr %A0" CR_TAB 8683 "lsr %A0" CR_TAB 8684 "lsr %A0"); 8685 8686 case 14: 8687 if (AVR_HAVE_MUL && ldi_ok) 8688 { 8689 *len = 5; 8690 return ("ldi %A0,0x04" CR_TAB 8691 "mul %B0,%A0" CR_TAB 8692 "mov %A0,r1" CR_TAB 8693 "clr %B0" CR_TAB 8694 "clr __zero_reg__"); 8695 } 8696 if (AVR_HAVE_MUL && scratch) 8697 { 8698 *len = 5; 8699 return ("ldi %3,0x04" CR_TAB 8700 "mul %B0,%3" CR_TAB 8701 "mov %A0,r1" CR_TAB 8702 "clr %B0" CR_TAB 8703 "clr __zero_reg__"); 8704 } 8705 if (optimize_size && ldi_ok) 8706 { 8707 *len = 5; 8708 return ("mov %A0,%B0" CR_TAB 8709 "ldi %B0,6" "\n1:\t" 8710 "lsr %A0" CR_TAB 8711 "dec %B0" CR_TAB 8712 "brne 1b"); 8713 } 8714 if (optimize_size && scratch) 8715 break; /* 5 */ 8716 *len = 6; 8717 return ("clr %A0" CR_TAB 8718 "lsl %B0" CR_TAB 8719 "rol %A0" CR_TAB 8720 "lsl %B0" CR_TAB 8721 "rol %A0" CR_TAB 8722 "clr %B0"); 8723 8724 case 15: 8725 *len = 4; 8726 return ("bst %B1,7" CR_TAB 8727 "clr %A0" CR_TAB 8728 "clr %B0" CR_TAB 8729 "bld %A0,0"); 8730 } 8731 len = t; 8732 } 8733 out_shift_with_cnt ("lsr %B0" CR_TAB 8734 "ror %A0", insn, operands, len, 2); 8735 return ""; 8736 } 8737 8738 8739 /* 24-bit logic shift right */ 8740 8741 const char * 8742 avr_out_lshrpsi3 (rtx_insn *insn, rtx *op, int *plen) 8743 { 8744 int dest = REGNO (op[0]); 8745 int src = REGNO (op[1]); 8746 8747 if (CONST_INT_P (op[2])) 8748 { 8749 if (plen) 8750 *plen = 0; 8751 8752 switch (INTVAL (op[2])) 8753 { 8754 case 8: 8755 if (dest <= src) 8756 return avr_asm_len ("mov %A0,%B1" CR_TAB 8757 "mov %B0,%C1" CR_TAB 8758 "clr %C0", op, plen, 3); 8759 else 8760 return avr_asm_len ("clr %C0" CR_TAB 8761 "mov %B0,%C1" CR_TAB 8762 "mov %A0,%B1", op, plen, 3); 8763 8764 case 16: 8765 if (dest != src + 2) 8766 avr_asm_len ("mov %A0,%C1", op, plen, 1); 8767 8768 return avr_asm_len ("clr %B0" CR_TAB 8769 "clr %C0", op, plen, 2); 8770 8771 default: 8772 if (INTVAL (op[2]) < 24) 8773 break; 8774 8775 /* fall through */ 8776 8777 case 23: 8778 return avr_asm_len ("bst %C1,7" CR_TAB 8779 "clr %A0" CR_TAB 8780 "clr %B0" CR_TAB 8781 "clr %C0" CR_TAB 8782 "bld %A0,0", op, plen, 5); 8783 } /* switch */ 8784 } 8785 8786 out_shift_with_cnt ("lsr %C0" CR_TAB 8787 "ror %B0" CR_TAB 8788 "ror %A0", insn, op, plen, 3); 8789 return ""; 8790 } 8791 8792 8793 /* 32-bit logic shift right ((unsigned int)x >> i) */ 8794 8795 const char * 8796 lshrsi3_out (rtx_insn *insn, rtx operands[], int *len) 8797 { 8798 if (CONST_INT_P (operands[2])) 8799 { 8800 int k; 8801 int *t = len; 8802 8803 if (!len) 8804 len = &k; 8805 8806 switch (INTVAL (operands[2])) 8807 { 8808 default: 8809 if (INTVAL (operands[2]) < 32) 8810 break; 8811 8812 if (AVR_HAVE_MOVW) 8813 return *len = 3, ("clr %D0" CR_TAB 8814 "clr %C0" CR_TAB 8815 "movw %A0,%C0"); 8816 *len = 4; 8817 return ("clr %D0" CR_TAB 8818 "clr %C0" CR_TAB 8819 "clr %B0" CR_TAB 8820 "clr %A0"); 8821 8822 case 8: 8823 { 8824 int reg0 = true_regnum (operands[0]); 8825 int reg1 = true_regnum (operands[1]); 8826 *len = 4; 8827 if (reg0 <= reg1) 8828 return ("mov %A0,%B1" CR_TAB 8829 "mov %B0,%C1" CR_TAB 8830 "mov %C0,%D1" CR_TAB 8831 "clr %D0"); 8832 else 8833 return ("clr %D0" CR_TAB 8834 "mov %C0,%D1" CR_TAB 8835 "mov %B0,%C1" CR_TAB 8836 "mov %A0,%B1"); 8837 } 8838 8839 case 16: 8840 { 8841 int reg0 = true_regnum (operands[0]); 8842 int reg1 = true_regnum (operands[1]); 8843 8844 if (reg0 == reg1 + 2) 8845 return *len = 2, ("clr %C0" CR_TAB 8846 "clr %D0"); 8847 if (AVR_HAVE_MOVW) 8848 return *len = 3, ("movw %A0,%C1" CR_TAB 8849 "clr %C0" CR_TAB 8850 "clr %D0"); 8851 else 8852 return *len = 4, ("mov %B0,%D1" CR_TAB 8853 "mov %A0,%C1" CR_TAB 8854 "clr %C0" CR_TAB 8855 "clr %D0"); 8856 } 8857 8858 case 24: 8859 return *len = 4, ("mov %A0,%D1" CR_TAB 8860 "clr %B0" CR_TAB 8861 "clr %C0" CR_TAB 8862 "clr %D0"); 8863 8864 case 31: 8865 if (AVR_HAVE_MOVW) 8866 return *len = 5, ("bst %D1,7" CR_TAB 8867 "clr %A0" CR_TAB 8868 "clr %B0" CR_TAB 8869 "movw %C0,%A0" CR_TAB 8870 "bld %A0,0"); 8871 *len = 6; 8872 return ("bst %D1,7" CR_TAB 8873 "clr %A0" CR_TAB 8874 "clr %B0" CR_TAB 8875 "clr %C0" CR_TAB 8876 "clr %D0" CR_TAB 8877 "bld %A0,0"); 8878 } 8879 len = t; 8880 } 8881 out_shift_with_cnt ("lsr %D0" CR_TAB 8882 "ror %C0" CR_TAB 8883 "ror %B0" CR_TAB 8884 "ror %A0", insn, operands, len, 4); 8885 return ""; 8886 } 8887 8888 8889 /* Output addition of register XOP[0] and compile time constant XOP[2]. 8890 INSN is a single_set insn or an insn pattern. 8891 CODE == PLUS: perform addition by using ADD instructions or 8892 CODE == MINUS: perform addition by using SUB instructions: 8893 8894 XOP[0] = XOP[0] + XOP[2] 8895 8896 Or perform addition/subtraction with register XOP[2] depending on CODE: 8897 8898 XOP[0] = XOP[0] +/- XOP[2] 8899 8900 If PLEN == NULL, print assembler instructions to perform the operation; 8901 otherwise, set *PLEN to the length of the instruction sequence (in words) 8902 printed with PLEN == NULL. XOP[3] is an 8-bit scratch register or NULL_RTX. 8903 8904 CODE_SAT == UNKNOWN: Perform ordinary, non-saturating operation. 8905 CODE_SAT != UNKNOWN: Perform operation and saturate according to CODE_SAT. 8906 If CODE_SAT != UNKNOWN then SIGN contains the sign of the summand resp. 8907 the subtrahend in the original insn, provided it is a compile time constant. 8908 In all other cases, SIGN is 0. 8909 8910 If OUT_LABEL is true, print the final 0: label which is needed for 8911 saturated addition / subtraction. The only case where OUT_LABEL = false 8912 is useful is for saturated addition / subtraction performed during 8913 fixed-point rounding, cf. `avr_out_round'. */ 8914 8915 static void 8916 avr_out_plus_1 (rtx insn, rtx *xop, int *plen, enum rtx_code code, 8917 enum rtx_code code_sat, int sign, bool out_label) 8918 { 8919 /* MODE of the operation. */ 8920 machine_mode mode = GET_MODE (xop[0]); 8921 8922 /* INT_MODE of the same size. */ 8923 scalar_int_mode imode = int_mode_for_mode (mode).require (); 8924 8925 /* Number of bytes to operate on. */ 8926 int n_bytes = GET_MODE_SIZE (mode); 8927 8928 /* Value (0..0xff) held in clobber register op[3] or -1 if unknown. */ 8929 int clobber_val = -1; 8930 8931 /* op[0]: 8-bit destination register 8932 op[1]: 8-bit const int 8933 op[2]: 8-bit scratch register */ 8934 rtx op[3]; 8935 8936 /* Started the operation? Before starting the operation we may skip 8937 adding 0. This is no more true after the operation started because 8938 carry must be taken into account. */ 8939 bool started = false; 8940 8941 /* Value to add. There are two ways to add VAL: R += VAL and R -= -VAL. */ 8942 rtx xval = xop[2]; 8943 8944 /* Output a BRVC instruction. Only needed with saturation. */ 8945 bool out_brvc = true; 8946 8947 if (plen) 8948 *plen = 0; 8949 8950 if (REG_P (xop[2])) 8951 { 8952 for (int i = 0; i < n_bytes; i++) 8953 { 8954 /* We operate byte-wise on the destination. */ 8955 op[0] = simplify_gen_subreg (QImode, xop[0], mode, i); 8956 op[1] = simplify_gen_subreg (QImode, xop[2], mode, i); 8957 8958 if (i == 0) 8959 avr_asm_len (code == PLUS ? "add %0,%1" : "sub %0,%1", 8960 op, plen, 1); 8961 else 8962 avr_asm_len (code == PLUS ? "adc %0,%1" : "sbc %0,%1", 8963 op, plen, 1); 8964 } 8965 8966 if (reg_overlap_mentioned_p (xop[0], xop[2])) 8967 { 8968 gcc_assert (REGNO (xop[0]) == REGNO (xop[2])); 8969 8970 if (MINUS == code) 8971 return; 8972 } 8973 8974 goto saturate; 8975 } 8976 8977 if (CONST_FIXED_P (xval)) 8978 xval = avr_to_int_mode (xval); 8979 8980 /* Adding/Subtracting zero is a no-op. */ 8981 8982 if (xval == const0_rtx) 8983 return; 8984 8985 if (MINUS == code) 8986 xval = simplify_unary_operation (NEG, imode, xval, imode); 8987 8988 op[2] = xop[3]; 8989 8990 if (SS_PLUS == code_sat && MINUS == code 8991 && sign < 0 8992 && 0x80 == (INTVAL (simplify_gen_subreg (QImode, xval, imode, n_bytes-1)) 8993 & GET_MODE_MASK (QImode))) 8994 { 8995 /* We compute x + 0x80 by means of SUB instructions. We negated the 8996 constant subtrahend above and are left with x - (-128) so that we 8997 need something like SUBI r,128 which does not exist because SUBI sets 8998 V according to the sign of the subtrahend. Notice the only case 8999 where this must be done is when NEG overflowed in case [2s] because 9000 the V computation needs the right sign of the subtrahend. */ 9001 9002 rtx msb = simplify_gen_subreg (QImode, xop[0], mode, n_bytes - 1); 9003 9004 avr_asm_len ("subi %0,128" CR_TAB 9005 "brmi 0f", &msb, plen, 2); 9006 out_brvc = false; 9007 9008 goto saturate; 9009 } 9010 9011 for (int i = 0; i < n_bytes; i++) 9012 { 9013 /* We operate byte-wise on the destination. */ 9014 rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i); 9015 rtx xval8 = simplify_gen_subreg (QImode, xval, imode, i); 9016 9017 /* 8-bit value to operate with this byte. */ 9018 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode); 9019 9020 /* Registers R16..R31 can operate with immediate. */ 9021 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8); 9022 9023 op[0] = reg8; 9024 op[1] = gen_int_mode (val8, QImode); 9025 9026 /* To get usable cc0 no low-bytes must have been skipped. */ 9027 9028 if (!started 9029 && i % 2 == 0 9030 && i + 2 <= n_bytes 9031 && avr_adiw_reg_p (reg8)) 9032 { 9033 rtx xval16 = simplify_gen_subreg (HImode, xval, imode, i); 9034 unsigned int val16 = UINTVAL (xval16) & GET_MODE_MASK (HImode); 9035 9036 /* Registers R24, X, Y, Z can use ADIW/SBIW with constants < 64 9037 i.e. operate word-wise. */ 9038 9039 if (val16 < 64) 9040 { 9041 if (val16 != 0) 9042 { 9043 started = true; 9044 avr_asm_len (code == PLUS ? "adiw %0,%1" : "sbiw %0,%1", 9045 op, plen, 1); 9046 } 9047 9048 i++; 9049 continue; 9050 } 9051 } 9052 9053 if (AVR_TINY 9054 && optimize 9055 && i == 0 9056 && n_bytes == 2 9057 // When that pass adjusts the frame pointer, then we know that 9058 // reg Y points to ordinary memory, and the only side-effect 9059 // of -Y and Y+ is the side effect on Y. 9060 && avr_fuse_add >= 2 9061 && frame_pointer_needed 9062 && REGNO (xop[0]) == FRAME_POINTER_REGNUM) 9063 { 9064 if (INSN_P (insn) 9065 && _reg_unused_after (as_a <rtx_insn *> (insn), xop[0], false)) 9066 return; 9067 9068 if (AVR_HAVE_8BIT_SP) 9069 { 9070 avr_asm_len ("subi %A0,%n2", xop, plen, 1); 9071 return; 9072 } 9073 else if (xop[2] == const1_rtx || xop[2] == constm1_rtx) 9074 { 9075 avr_asm_len (xop[2] == const1_rtx 9076 ? "ld __tmp_reg__,%a0+" 9077 : "ld __tmp_reg__,-%a0", xop, plen, 1); 9078 return; 9079 } 9080 } 9081 9082 if (val8 == 0) 9083 { 9084 if (started) 9085 avr_asm_len (code == PLUS 9086 ? "adc %0,__zero_reg__" : "sbc %0,__zero_reg__", 9087 op, plen, 1); 9088 continue; 9089 } 9090 else if ((val8 == 1 || val8 == 0xff) 9091 && UNKNOWN == code_sat 9092 && !started 9093 && i == n_bytes - 1) 9094 { 9095 avr_asm_len ((code == PLUS) ^ (val8 == 1) ? "dec %0" : "inc %0", 9096 op, plen, 1); 9097 break; 9098 } 9099 9100 switch (code) 9101 { 9102 case PLUS: 9103 9104 gcc_assert (plen != NULL || (op[2] && REG_P (op[2]))); 9105 9106 if (plen != NULL && UNKNOWN != code_sat) 9107 { 9108 /* This belongs to the x + 0x80 corner case. The code with 9109 ADD instruction is not smaller, thus make this case 9110 expensive so that the caller won't pick it. */ 9111 9112 *plen += 10; 9113 break; 9114 } 9115 9116 if (clobber_val != (int) val8) 9117 avr_asm_len ("ldi %2,%1", op, plen, 1); 9118 clobber_val = (int) val8; 9119 9120 avr_asm_len (started ? "adc %0,%2" : "add %0,%2", op, plen, 1); 9121 9122 break; /* PLUS */ 9123 9124 case MINUS: 9125 9126 if (ld_reg_p) 9127 avr_asm_len (started ? "sbci %0,%1" : "subi %0,%1", op, plen, 1); 9128 else 9129 { 9130 gcc_assert (plen != NULL || REG_P (op[2])); 9131 9132 if (clobber_val != (int) val8) 9133 avr_asm_len ("ldi %2,%1", op, plen, 1); 9134 clobber_val = (int) val8; 9135 9136 avr_asm_len (started ? "sbc %0,%2" : "sub %0,%2", op, plen, 1); 9137 } 9138 9139 break; /* MINUS */ 9140 9141 default: 9142 /* Unknown code */ 9143 gcc_unreachable(); 9144 } 9145 9146 started = true; 9147 9148 } /* for all sub-bytes */ 9149 9150 saturate: 9151 9152 if (UNKNOWN == code_sat) 9153 return; 9154 9155 /* Vanilla addition/subtraction is done. We are left with saturation. 9156 9157 We have to compute A = A <op> B where A is a register and 9158 B is a register or a non-zero compile time constant CONST. 9159 A is register class "r" if unsigned && B is REG. Otherwise, A is in "d". 9160 B stands for the original operand $2 in INSN. In the case of B = CONST, 9161 SIGN in { -1, 1 } is the sign of B. Otherwise, SIGN is 0. 9162 9163 CODE is the instruction flavor we use in the asm sequence to perform <op>. 9164 9165 9166 unsigned 9167 operation | code | sat if | b is | sat value | case 9168 -----------------+-------+----------+--------------+-----------+------- 9169 + as a + b | add | C == 1 | const, reg | u+ = 0xff | [1u] 9170 + as a - (-b) | sub | C == 0 | const | u+ = 0xff | [2u] 9171 - as a - b | sub | C == 1 | const, reg | u- = 0 | [3u] 9172 - as a + (-b) | add | C == 0 | const | u- = 0 | [4u] 9173 9174 9175 signed 9176 operation | code | sat if | b is | sat value | case 9177 -----------------+-------+----------+--------------+-----------+------- 9178 + as a + b | add | V == 1 | const, reg | s+ | [1s] 9179 + as a - (-b) | sub | V == 1 | const | s+ | [2s] 9180 - as a - b | sub | V == 1 | const, reg | s- | [3s] 9181 - as a + (-b) | add | V == 1 | const | s- | [4s] 9182 9183 s+ = b < 0 ? -0x80 : 0x7f 9184 s- = b < 0 ? 0x7f : -0x80 9185 9186 The cases a - b actually perform a - (-(-b)) if B is CONST. 9187 */ 9188 9189 op[0] = simplify_gen_subreg (QImode, xop[0], mode, n_bytes-1); 9190 op[1] = n_bytes > 1 9191 ? simplify_gen_subreg (QImode, xop[0], mode, n_bytes-2) 9192 : NULL_RTX; 9193 9194 bool need_copy = true; 9195 int len_call = 1 + AVR_HAVE_JMP_CALL; 9196 9197 switch (code_sat) 9198 { 9199 default: 9200 gcc_unreachable(); 9201 9202 case SS_PLUS: 9203 case SS_MINUS: 9204 9205 if (out_brvc) 9206 avr_asm_len ("brvc 0f", op, plen, 1); 9207 9208 if (reg_overlap_mentioned_p (xop[0], xop[2])) 9209 { 9210 /* [1s,reg] */ 9211 9212 if (n_bytes == 1) 9213 avr_asm_len ("ldi %0,0x7f" CR_TAB 9214 "adc %0,__zero_reg__", op, plen, 2); 9215 else 9216 avr_asm_len ("ldi %0,0x7f" CR_TAB 9217 "ldi %1,0xff" CR_TAB 9218 "adc %1,__zero_reg__" CR_TAB 9219 "adc %0,__zero_reg__", op, plen, 4); 9220 } 9221 else if (sign == 0 && PLUS == code) 9222 { 9223 /* [1s,reg] */ 9224 9225 op[2] = simplify_gen_subreg (QImode, xop[2], mode, n_bytes-1); 9226 9227 if (n_bytes == 1) 9228 avr_asm_len ("ldi %0,0x80" CR_TAB 9229 "sbrs %2,7" CR_TAB 9230 "dec %0", op, plen, 3); 9231 else 9232 avr_asm_len ("ldi %0,0x80" CR_TAB 9233 "cp %2,%0" CR_TAB 9234 "sbc %1,%1" CR_TAB 9235 "sbci %0,0", op, plen, 4); 9236 } 9237 else if (sign == 0 && MINUS == code) 9238 { 9239 /* [3s,reg] */ 9240 9241 op[2] = simplify_gen_subreg (QImode, xop[2], mode, n_bytes-1); 9242 9243 if (n_bytes == 1) 9244 avr_asm_len ("ldi %0,0x7f" CR_TAB 9245 "sbrs %2,7" CR_TAB 9246 "inc %0", op, plen, 3); 9247 else 9248 avr_asm_len ("ldi %0,0x7f" CR_TAB 9249 "cp %0,%2" CR_TAB 9250 "sbc %1,%1" CR_TAB 9251 "sbci %0,-1", op, plen, 4); 9252 } 9253 else if ((sign < 0) ^ (SS_MINUS == code_sat)) 9254 { 9255 /* [1s,const,B < 0] [2s,B < 0] */ 9256 /* [3s,const,B > 0] [4s,B > 0] */ 9257 9258 if (n_bytes == 8) 9259 { 9260 avr_asm_len ("%~call __clr_8", op, plen, len_call); 9261 need_copy = false; 9262 } 9263 9264 avr_asm_len ("ldi %0,0x80", op, plen, 1); 9265 if (n_bytes > 1 && need_copy) 9266 avr_asm_len ("clr %1", op, plen, 1); 9267 } 9268 else if ((sign > 0) ^ (SS_MINUS == code_sat)) 9269 { 9270 /* [1s,const,B > 0] [2s,B > 0] */ 9271 /* [3s,const,B < 0] [4s,B < 0] */ 9272 9273 if (n_bytes == 8) 9274 { 9275 avr_asm_len ("sec" CR_TAB 9276 "%~call __sbc_8", op, plen, 1 + len_call); 9277 need_copy = false; 9278 } 9279 9280 avr_asm_len ("ldi %0,0x7f", op, plen, 1); 9281 if (n_bytes > 1 && need_copy) 9282 avr_asm_len ("ldi %1,0xff", op, plen, 1); 9283 } 9284 else 9285 gcc_unreachable(); 9286 9287 break; 9288 9289 case US_PLUS: 9290 /* [1u] : [2u] */ 9291 9292 avr_asm_len (PLUS == code ? "brcc 0f" : "brcs 0f", op, plen, 1); 9293 9294 if (n_bytes == 8) 9295 { 9296 if (MINUS == code) 9297 avr_asm_len ("sec", op, plen, 1); 9298 avr_asm_len ("%~call __sbc_8", op, plen, len_call); 9299 9300 need_copy = false; 9301 } 9302 else 9303 { 9304 if (MINUS == code && !test_hard_reg_class (LD_REGS, op[0])) 9305 avr_asm_len ("sec" CR_TAB 9306 "sbc %0,%0", op, plen, 2); 9307 else 9308 avr_asm_len (PLUS == code ? "sbc %0,%0" : "ldi %0,0xff", 9309 op, plen, 1); 9310 } 9311 break; /* US_PLUS */ 9312 9313 case US_MINUS: 9314 /* [4u] : [3u] */ 9315 9316 avr_asm_len (PLUS == code ? "brcs 0f" : "brcc 0f", op, plen, 1); 9317 9318 if (n_bytes == 8) 9319 { 9320 avr_asm_len ("%~call __clr_8", op, plen, len_call); 9321 need_copy = false; 9322 } 9323 else 9324 avr_asm_len ("clr %0", op, plen, 1); 9325 9326 break; 9327 } 9328 9329 /* We set the MSB in the unsigned case and the 2 MSBs in the signed case. 9330 Now copy the right value to the LSBs. */ 9331 9332 if (need_copy && n_bytes > 1) 9333 { 9334 if (US_MINUS == code_sat || US_PLUS == code_sat) 9335 { 9336 avr_asm_len ("mov %1,%0", op, plen, 1); 9337 9338 if (n_bytes > 2) 9339 { 9340 op[0] = xop[0]; 9341 if (AVR_HAVE_MOVW) 9342 avr_asm_len ("movw %0,%1", op, plen, 1); 9343 else 9344 avr_asm_len ("mov %A0,%1" CR_TAB 9345 "mov %B0,%1", op, plen, 2); 9346 } 9347 } 9348 else if (n_bytes > 2) 9349 { 9350 op[0] = xop[0]; 9351 avr_asm_len ("mov %A0,%1" CR_TAB 9352 "mov %B0,%1", op, plen, 2); 9353 } 9354 } 9355 9356 if (need_copy && n_bytes == 8) 9357 { 9358 if (AVR_HAVE_MOVW) 9359 avr_asm_len ("movw %r0+2,%0" CR_TAB 9360 "movw %r0+4,%0", xop, plen, 2); 9361 else 9362 avr_asm_len ("mov %r0+2,%0" CR_TAB 9363 "mov %r0+3,%0" CR_TAB 9364 "mov %r0+4,%0" CR_TAB 9365 "mov %r0+5,%0", xop, plen, 4); 9366 } 9367 9368 if (out_label) 9369 avr_asm_len ("0:", op, plen, 0); 9370 } 9371 9372 9373 /* Output addition/subtraction of register XOP[0] and a constant XOP[2] that 9374 is not a compile-time constant: 9375 9376 XOP[0] = XOP[0] +/- XOP[2] 9377 9378 This is a helper for the function below. The only insns that need this 9379 are additions/subtraction for pointer modes, i.e. HImode and PSImode. */ 9380 9381 static const char * 9382 avr_out_plus_symbol (rtx *xop, enum rtx_code code, int *plen) 9383 { 9384 machine_mode mode = GET_MODE (xop[0]); 9385 9386 /* Only pointer modes want to add symbols. */ 9387 9388 gcc_assert (mode == HImode || mode == PSImode); 9389 9390 avr_asm_len (PLUS == code 9391 ? "subi %A0,lo8(-(%2))" CR_TAB "sbci %B0,hi8(-(%2))" 9392 : "subi %A0,lo8(%2)" CR_TAB "sbci %B0,hi8(%2)", 9393 xop, plen, -2); 9394 9395 if (PSImode == mode) 9396 avr_asm_len (PLUS == code 9397 ? "sbci %C0,hlo8(-(%2))" 9398 : "sbci %C0,hlo8(%2)", xop, plen, 1); 9399 return ""; 9400 } 9401 9402 9403 /* Prepare operands of addition/subtraction to be used with avr_out_plus_1. 9404 9405 INSN is a single_set insn or an insn pattern with a binary operation as 9406 SET_SRC that is one of: PLUS, SS_PLUS, US_PLUS, MINUS, SS_MINUS, US_MINUS. 9407 9408 XOP are the operands of INSN. In the case of 64-bit operations with 9409 constant XOP[] has just one element: The summand/subtrahend in XOP[0]. 9410 The non-saturating insns up to 32 bits may or may not supply a "d" class 9411 scratch as XOP[3]. 9412 9413 If PLEN == NULL output the instructions. 9414 If PLEN != NULL set *PLEN to the length of the sequence in words. 9415 9416 PLEN defaults to NULL. 9417 9418 OUT_LABEL defaults to TRUE. For a description, see AVR_OUT_PLUS_1. 9419 9420 Return "" */ 9421 9422 const char * 9423 avr_out_plus (rtx insn, rtx *xop, int *plen, bool out_label) 9424 { 9425 int len_plus, len_minus; 9426 rtx op[4]; 9427 rtx xpattern = INSN_P (insn) ? single_set (as_a <rtx_insn *> (insn)) : insn; 9428 rtx xdest = SET_DEST (xpattern); 9429 machine_mode mode = GET_MODE (xdest); 9430 scalar_int_mode imode = int_mode_for_mode (mode).require (); 9431 int n_bytes = GET_MODE_SIZE (mode); 9432 enum rtx_code code_sat = GET_CODE (SET_SRC (xpattern)); 9433 enum rtx_code code 9434 = (PLUS == code_sat || SS_PLUS == code_sat || US_PLUS == code_sat 9435 ? PLUS : MINUS); 9436 9437 /* PLUS and MINUS don't saturate: Use modular wrap-around. */ 9438 9439 if (PLUS == code_sat || MINUS == code_sat) 9440 code_sat = UNKNOWN; 9441 9442 if (n_bytes <= 4 && REG_P (xop[2])) 9443 { 9444 avr_out_plus_1 (insn, xop, plen, code, code_sat, 0, out_label); 9445 return ""; 9446 } 9447 9448 if (n_bytes == 8) 9449 { 9450 op[0] = gen_rtx_REG (DImode, ACC_A); 9451 op[1] = gen_rtx_REG (DImode, ACC_A); 9452 op[2] = avr_to_int_mode (xop[0]); 9453 } 9454 else 9455 { 9456 if (!REG_P (xop[2]) 9457 && !CONST_INT_P (xop[2]) 9458 && !CONST_FIXED_P (xop[2])) 9459 { 9460 return avr_out_plus_symbol (xop, code, plen); 9461 } 9462 9463 op[0] = avr_to_int_mode (xop[0]); 9464 op[1] = avr_to_int_mode (xop[1]); 9465 op[2] = avr_to_int_mode (xop[2]); 9466 } 9467 9468 /* Saturations and 64-bit operations don't have a clobber operand. 9469 For the other cases, the caller will provide a proper XOP[3]. */ 9470 9471 xpattern = INSN_P (insn) ? PATTERN (insn) : insn; 9472 op[3] = PARALLEL == GET_CODE (xpattern) ? xop[3] : NULL_RTX; 9473 9474 /* Saturation will need the sign of the original operand. */ 9475 9476 rtx xmsb = simplify_gen_subreg (QImode, op[2], imode, n_bytes-1); 9477 int sign = INTVAL (xmsb) < 0 ? -1 : 1; 9478 9479 /* If we subtract and the subtrahend is a constant, then negate it 9480 so that avr_out_plus_1 can be used. */ 9481 9482 if (MINUS == code) 9483 op[2] = simplify_unary_operation (NEG, imode, op[2], imode); 9484 9485 /* Work out the shortest sequence. */ 9486 9487 avr_out_plus_1 (insn, op, &len_minus, MINUS, code_sat, sign, out_label); 9488 avr_out_plus_1 (insn, op, &len_plus, PLUS, code_sat, sign, out_label); 9489 9490 if (plen) 9491 *plen = (len_minus <= len_plus) ? len_minus : len_plus; 9492 else if (len_minus <= len_plus) 9493 avr_out_plus_1 (insn, op, NULL, MINUS, code_sat, sign, out_label); 9494 else 9495 avr_out_plus_1 (insn, op, NULL, PLUS, code_sat, sign, out_label); 9496 9497 return ""; 9498 } 9499 9500 9501 /* Output an instruction sequence for addition of REG in XOP[0] and CONST_INT 9502 in XOP[1] in such a way that SREG.Z and SREG.N are set according to the 9503 result. XOP[2] might be a d-regs clobber register. If XOP[2] is SCRATCH, 9504 then the addition can be performed without a clobber reg. Return "". 9505 9506 If PLEN == NULL, then output the instructions. 9507 If PLEN != NULL, then set *PLEN to the length of the sequence in words. */ 9508 9509 const char * 9510 avr_out_plus_set_ZN (rtx *xop, int *plen) 9511 { 9512 if (plen) 9513 *plen = 0; 9514 9515 // Register to compare and value to compare against. 9516 rtx xreg = xop[0]; 9517 rtx xval = xop[1]; 9518 9519 machine_mode mode = GET_MODE (xreg); 9520 9521 // Number of bytes to operate on. 9522 int n_bytes = GET_MODE_SIZE (mode); 9523 9524 if (n_bytes == 1) 9525 { 9526 if (INTVAL (xval) == 1) 9527 return avr_asm_len ("inc %0", xop, plen, 1); 9528 9529 if (INTVAL (xval) == -1) 9530 return avr_asm_len ("dec %0", xop, plen, 1); 9531 } 9532 9533 if (n_bytes == 2 9534 && avr_adiw_reg_p (xreg) 9535 && IN_RANGE (INTVAL (xval), 1, 63)) 9536 { 9537 // Add 16-bit value in [1..63] to a w register. 9538 return avr_asm_len ("adiw %0, %1", xop, plen, 1); 9539 } 9540 9541 // Addition won't work; subtract the negative of XVAL instead. 9542 xval = simplify_unary_operation (NEG, mode, xval, mode); 9543 9544 // Value (0..0xff) held in clobber register xop[2] or -1 if unknown. 9545 int clobber_val = -1; 9546 9547 // [0] = Current sub-register. 9548 // [1] = Current partial xval. 9549 // [2] = 8-bit clobber d-register or SCRATCH. 9550 rtx op[3]; 9551 op[2] = xop[2]; 9552 9553 // Work byte-wise from LSB to MSB. The lower two bytes might be 9554 // SBIW'ed in one go. 9555 for (int i = 0; i < n_bytes; ++i) 9556 { 9557 op[0] = simplify_gen_subreg (QImode, xreg, mode, i); 9558 9559 if (i == 0 9560 && n_bytes >= 2 9561 && avr_adiw_reg_p (op[0])) 9562 { 9563 op[1] = simplify_gen_subreg (HImode, xval, mode, 0); 9564 if (IN_RANGE (INTVAL (op[1]), 0, 63)) 9565 { 9566 // SBIW can handle the lower 16 bits. 9567 avr_asm_len ("sbiw %0, %1", op, plen, 1); 9568 9569 // Next byte has already been handled: Skip it. 9570 ++i; 9571 continue; 9572 } 9573 } 9574 9575 op[1] = simplify_gen_subreg (QImode, xval, mode, i); 9576 9577 if (test_hard_reg_class (LD_REGS, op[0])) 9578 { 9579 // d-regs can subtract immediates. 9580 avr_asm_len (i == 0 9581 ? "subi %0, %1" 9582 : "sbci %0, %1", op, plen, 1); 9583 } 9584 else 9585 { 9586 int val8 = 0xff & INTVAL (op[1]); 9587 if (val8 == 0) 9588 { 9589 // Any register can subtract 0. 9590 avr_asm_len (i == 0 9591 ? "sub %0, __zero_reg__" 9592 : "sbc %0, __zero_reg__", op, plen, 1); 9593 } 9594 else 9595 { 9596 // Use d-register to hold partial xval. 9597 9598 if (val8 != clobber_val) 9599 { 9600 // Load partial xval to QI clobber reg and memoize for later. 9601 gcc_assert (REG_P (op[2])); 9602 avr_asm_len ("ldi %2, %1", op, plen, 1); 9603 clobber_val = val8; 9604 } 9605 9606 avr_asm_len (i == 0 9607 ? "sub %0, %2" 9608 : "sbc %0, %2", op, plen, 1); 9609 } 9610 } 9611 } // Loop bytes. 9612 9613 return ""; 9614 } 9615 9616 9617 /* Output bit operation (IOR, AND, XOR) with register XOP[0] and compile 9618 time constant XOP[2]: 9619 9620 XOP[0] = XOP[0] <op> XOP[2] 9621 9622 and return "". If PLEN == NULL, print assembler instructions to perform the 9623 operation; otherwise, set *PLEN to the length of the instruction sequence 9624 (in words) printed with PLEN == NULL. XOP[3] is either an 8-bit clobber 9625 register or SCRATCH if no clobber register is needed for the operation. 9626 INSN is an INSN_P or a pattern of an insn. */ 9627 9628 const char * 9629 avr_out_bitop (rtx insn, rtx *xop, int *plen) 9630 { 9631 /* CODE and MODE of the operation. */ 9632 rtx xpattern = INSN_P (insn) ? single_set (as_a <rtx_insn *> (insn)) : insn; 9633 enum rtx_code code = GET_CODE (SET_SRC (xpattern)); 9634 machine_mode mode = GET_MODE (xop[0]); 9635 9636 /* Number of bytes to operate on. */ 9637 int n_bytes = GET_MODE_SIZE (mode); 9638 9639 /* Value of T-flag (0 or 1) or -1 if unknow. */ 9640 int set_t = -1; 9641 9642 /* Value (0..0xff) held in clobber register op[3] or -1 if unknown. */ 9643 int clobber_val = -1; 9644 9645 /* op[0]: 8-bit destination register 9646 op[1]: 8-bit const int 9647 op[2]: 8-bit clobber register, SCRATCH or NULL_RTX. 9648 op[3]: 8-bit register containing 0xff or NULL_RTX */ 9649 rtx op[4]; 9650 9651 op[2] = QImode == mode ? NULL_RTX : xop[3]; 9652 op[3] = NULL_RTX; 9653 9654 if (plen) 9655 *plen = 0; 9656 9657 for (int i = 0; i < n_bytes; i++) 9658 { 9659 /* We operate byte-wise on the destination. */ 9660 rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i); 9661 rtx xval8 = simplify_gen_subreg (QImode, xop[2], mode, i); 9662 9663 /* 8-bit value to operate with this byte. */ 9664 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode); 9665 9666 /* Number of bits set in the current byte of the constant. */ 9667 int pop8 = popcount_hwi (val8); 9668 9669 /* Registers R16..R31 can operate with immediate. */ 9670 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8); 9671 9672 op[0] = reg8; 9673 op[1] = GEN_INT (val8); 9674 9675 switch (code) 9676 { 9677 case IOR: 9678 9679 if (pop8 == 0) 9680 continue; 9681 else if (ld_reg_p) 9682 avr_asm_len ("ori %0,%1", op, plen, 1); 9683 else if (pop8 == 1) 9684 { 9685 if (set_t != 1) 9686 avr_asm_len ("set", op, plen, 1); 9687 set_t = 1; 9688 9689 op[1] = GEN_INT (exact_log2 (val8)); 9690 avr_asm_len ("bld %0,%1", op, plen, 1); 9691 } 9692 else if (pop8 == 8) 9693 { 9694 if (op[3] != NULL_RTX) 9695 avr_asm_len ("mov %0,%3", op, plen, 1); 9696 else 9697 avr_asm_len ("clr %0" CR_TAB 9698 "dec %0", op, plen, 2); 9699 9700 op[3] = op[0]; 9701 } 9702 else 9703 { 9704 if (clobber_val != (int) val8) 9705 avr_asm_len ("ldi %2,%1", op, plen, 1); 9706 clobber_val = (int) val8; 9707 9708 avr_asm_len ("or %0,%2", op, plen, 1); 9709 } 9710 9711 continue; /* IOR */ 9712 9713 case AND: 9714 9715 if (pop8 == 8) 9716 continue; 9717 else if (pop8 == 0) 9718 avr_asm_len ("clr %0", op, plen, 1); 9719 else if (ld_reg_p) 9720 avr_asm_len ("andi %0,%1", op, plen, 1); 9721 else if (pop8 == 7) 9722 { 9723 if (set_t != 0) 9724 avr_asm_len ("clt", op, plen, 1); 9725 set_t = 0; 9726 9727 op[1] = GEN_INT (exact_log2 (GET_MODE_MASK (QImode) & ~val8)); 9728 avr_asm_len ("bld %0,%1", op, plen, 1); 9729 } 9730 else 9731 { 9732 if (clobber_val != (int) val8) 9733 avr_asm_len ("ldi %2,%1", op, plen, 1); 9734 clobber_val = (int) val8; 9735 9736 avr_asm_len ("and %0,%2", op, plen, 1); 9737 } 9738 9739 continue; /* AND */ 9740 9741 case XOR: 9742 9743 if (pop8 == 0) 9744 continue; 9745 else if (pop8 == 8) 9746 avr_asm_len ("com %0", op, plen, 1); 9747 else if (ld_reg_p && val8 == (1 << 7)) 9748 avr_asm_len ("subi %0,%1", op, plen, 1); 9749 else 9750 { 9751 if (clobber_val != (int) val8) 9752 avr_asm_len ("ldi %2,%1", op, plen, 1); 9753 clobber_val = (int) val8; 9754 9755 avr_asm_len ("eor %0,%2", op, plen, 1); 9756 } 9757 9758 continue; /* XOR */ 9759 9760 default: 9761 /* Unknown rtx_code */ 9762 gcc_unreachable(); 9763 } 9764 } /* for all sub-bytes */ 9765 9766 return ""; 9767 } 9768 9769 9770 /* Output sign extension from XOP[1] to XOP[0] and return "". 9771 If PLEN == NULL, print assembler instructions to perform the operation; 9772 otherwise, set *PLEN to the length of the instruction sequence (in words) 9773 as printed with PLEN == NULL. */ 9774 9775 const char * 9776 avr_out_sign_extend (rtx_insn *insn, rtx *xop, int *plen) 9777 { 9778 // Size in bytes of source resp. destination operand. 9779 unsigned n_src = GET_MODE_SIZE (GET_MODE (xop[1])); 9780 unsigned n_dest = GET_MODE_SIZE (GET_MODE (xop[0])); 9781 rtx r_msb = all_regs_rtx[REGNO (xop[1]) + n_src - 1]; 9782 9783 if (plen) 9784 *plen = 0; 9785 9786 // Copy destination to source 9787 9788 if (REGNO (xop[0]) != REGNO (xop[1])) 9789 { 9790 gcc_assert (n_src <= 2); 9791 9792 if (n_src == 2) 9793 avr_asm_len (AVR_HAVE_MOVW 9794 ? "movw %0,%1" 9795 : "mov %B0,%B1", xop, plen, 1); 9796 if (n_src == 1 || !AVR_HAVE_MOVW) 9797 avr_asm_len ("mov %A0,%A1", xop, plen, 1); 9798 } 9799 9800 // Set Carry to the sign bit MSB.7... 9801 9802 if (REGNO (xop[0]) == REGNO (xop[1]) 9803 || !reg_unused_after (insn, r_msb)) 9804 { 9805 avr_asm_len ("mov __tmp_reg__,%0", &r_msb, plen, 1); 9806 r_msb = tmp_reg_rtx; 9807 } 9808 9809 avr_asm_len ("lsl %0", &r_msb, plen, 1); 9810 9811 // ...and propagate it to all the new sign bits 9812 9813 for (unsigned n = n_src; n < n_dest; n++) 9814 avr_asm_len ("sbc %0,%0", &all_regs_rtx[REGNO (xop[0]) + n], plen, 1); 9815 9816 return ""; 9817 } 9818 9819 9820 /* PLEN == NULL: Output code to add CONST_INT OP[0] to SP. 9821 PLEN != NULL: Set *PLEN to the length of that sequence. 9822 Return "". */ 9823 9824 const char * 9825 avr_out_addto_sp (rtx *op, int *plen) 9826 { 9827 int pc_len = AVR_2_BYTE_PC ? 2 : 3; 9828 int addend = INTVAL (op[0]); 9829 9830 if (plen) 9831 *plen = 0; 9832 9833 if (addend < 0) 9834 { 9835 if (flag_verbose_asm || flag_print_asm_name) 9836 avr_asm_len (ASM_COMMENT_START "SP -= %n0", op, plen, 0); 9837 9838 while (addend <= -pc_len) 9839 { 9840 addend += pc_len; 9841 avr_asm_len ("rcall .", op, plen, 1); 9842 } 9843 9844 while (addend++ < 0) 9845 avr_asm_len ("push __tmp_reg__", op, plen, 1); 9846 } 9847 else if (addend > 0) 9848 { 9849 if (flag_verbose_asm || flag_print_asm_name) 9850 avr_asm_len (ASM_COMMENT_START "SP += %0", op, plen, 0); 9851 9852 while (addend-- > 0) 9853 avr_asm_len ("pop __tmp_reg__", op, plen, 1); 9854 } 9855 9856 return ""; 9857 } 9858 9859 9860 /* Output instructions to insert an inverted bit into OP[0]: $0.$1 = ~$2.$3. 9861 If PLEN = NULL then output the respective instruction sequence which 9862 is a combination of BST / BLD and some instruction(s) to invert the bit. 9863 If PLEN != NULL then store the length of the sequence (in words) in *PLEN. 9864 Return "". */ 9865 9866 const char * 9867 avr_out_insert_notbit (rtx_insn *insn, rtx op[], int *plen) 9868 { 9869 if (INTVAL (op[1]) == 7 9870 && test_hard_reg_class (LD_REGS, op[0])) 9871 { 9872 /* If the inserted bit number is 7 and we have a d-reg, then invert 9873 the bit after the insertion by means of SUBI *,0x80. */ 9874 9875 if (INTVAL (op[3]) == 7 9876 && REGNO (op[0]) == REGNO (op[2])) 9877 { 9878 avr_asm_len ("subi %0,0x80", op, plen, -1); 9879 } 9880 else 9881 { 9882 avr_asm_len ("bst %2,%3" CR_TAB 9883 "bld %0,%1" CR_TAB 9884 "subi %0,0x80", op, plen, -3); 9885 } 9886 } 9887 else if (test_hard_reg_class (LD_REGS, op[0]) 9888 && (INTVAL (op[1]) != INTVAL (op[3]) 9889 || !reg_overlap_mentioned_p (op[0], op[2]))) 9890 { 9891 /* If the destination bit is in a d-reg we can jump depending 9892 on the source bit and use ANDI / ORI. This just applies if we 9893 have not an early-clobber situation with the bit. */ 9894 9895 avr_asm_len ("andi %0,~(1<<%1)" CR_TAB 9896 "sbrs %2,%3" CR_TAB 9897 "ori %0,1<<%1", op, plen, -3); 9898 } 9899 else 9900 { 9901 /* Otherwise, invert the bit by means of COM before we store it with 9902 BST and then undo the COM if needed. */ 9903 9904 avr_asm_len ("com %2" CR_TAB 9905 "bst %2,%3", op, plen, -2); 9906 9907 if (!reg_unused_after (insn, op[2]) 9908 // A simple 'reg_unused_after' is not enough because that function 9909 // assumes that the destination register is overwritten completely 9910 // and hence is in order for our purpose. This is not the case 9911 // with BLD which just changes one bit of the destination. 9912 || reg_overlap_mentioned_p (op[0], op[2])) 9913 { 9914 /* Undo the COM from above. */ 9915 avr_asm_len ("com %2", op, plen, 1); 9916 } 9917 9918 avr_asm_len ("bld %0,%1", op, plen, 1); 9919 } 9920 9921 return ""; 9922 } 9923 9924 9925 /* Output instructions for XOP[0] = (XOP[1] <Shift> XOP[2]) & XOP[3] where 9926 - XOP[0] and XOP[1] have the same mode which is one of: QI, HI, PSI, SI. 9927 - XOP[3] is an exact const_int power of 2. 9928 - XOP[2] and XOP[3] are const_int. 9929 - <Shift> is any of: ASHIFT, LSHIFTRT, ASHIFTRT. 9930 - The result depends on XOP[1]. 9931 or XOP[0] = XOP[1] & XOP[2] where 9932 - XOP[0] and XOP[1] have the same mode which is one of: HI, PSI, SI. 9933 - XOP[2] is an exact const_int power of 2. 9934 Returns "". 9935 PLEN != 0: Set *PLEN to the code length in words. Don't output anything. 9936 PLEN == 0: Output instructions. */ 9937 9938 const char* 9939 avr_out_insv (rtx_insn *insn, rtx xop[], int *plen) 9940 { 9941 machine_mode mode = GET_MODE (xop[0]); 9942 int n_bytes = GET_MODE_SIZE (mode); 9943 rtx xsrc = SET_SRC (single_set (insn)); 9944 9945 gcc_assert (AND == GET_CODE (xsrc)); 9946 9947 rtx xop2 = xop[2]; 9948 rtx xop3 = xop[3]; 9949 9950 if (REG_P (XEXP (xsrc, 0))) 9951 { 9952 // This function can also handle AND with an exact power of 2, 9953 // which can be regarded as a XOP[1] shift with offset 0. 9954 rtx xshift = gen_rtx_ASHIFT (mode, xop[1], const0_rtx); 9955 xsrc = gen_rtx_AND (mode, xshift, xop[2]); 9956 xop3 = xop[2]; 9957 xop2 = const0_rtx; 9958 } 9959 9960 // Any of ASHIFT, LSHIFTRT, ASHIFTRT. 9961 enum rtx_code code = GET_CODE (XEXP (xsrc, 0)); 9962 int shift = code == ASHIFT ? INTVAL (xop2) : -INTVAL (xop2); 9963 9964 // Determines the position of the output bit. 9965 unsigned mask = GET_MODE_MASK (mode) & INTVAL (xop3); 9966 9967 // Position of the output / input bit, respectively. 9968 int obit = exact_log2 (mask); 9969 int ibit = obit - shift; 9970 9971 gcc_assert (IN_RANGE (obit, 0, GET_MODE_BITSIZE (mode) - 1)); 9972 gcc_assert (IN_RANGE (ibit, 0, GET_MODE_BITSIZE (mode) - 1)); 9973 9974 // In the remainder, use the sub-bytes that hold the bits. 9975 rtx op[4] = 9976 { 9977 // Output 9978 simplify_gen_subreg (QImode, xop[0], mode, obit / 8), 9979 GEN_INT (obit & 7), 9980 // Input 9981 simplify_gen_subreg (QImode, xop[1], mode, ibit / 8), 9982 GEN_INT (ibit & 7) 9983 }; 9984 obit &= 7; 9985 ibit &= 7; 9986 9987 // The length of the default sequence at the end of this function. 9988 // We only emit anything other than the default when we find a sequence 9989 // that is strictly shorter than the default sequence; which is: 9990 // BST + <CLR-result-bytes> + BLD. 9991 const int len0 = 2 + n_bytes - (n_bytes == 4 && AVR_HAVE_MOVW); 9992 9993 // Finding something shorter than the default sequence implies that there 9994 // must be at most 2 instructions that deal with the bytes containing the 9995 // relevant bits. In addition, we need N_BYTES - 1 instructions to clear 9996 // the remaining result bytes. 9997 9998 const int n_clr = n_bytes - 1; 9999 bool clr_p = false; 10000 bool andi_p = false; 10001 10002 if (plen) 10003 *plen = 0; 10004 10005 if (REGNO (op[0]) == REGNO (op[2]) 10006 // Output reg allows ANDI. 10007 && test_hard_reg_class (LD_REGS, op[0])) 10008 { 10009 if (1 + n_clr < len0 10010 // Same byte and bit: A single ANDI will do. 10011 && obit == ibit) 10012 { 10013 clr_p = andi_p = true; 10014 } 10015 else if (2 + n_clr < len0 10016 // |obit - ibit| = 4: SWAP + ANDI will do. 10017 && (obit == ibit + 4 || obit == ibit - 4)) 10018 { 10019 avr_asm_len ("swap %0", op, plen, 1); 10020 clr_p = andi_p = true; 10021 } 10022 else if (2 + n_clr < len0 10023 // LSL + ANDI will do. 10024 && obit == ibit + 1) 10025 { 10026 avr_asm_len ("lsl %0", op, plen, 1); 10027 clr_p = andi_p = true; 10028 } 10029 else if (2 + n_clr < len0 10030 // LSR + ANDI will do. 10031 && obit == ibit - 1) 10032 { 10033 avr_asm_len ("lsr %0", op, plen, 1); 10034 clr_p = andi_p = true; 10035 } 10036 } 10037 10038 if (REGNO (op[0]) != REGNO (op[2]) 10039 && obit == ibit) 10040 { 10041 if (2 + n_clr < len0 10042 // Same bit but different byte: MOV + ANDI will do. 10043 && test_hard_reg_class (LD_REGS, op[0])) 10044 { 10045 avr_asm_len ("mov %0,%2", op, plen, 1); 10046 clr_p = andi_p = true; 10047 } 10048 else if (2 + n_clr < len0 10049 // Same bit but different byte: We can use ANDI + MOV, 10050 // but only if the input byte is LD_REGS and unused after. 10051 && test_hard_reg_class (LD_REGS, op[2]) 10052 && reg_unused_after (insn, op[2])) 10053 { 10054 avr_asm_len ("andi %2,1<<%3" CR_TAB 10055 "mov %0,%2", op, plen, 2); 10056 clr_p = true; 10057 } 10058 } 10059 10060 // Output remaining instructions of the shorter sequence. 10061 10062 if (andi_p) 10063 avr_asm_len ("andi %0,1<<%1", op, plen, 1); 10064 10065 if (clr_p) 10066 { 10067 for (int b = 0; b < n_bytes; ++b) 10068 { 10069 rtx byte = simplify_gen_subreg (QImode, xop[0], mode, b); 10070 if (REGNO (byte) != REGNO (op[0])) 10071 avr_asm_len ("clr %0", &byte, plen, 1); 10072 } 10073 10074 // CLR_P means we found a shorter sequence, so we are done now. 10075 return ""; 10076 } 10077 10078 // No shorter sequence found, just emit BST, CLR*, BLD sequence. 10079 10080 avr_asm_len ("bst %2,%3", op, plen, -1); 10081 10082 if (n_bytes == 4 && AVR_HAVE_MOVW) 10083 avr_asm_len ("clr %A0" CR_TAB 10084 "clr %B0" CR_TAB 10085 "movw %C0,%A0", xop, plen, 3); 10086 else 10087 for (int b = 0; b < n_bytes; ++b) 10088 { 10089 rtx byte = simplify_gen_subreg (QImode, xop[0], mode, b); 10090 avr_asm_len ("clr %0", &byte, plen, 1); 10091 } 10092 10093 return avr_asm_len ("bld %0,%1", op, plen, 1); 10094 } 10095 10096 10097 /* Output instructions to extract a bit to 8-bit register XOP[0]. 10098 The input XOP[1] is a register or an 8-bit MEM in the lower I/O range. 10099 XOP[2] is the const_int bit position. Return "". 10100 10101 PLEN != 0: Set *PLEN to the code length in words. Don't output anything. 10102 PLEN == 0: Output instructions. */ 10103 10104 const char * 10105 avr_out_extr (rtx_insn *insn, rtx xop[], int *plen) 10106 { 10107 rtx dest = xop[0]; 10108 rtx src = xop[1]; 10109 int bit = INTVAL (xop[2]); 10110 10111 if (GET_MODE (src) != QImode) 10112 { 10113 src = xop[1] = simplify_gen_subreg (QImode, src, GET_MODE (src), bit / 8); 10114 bit %= 8; 10115 xop[2] = GEN_INT (bit); 10116 } 10117 10118 if (MEM_P (src)) 10119 { 10120 xop[1] = XEXP (src, 0); // address 10121 gcc_assert (low_io_address_operand (xop[1], Pmode)); 10122 10123 return avr_asm_len ("clr %0" CR_TAB 10124 "sbic %i1,%2" CR_TAB 10125 "inc %0", xop, plen, -3); 10126 } 10127 10128 gcc_assert (REG_P (src)); 10129 10130 bool ld_dest_p = test_hard_reg_class (LD_REGS, dest); 10131 bool ld_src_p = test_hard_reg_class (LD_REGS, src); 10132 10133 if (ld_dest_p 10134 && REGNO (src) == REGNO (dest)) 10135 { 10136 if (bit == 0) 10137 return avr_asm_len ("andi %0,1", xop, plen, -1); 10138 if (bit == 1) 10139 return avr_asm_len ("lsr %0" CR_TAB 10140 "andi %0,1", xop, plen, -2); 10141 if (bit == 4) 10142 return avr_asm_len ("swap %0" CR_TAB 10143 "andi %0,1", xop, plen, -2); 10144 } 10145 10146 if (bit == 0 10147 && REGNO (src) != REGNO (dest)) 10148 { 10149 if (ld_dest_p) 10150 return avr_asm_len ("mov %0,%1" CR_TAB 10151 "andi %0,1", xop, plen, -2); 10152 if (ld_src_p 10153 && reg_unused_after (insn, src)) 10154 return avr_asm_len ("andi %1,1" CR_TAB 10155 "mov %0,%1", xop, plen, -2); 10156 } 10157 10158 return avr_asm_len ("bst %1,%2" CR_TAB 10159 "clr %0" CR_TAB 10160 "bld %0,0", xop, plen, -3); 10161 } 10162 10163 10164 /* Output instructions to extract a negated bit to 8-bit register XOP[0]. 10165 The input XOP[1] is an 8-bit register or MEM in the lower I/O range. 10166 XOP[2] is the const_int bit position. Return "". 10167 10168 PLEN != 0: Set *PLEN to the code length in words. Don't output anything. 10169 PLEN == 0: Output instructions. */ 10170 10171 const char * 10172 avr_out_extr_not (rtx_insn * /* insn */, rtx xop[], int *plen) 10173 { 10174 rtx dest = xop[0]; 10175 rtx src = xop[1]; 10176 int bit = INTVAL (xop[2]); 10177 10178 if (MEM_P (src)) 10179 { 10180 xop[1] = XEXP (src, 0); // address 10181 gcc_assert (low_io_address_operand (xop[1], Pmode)); 10182 10183 return avr_asm_len ("clr %0" CR_TAB 10184 "sbis %i1,%2" CR_TAB 10185 "inc %0", xop, plen, -3); 10186 } 10187 10188 gcc_assert (REG_P (src)); 10189 10190 bool ld_src_p = test_hard_reg_class (LD_REGS, src); 10191 10192 if (ld_src_p 10193 && REGNO (src) == REGNO (dest)) 10194 { 10195 if (bit == 0) 10196 return avr_asm_len ("inc %0" CR_TAB 10197 "andi %0,1", xop, plen, -2); 10198 if (bit == 1) 10199 return avr_asm_len ("lsr %0" CR_TAB 10200 "inc %0" CR_TAB 10201 "andi %0,1", xop, plen, -3); 10202 if (bit == 4) 10203 return avr_asm_len ("swap %0" CR_TAB 10204 "inc %0" CR_TAB 10205 "andi %0,1", xop, plen, -3); 10206 } 10207 10208 if (bit == 7 10209 && ld_src_p) 10210 return avr_asm_len ("cpi %1,0x80" CR_TAB 10211 "sbc %0,%0" CR_TAB 10212 "neg %0", xop, plen, -3); 10213 10214 if (REGNO (src) != REGNO (dest)) 10215 return avr_asm_len ("clr %0" CR_TAB 10216 "sbrs %1,%2" CR_TAB 10217 "inc %0", xop, plen, -3); 10218 10219 return avr_asm_len ("clr __tmp_reg__" CR_TAB 10220 "sbrs %1,%2" CR_TAB 10221 "inc __tmp_reg__" CR_TAB 10222 "mov %0,__tmp_reg__", xop, plen, -4); 10223 } 10224 10225 10226 /* Outputs instructions needed for fixed point type conversion. 10227 This includes converting between any fixed point type, as well 10228 as converting to any integer type. Conversion between integer 10229 types is not supported. 10230 10231 Converting signed fractional types requires a bit shift if converting 10232 to or from any unsigned fractional type because the decimal place is 10233 shifted by 1 bit. When the destination is a signed fractional, the sign 10234 is stored in either the carry or T bit. */ 10235 10236 const char * 10237 avr_out_fract (rtx_insn *insn, rtx operands[], bool intsigned, int *plen) 10238 { 10239 rtx xop[6]; 10240 RTX_CODE shift = UNKNOWN; 10241 bool sign_in_carry = false; 10242 bool msb_in_carry = false; 10243 bool lsb_in_tmp_reg = false; 10244 bool lsb_in_carry = false; 10245 bool frac_rounded = false; 10246 const char *code_ashift = "lsl %0"; 10247 10248 10249 #define MAY_CLOBBER(RR) \ 10250 /* Shorthand used below. */ \ 10251 ((sign_bytes \ 10252 && IN_RANGE (RR, dest.regno_msb - sign_bytes + 1, dest.regno_msb)) \ 10253 || (offset && IN_RANGE (RR, dest.regno, dest.regno_msb)) \ 10254 || (reg_unused_after (insn, all_regs_rtx[RR]) \ 10255 && !IN_RANGE (RR, dest.regno, dest.regno_msb))) 10256 10257 struct 10258 { 10259 /* bytes : Length of operand in bytes. 10260 ibyte : Length of integral part in bytes. 10261 fbyte, fbit : Length of fractional part in bytes, bits. */ 10262 10263 bool sbit; 10264 unsigned fbit, bytes, ibyte, fbyte; 10265 unsigned regno, regno_msb; 10266 } dest, src, *val[2] = { &dest, &src }; 10267 10268 if (plen) 10269 *plen = 0; 10270 10271 /* Step 0: Determine information on source and destination operand we 10272 ====== will need in the remainder. */ 10273 10274 for (size_t i = 0; i < ARRAY_SIZE (val); i++) 10275 { 10276 machine_mode mode; 10277 10278 xop[i] = operands[i]; 10279 10280 mode = GET_MODE (xop[i]); 10281 10282 val[i]->bytes = GET_MODE_SIZE (mode); 10283 val[i]->regno = REGNO (xop[i]); 10284 val[i]->regno_msb = REGNO (xop[i]) + val[i]->bytes - 1; 10285 10286 if (SCALAR_INT_MODE_P (mode)) 10287 { 10288 val[i]->sbit = intsigned; 10289 val[i]->fbit = 0; 10290 } 10291 else if (ALL_SCALAR_FIXED_POINT_MODE_P (mode)) 10292 { 10293 val[i]->sbit = SIGNED_SCALAR_FIXED_POINT_MODE_P (mode); 10294 val[i]->fbit = GET_MODE_FBIT (mode); 10295 } 10296 else 10297 fatal_insn ("unsupported fixed-point conversion", insn); 10298 10299 val[i]->fbyte = (1 + val[i]->fbit) / BITS_PER_UNIT; 10300 val[i]->ibyte = val[i]->bytes - val[i]->fbyte; 10301 } 10302 10303 // Byte offset of the decimal point taking into account different place 10304 // of the decimal point in input and output and different register numbers 10305 // of input and output. 10306 int offset = dest.regno - src.regno + dest.fbyte - src.fbyte; 10307 10308 // Number of destination bytes that will come from sign / zero extension. 10309 int sign_bytes = (dest.ibyte - src.ibyte) * (dest.ibyte > src.ibyte); 10310 10311 // Number of bytes at the low end to be filled with zeros. 10312 int zero_bytes = (dest.fbyte - src.fbyte) * (dest.fbyte > src.fbyte); 10313 10314 // Do we have a 16-Bit register that is cleared? 10315 rtx clrw = NULL_RTX; 10316 10317 bool sign_extend = src.sbit && sign_bytes; 10318 10319 if (dest.fbit % 8 == 0 && src.fbit % 8 == 7) 10320 shift = ASHIFT; 10321 else if (dest.fbit % 8 == 7 && src.fbit % 8 == 0) 10322 shift = ASHIFTRT; 10323 else if (dest.fbit % 8 == src.fbit % 8) 10324 shift = UNKNOWN; 10325 else 10326 gcc_unreachable(); 10327 10328 /* If we need to round the fraction part, we might need to save/round it 10329 before clobbering any of it in Step 1. Also, we might want to do 10330 the rounding now to make use of LD_REGS. */ 10331 if (SCALAR_INT_MODE_P (GET_MODE (xop[0])) 10332 && SCALAR_ACCUM_MODE_P (GET_MODE (xop[1])) 10333 && !TARGET_FRACT_CONV_TRUNC) 10334 { 10335 bool overlap 10336 = (src.regno <= 10337 (offset ? dest.regno_msb - sign_bytes : dest.regno + zero_bytes - 1) 10338 && dest.regno - offset -1 >= dest.regno); 10339 unsigned s0 = dest.regno - offset -1; 10340 bool use_src = true; 10341 unsigned sn; 10342 unsigned copied_msb = src.regno_msb; 10343 bool have_carry = false; 10344 10345 if (src.ibyte > dest.ibyte) 10346 copied_msb -= src.ibyte - dest.ibyte; 10347 10348 for (sn = s0; sn <= copied_msb; sn++) 10349 if (!IN_RANGE (sn, dest.regno, dest.regno_msb) 10350 && !reg_unused_after (insn, all_regs_rtx[sn])) 10351 use_src = false; 10352 if (use_src && TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], s0)) 10353 { 10354 avr_asm_len ("tst %0" CR_TAB "brpl 0f", 10355 &all_regs_rtx[src.regno_msb], plen, 2); 10356 sn = src.regno; 10357 if (sn < s0) 10358 { 10359 if (TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], sn)) 10360 avr_asm_len ("cpi %0,1", &all_regs_rtx[sn], plen, 1); 10361 else 10362 avr_asm_len ("sec" CR_TAB 10363 "cpc %0,__zero_reg__", 10364 &all_regs_rtx[sn], plen, 2); 10365 have_carry = true; 10366 } 10367 while (++sn < s0) 10368 avr_asm_len ("cpc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1); 10369 10370 avr_asm_len (have_carry ? "sbci %0,128" : "subi %0,129", 10371 &all_regs_rtx[s0], plen, 1); 10372 for (sn = src.regno + src.fbyte; sn <= copied_msb; sn++) 10373 avr_asm_len ("sbci %0,255", &all_regs_rtx[sn], plen, 1); 10374 avr_asm_len ("\n0:", NULL, plen, 0); 10375 frac_rounded = true; 10376 } 10377 else if (use_src && overlap) 10378 { 10379 avr_asm_len ("clr __tmp_reg__" CR_TAB 10380 "sbrc %1,0" CR_TAB 10381 "dec __tmp_reg__", xop, plen, 1); 10382 sn = src.regno; 10383 if (sn < s0) 10384 { 10385 avr_asm_len ("add %0,__tmp_reg__", &all_regs_rtx[sn], plen, 1); 10386 have_carry = true; 10387 } 10388 10389 while (++sn < s0) 10390 avr_asm_len ("adc %0,__tmp_reg__", &all_regs_rtx[sn], plen, 1); 10391 10392 if (have_carry) 10393 avr_asm_len ("clt" CR_TAB 10394 "bld __tmp_reg__,7" CR_TAB 10395 "adc %0,__tmp_reg__", 10396 &all_regs_rtx[s0], plen, 1); 10397 else 10398 avr_asm_len ("lsr __tmp_reg" CR_TAB 10399 "add %0,__tmp_reg__", 10400 &all_regs_rtx[s0], plen, 2); 10401 for (sn = src.regno + src.fbyte; sn <= copied_msb; sn++) 10402 avr_asm_len ("adc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1); 10403 frac_rounded = true; 10404 } 10405 else if (overlap) 10406 { 10407 bool use_src 10408 = (TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], s0) 10409 && (IN_RANGE (s0, dest.regno, dest.regno_msb) 10410 || reg_unused_after (insn, all_regs_rtx[s0]))); 10411 xop[2] = all_regs_rtx[s0]; 10412 unsigned sn = src.regno; 10413 if (!use_src || sn == s0) 10414 avr_asm_len ("mov __tmp_reg__,%2", xop, plen, 1); 10415 /* We need to consider to-be-discarded bits 10416 if the value is negative. */ 10417 if (sn < s0) 10418 { 10419 avr_asm_len ("tst %0" CR_TAB 10420 "brpl 0f", 10421 &all_regs_rtx[src.regno_msb], plen, 2); 10422 /* Test to-be-discarded bytes for any nozero bits. 10423 ??? Could use OR or SBIW to test two registers at once. */ 10424 if (sn < s0) 10425 avr_asm_len ("cp %0,__zero_reg__", &all_regs_rtx[sn], plen, 1); 10426 10427 while (++sn < s0) 10428 avr_asm_len ("cpc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1); 10429 /* Set bit 0 in __tmp_reg__ if any of the lower bits was set. */ 10430 if (use_src) 10431 avr_asm_len ("breq 0f" CR_TAB 10432 "ori %2,1" 10433 "\n0:\t" "mov __tmp_reg__,%2", 10434 xop, plen, 3); 10435 else 10436 avr_asm_len ("breq 0f" CR_TAB 10437 "set" CR_TAB 10438 "bld __tmp_reg__,0\n0:", 10439 xop, plen, 3); 10440 } 10441 lsb_in_tmp_reg = true; 10442 } 10443 } 10444 10445 /* Step 1: Clear bytes at the low end and copy payload bits from source 10446 ====== to destination. */ 10447 10448 int step = offset < 0 ? 1 : -1; 10449 unsigned d0 = offset < 0 ? dest.regno : dest.regno_msb; 10450 10451 // We cleared at least that number of registers. 10452 int clr_n = 0; 10453 10454 for (; d0 >= dest.regno && d0 <= dest.regno_msb; d0 += step) 10455 { 10456 // Next regno of destination is needed for MOVW 10457 unsigned d1 = d0 + step; 10458 10459 // Current and next regno of source 10460 signed s0 = d0 - offset; 10461 signed s1 = s0 + step; 10462 10463 // Must current resp. next regno be CLRed? This applies to the low 10464 // bytes of the destination that have no associated source bytes. 10465 bool clr0 = s0 < (signed) src.regno; 10466 bool clr1 = s1 < (signed) src.regno && d1 >= dest.regno; 10467 10468 // First gather what code to emit (if any) and additional step to 10469 // apply if a MOVW is in use. xop[2] is destination rtx and xop[3] 10470 // is the source rtx for the current loop iteration. 10471 const char *code = NULL; 10472 int stepw = 0; 10473 10474 if (clr0) 10475 { 10476 if (AVR_HAVE_MOVW && clr1 && clrw) 10477 { 10478 xop[2] = all_regs_rtx[d0 & ~1]; 10479 xop[3] = clrw; 10480 code = "movw %2,%3"; 10481 stepw = step; 10482 } 10483 else 10484 { 10485 xop[2] = all_regs_rtx[d0]; 10486 code = "clr %2"; 10487 10488 if (++clr_n >= 2 10489 && !clrw 10490 && d0 % 2 == (step > 0)) 10491 { 10492 clrw = all_regs_rtx[d0 & ~1]; 10493 } 10494 } 10495 } 10496 else if (offset && s0 <= (signed) src.regno_msb) 10497 { 10498 int movw = AVR_HAVE_MOVW && offset % 2 == 0 10499 && d0 % 2 == (offset > 0) 10500 && d1 <= dest.regno_msb && d1 >= dest.regno 10501 && s1 <= (signed) src.regno_msb && s1 >= (signed) src.regno; 10502 10503 xop[2] = all_regs_rtx[d0 & ~movw]; 10504 xop[3] = all_regs_rtx[s0 & ~movw]; 10505 code = movw ? "movw %2,%3" : "mov %2,%3"; 10506 stepw = step * movw; 10507 } 10508 10509 if (code) 10510 { 10511 if (sign_extend && shift != ASHIFT && !sign_in_carry 10512 && (d0 == src.regno_msb || d0 + stepw == src.regno_msb)) 10513 { 10514 /* We are going to override the sign bit. If we sign-extend, 10515 store the sign in the Carry flag. This is not needed if 10516 the destination will be ASHIFT in the remainder because 10517 the ASHIFT will set Carry without extra instruction. */ 10518 10519 avr_asm_len ("lsl %0", &all_regs_rtx[src.regno_msb], plen, 1); 10520 sign_in_carry = true; 10521 } 10522 10523 unsigned src_msb = dest.regno_msb - sign_bytes - offset + 1; 10524 10525 if (!sign_extend && shift == ASHIFTRT && !msb_in_carry 10526 && src.ibyte > dest.ibyte 10527 && (d0 == src_msb || d0 + stepw == src_msb)) 10528 { 10529 /* We are going to override the MSB. If we shift right, 10530 store the MSB in the Carry flag. This is only needed if 10531 we don't sign-extend becaue with sign-extension the MSB 10532 (the sign) will be produced by the sign extension. */ 10533 10534 avr_asm_len ("lsr %0", &all_regs_rtx[src_msb], plen, 1); 10535 msb_in_carry = true; 10536 } 10537 10538 unsigned src_lsb = dest.regno - offset -1; 10539 10540 if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry 10541 && !lsb_in_tmp_reg 10542 && (d0 == src_lsb || d0 + stepw == src_lsb)) 10543 { 10544 /* We are going to override the new LSB; store it into carry. */ 10545 10546 avr_asm_len ("lsl %0", &all_regs_rtx[src_lsb], plen, 1); 10547 code_ashift = "rol %0"; 10548 lsb_in_carry = true; 10549 } 10550 10551 avr_asm_len (code, xop, plen, 1); 10552 d0 += stepw; 10553 } 10554 } 10555 10556 /* Step 2: Shift destination left by 1 bit position. This might be needed 10557 ====== for signed input and unsigned output. */ 10558 10559 if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry) 10560 { 10561 unsigned s0 = dest.regno - offset -1; 10562 10563 /* n1169 4.1.4 says: 10564 "Conversions from a fixed-point to an integer type round toward zero." 10565 Hence, converting a fract type to integer only gives a non-zero result 10566 for -1. */ 10567 if (SCALAR_INT_MODE_P (GET_MODE (xop[0])) 10568 && SCALAR_FRACT_MODE_P (GET_MODE (xop[1])) 10569 && !TARGET_FRACT_CONV_TRUNC) 10570 { 10571 gcc_assert (s0 == src.regno_msb); 10572 /* Check if the input is -1. We do that by checking if negating 10573 the input causes an integer overflow. */ 10574 unsigned sn = src.regno; 10575 avr_asm_len ("cp __zero_reg__,%0", &all_regs_rtx[sn++], plen, 1); 10576 while (sn <= s0) 10577 avr_asm_len ("cpc __zero_reg__,%0", &all_regs_rtx[sn++], plen, 1); 10578 10579 /* Overflow goes with set carry. Clear carry otherwise. */ 10580 avr_asm_len ("brvs 0f" CR_TAB 10581 "clc\n0:", NULL, plen, 2); 10582 } 10583 /* Likewise, when converting from accumulator types to integer, we 10584 need to round up negative values. */ 10585 else if (SCALAR_INT_MODE_P (GET_MODE (xop[0])) 10586 && SCALAR_ACCUM_MODE_P (GET_MODE (xop[1])) 10587 && !TARGET_FRACT_CONV_TRUNC 10588 && !frac_rounded) 10589 { 10590 bool have_carry = false; 10591 10592 xop[2] = all_regs_rtx[s0]; 10593 if (!lsb_in_tmp_reg && !MAY_CLOBBER (s0)) 10594 avr_asm_len ("mov __tmp_reg__,%2", xop, plen, 1); 10595 avr_asm_len ("tst %0" CR_TAB "brpl 0f", 10596 &all_regs_rtx[src.regno_msb], plen, 2); 10597 if (!lsb_in_tmp_reg) 10598 { 10599 unsigned sn = src.regno; 10600 if (sn < s0) 10601 { 10602 avr_asm_len ("cp __zero_reg__,%0", &all_regs_rtx[sn], 10603 plen, 1); 10604 have_carry = true; 10605 } 10606 while (++sn < s0) 10607 avr_asm_len ("cpc __zero_reg__,%0", &all_regs_rtx[sn], plen, 1); 10608 lsb_in_tmp_reg = !MAY_CLOBBER (s0); 10609 } 10610 /* Add in C and the rounding value 127. */ 10611 /* If the destination msb is a sign byte, and in LD_REGS, 10612 grab it as a temporary. */ 10613 if (sign_bytes 10614 && TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], 10615 dest.regno_msb)) 10616 { 10617 xop[3] = all_regs_rtx[dest.regno_msb]; 10618 avr_asm_len ("ldi %3,127", xop, plen, 1); 10619 avr_asm_len ((have_carry && lsb_in_tmp_reg ? "adc __tmp_reg__,%3" 10620 : have_carry ? "adc %2,%3" 10621 : lsb_in_tmp_reg ? "add __tmp_reg__,%3" 10622 : "add %2,%3"), 10623 xop, plen, 1); 10624 } 10625 else 10626 { 10627 /* Fall back to use __zero_reg__ as a temporary. */ 10628 avr_asm_len ("dec __zero_reg__", NULL, plen, 1); 10629 if (have_carry) 10630 avr_asm_len ("clt" CR_TAB 10631 "bld __zero_reg__,7", NULL, plen, 2); 10632 else 10633 avr_asm_len ("lsr __zero_reg__", NULL, plen, 1); 10634 avr_asm_len (have_carry && lsb_in_tmp_reg 10635 ? "adc __tmp_reg__,__zero_reg__" 10636 : have_carry ? "adc %2,__zero_reg__" 10637 : lsb_in_tmp_reg ? "add __tmp_reg__,__zero_reg__" 10638 : "add %2,__zero_reg__", 10639 xop, plen, 1); 10640 avr_asm_len ("eor __zero_reg__,__zero_reg__", NULL, plen, 1); 10641 } 10642 10643 for (d0 = dest.regno + zero_bytes; 10644 d0 <= dest.regno_msb - sign_bytes; d0++) 10645 avr_asm_len ("adc %0,__zero_reg__", &all_regs_rtx[d0], plen, 1); 10646 10647 avr_asm_len (lsb_in_tmp_reg 10648 ? "\n0:\t" "lsl __tmp_reg__" 10649 : "\n0:\t" "lsl %2", 10650 xop, plen, 1); 10651 } 10652 else if (MAY_CLOBBER (s0)) 10653 avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1); 10654 else 10655 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB 10656 "lsl __tmp_reg__", &all_regs_rtx[s0], plen, 2); 10657 10658 code_ashift = "rol %0"; 10659 lsb_in_carry = true; 10660 } 10661 10662 if (shift == ASHIFT) 10663 { 10664 for (d0 = dest.regno + zero_bytes; 10665 d0 <= dest.regno_msb - sign_bytes; d0++) 10666 { 10667 avr_asm_len (code_ashift, &all_regs_rtx[d0], plen, 1); 10668 code_ashift = "rol %0"; 10669 } 10670 10671 lsb_in_carry = false; 10672 sign_in_carry = true; 10673 } 10674 10675 /* Step 4a: Store MSB in carry if we don't already have it or will produce 10676 ======= it in sign-extension below. */ 10677 10678 if (!sign_extend && shift == ASHIFTRT && !msb_in_carry 10679 && src.ibyte > dest.ibyte) 10680 { 10681 unsigned s0 = dest.regno_msb - sign_bytes - offset + 1; 10682 10683 if (MAY_CLOBBER (s0)) 10684 avr_asm_len ("lsr %0", &all_regs_rtx[s0], plen, 1); 10685 else 10686 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB 10687 "lsr __tmp_reg__", &all_regs_rtx[s0], plen, 2); 10688 10689 msb_in_carry = true; 10690 } 10691 10692 /* Step 3: Sign-extend or zero-extend the destination as needed. 10693 ====== */ 10694 10695 if (sign_extend && !sign_in_carry) 10696 { 10697 unsigned s0 = src.regno_msb; 10698 10699 if (MAY_CLOBBER (s0)) 10700 avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1); 10701 else 10702 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB 10703 "lsl __tmp_reg__", &all_regs_rtx[s0], plen, 2); 10704 10705 sign_in_carry = true; 10706 } 10707 10708 gcc_assert (sign_in_carry + msb_in_carry + lsb_in_carry <= 1); 10709 10710 unsigned copies = 0; 10711 rtx movw = sign_extend ? NULL_RTX : clrw; 10712 10713 for (d0 = dest.regno_msb - sign_bytes + 1; d0 <= dest.regno_msb; d0++) 10714 { 10715 if (AVR_HAVE_MOVW && movw 10716 && d0 % 2 == 0 && d0 + 1 <= dest.regno_msb) 10717 { 10718 xop[2] = all_regs_rtx[d0]; 10719 xop[3] = movw; 10720 avr_asm_len ("movw %2,%3", xop, plen, 1); 10721 d0++; 10722 } 10723 else 10724 { 10725 avr_asm_len (sign_extend ? "sbc %0,%0" : "clr %0", 10726 &all_regs_rtx[d0], plen, 1); 10727 10728 if (++copies >= 2 && !movw && d0 % 2 == 1) 10729 movw = all_regs_rtx[d0-1]; 10730 } 10731 } /* for */ 10732 10733 10734 /* Step 4: Right shift the destination. This might be needed for 10735 ====== conversions from unsigned to signed. */ 10736 10737 if (shift == ASHIFTRT) 10738 { 10739 const char *code_ashiftrt = "lsr %0"; 10740 10741 if (sign_extend || msb_in_carry) 10742 code_ashiftrt = "ror %0"; 10743 10744 if (src.sbit && src.ibyte == dest.ibyte) 10745 code_ashiftrt = "asr %0"; 10746 10747 for (d0 = dest.regno_msb - sign_bytes; 10748 d0 >= dest.regno + zero_bytes - 1 && d0 >= dest.regno; d0--) 10749 { 10750 avr_asm_len (code_ashiftrt, &all_regs_rtx[d0], plen, 1); 10751 code_ashiftrt = "ror %0"; 10752 } 10753 } 10754 10755 #undef MAY_CLOBBER 10756 10757 return ""; 10758 } 10759 10760 10761 /* Output fixed-point rounding. XOP[0] = XOP[1] is the operand to round. 10762 XOP[2] is the rounding point, a CONST_INT. The function prints the 10763 instruction sequence if PLEN = NULL and computes the length in words 10764 of the sequence if PLEN != NULL. Most of this function deals with 10765 preparing operands for calls to `avr_out_plus' and `avr_out_bitop'. */ 10766 10767 const char * 10768 avr_out_round (rtx_insn * /*insn*/, rtx *xop, int *plen) 10769 { 10770 scalar_mode mode = as_a <scalar_mode> (GET_MODE (xop[0])); 10771 scalar_int_mode imode = int_mode_for_mode (mode).require (); 10772 // The smallest fractional bit not cleared by the rounding is 2^(-RP). 10773 int fbit = (int) GET_MODE_FBIT (mode); 10774 double_int i_add = double_int_zero.set_bit (fbit-1 - INTVAL (xop[2])); 10775 wide_int wi_add = wi::set_bit_in_zero (fbit-1 - INTVAL (xop[2]), 10776 GET_MODE_PRECISION (imode)); 10777 // Lengths of PLUS and AND parts. 10778 int len_add = 0, *plen_add = plen ? &len_add : NULL; 10779 int len_and = 0, *plen_and = plen ? &len_and : NULL; 10780 10781 // Add-Saturate 1/2 * 2^(-RP). Don't print the label "0:" when printing 10782 // the saturated addition so that we can emit the "rjmp 1f" before the 10783 // "0:" below. 10784 10785 rtx xadd = const_fixed_from_double_int (i_add, mode); 10786 rtx xpattern, xsrc, op[4]; 10787 10788 xsrc = SIGNED_FIXED_POINT_MODE_P (mode) 10789 ? gen_rtx_SS_PLUS (mode, xop[1], xadd) 10790 : gen_rtx_US_PLUS (mode, xop[1], xadd); 10791 xpattern = gen_rtx_SET (xop[0], xsrc); 10792 10793 op[0] = xop[0]; 10794 op[1] = xop[1]; 10795 op[2] = xadd; 10796 avr_out_plus (xpattern, op, plen_add, false /* Don't print "0:" */); 10797 10798 avr_asm_len ("rjmp 1f" CR_TAB 10799 "0:", NULL, plen_add, 1); 10800 10801 // Keep all bits from RP and higher: ... 2^(-RP) 10802 // Clear all bits from RP+1 and lower: 2^(-RP-1) ... 10803 // Rounding point ^^^^^^^ 10804 // Added above ^^^^^^^^^ 10805 rtx xreg = simplify_gen_subreg (imode, xop[0], mode, 0); 10806 rtx xmask = immed_wide_int_const (-wi_add - wi_add, imode); 10807 10808 xpattern = gen_rtx_SET (xreg, gen_rtx_AND (imode, xreg, xmask)); 10809 10810 op[0] = xreg; 10811 op[1] = xreg; 10812 op[2] = xmask; 10813 op[3] = gen_rtx_SCRATCH (QImode); 10814 avr_out_bitop (xpattern, op, plen_and); 10815 avr_asm_len ("1:", NULL, plen, 0); 10816 10817 if (plen) 10818 *plen = len_add + len_and; 10819 10820 return ""; 10821 } 10822 10823 10824 /* Create RTL split patterns for byte sized rotate expressions. This 10825 produces a series of move instructions and considers overlap situations. 10826 Overlapping non-HImode operands need a scratch register. */ 10827 10828 bool 10829 avr_rotate_bytes (rtx operands[]) 10830 { 10831 machine_mode mode = GET_MODE (operands[0]); 10832 bool overlapped = reg_overlap_mentioned_p (operands[0], operands[1]); 10833 bool same_reg = rtx_equal_p (operands[0], operands[1]); 10834 int num = INTVAL (operands[2]); 10835 rtx scratch = operands[3]; 10836 /* Work out if byte or word move is needed. Odd byte rotates need QImode. 10837 Word move if no scratch is needed, otherwise use size of scratch. */ 10838 machine_mode move_mode = QImode; 10839 10840 if (num & 0xf) 10841 move_mode = QImode; 10842 else if ((mode == SImode && !same_reg) || !overlapped) 10843 move_mode = HImode; 10844 else 10845 move_mode = GET_MODE (scratch); 10846 10847 /* Force DI rotate to use QI moves since other DI moves are currently split 10848 into QI moves so forward propagation works better. */ 10849 if (mode == DImode) 10850 move_mode = QImode; 10851 /* Make scratch smaller if needed. */ 10852 if (SCRATCH != GET_CODE (scratch) 10853 && HImode == GET_MODE (scratch) 10854 && QImode == move_mode) 10855 scratch = simplify_gen_subreg (move_mode, scratch, HImode, 0); 10856 10857 int move_size = GET_MODE_SIZE (move_mode); 10858 /* Number of bytes/words to rotate. */ 10859 int offset = (num >> 3) / move_size; 10860 /* Number of moves needed. */ 10861 int size = GET_MODE_SIZE (mode) / move_size; 10862 /* Himode byte swap is special case to avoid a scratch register. */ 10863 if (mode == HImode && same_reg) 10864 { 10865 /* HImode byte swap, using xor. This is as quick as using scratch. */ 10866 rtx src, dst; 10867 src = simplify_gen_subreg (move_mode, operands[1], mode, 0); 10868 dst = simplify_gen_subreg (move_mode, operands[0], mode, 1); 10869 if (!rtx_equal_p (dst, src)) 10870 { 10871 emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src)); 10872 emit_move_insn (src, gen_rtx_XOR (QImode, src, dst)); 10873 emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src)); 10874 } 10875 } 10876 else 10877 { 10878 #define MAX_SIZE 8 /* GET_MODE_SIZE (DImode) / GET_MODE_SIZE (QImode) */ 10879 /* Create linked list of moves to determine move order. */ 10880 struct { 10881 rtx src, dst; 10882 int links; 10883 } move[MAX_SIZE + 8]; 10884 int blocked, moves; 10885 10886 gcc_assert (size <= MAX_SIZE); 10887 /* Generate list of subreg moves. */ 10888 for (int i = 0; i < size; i++) 10889 { 10890 int from = i; 10891 int to = (from + offset) % size; 10892 move[i].src = simplify_gen_subreg (move_mode, operands[1], 10893 mode, from * move_size); 10894 move[i].dst = simplify_gen_subreg (move_mode, operands[0], 10895 mode, to * move_size); 10896 move[i].links = -1; 10897 } 10898 /* Mark dependence where a dst of one move is the src of another move. 10899 The first move is a conflict as it must wait until second is 10900 performed. We ignore moves to self - we catch this later. */ 10901 if (overlapped) 10902 for (int i = 0; i < size; i++) 10903 if (reg_overlap_mentioned_p (move[i].dst, operands[1])) 10904 for (int j = 0; j < size; j++) 10905 if (j != i && rtx_equal_p (move[j].src, move[i].dst)) 10906 { 10907 /* The dst of move i is the src of move j. */ 10908 move[i].links = j; 10909 break; 10910 } 10911 10912 blocked = -1; 10913 moves = 0; 10914 /* Go through move list and perform non-conflicting moves. As each 10915 non-overlapping move is made, it may remove other conflicts 10916 so the process is repeated until no conflicts remain. */ 10917 do 10918 { 10919 blocked = -1; 10920 moves = 0; 10921 /* Emit move where dst is not also a src or we have used that 10922 src already. */ 10923 for (int i = 0; i < size; i++) 10924 if (move[i].src != NULL_RTX) 10925 { 10926 if (move[i].links == -1 10927 || move[move[i].links].src == NULL_RTX) 10928 { 10929 moves++; 10930 /* Ignore NOP moves to self. */ 10931 if (!rtx_equal_p (move[i].dst, move[i].src)) 10932 emit_move_insn (move[i].dst, move[i].src); 10933 10934 /* Remove conflict from list. */ 10935 move[i].src = NULL_RTX; 10936 } 10937 else 10938 blocked = i; 10939 } 10940 10941 /* Check for deadlock. This is when no moves occurred and we have 10942 at least one blocked move. */ 10943 if (moves == 0 && blocked != -1) 10944 { 10945 /* Need to use scratch register to break deadlock. 10946 Add move to put dst of blocked move into scratch. 10947 When this move occurs, it will break chain deadlock. 10948 The scratch register is substituted for real move. */ 10949 10950 gcc_assert (SCRATCH != GET_CODE (scratch)); 10951 10952 move[size].src = move[blocked].dst; 10953 move[size].dst = scratch; 10954 /* Scratch move is never blocked. */ 10955 move[size].links = -1; 10956 /* Make sure we have valid link. */ 10957 gcc_assert (move[blocked].links != -1); 10958 /* Replace src of blocking move with scratch reg. */ 10959 move[move[blocked].links].src = scratch; 10960 /* Make dependent on scratch move occurring. */ 10961 move[blocked].links = size; 10962 size=size+1; 10963 } 10964 } 10965 while (blocked != -1); 10966 } 10967 return true; 10968 } 10969 10970 10971 /* Worker function for `ADJUST_INSN_LENGTH'. */ 10972 /* Modifies the length assigned to instruction INSN 10973 LEN is the initially computed length of the insn. */ 10974 10975 int 10976 avr_adjust_insn_length (rtx_insn *insn, int len) 10977 { 10978 rtx *op = recog_data.operand; 10979 10980 /* As we pretend jump tables in .text, fix branch offsets crossing jump 10981 tables now. */ 10982 10983 if (JUMP_TABLE_DATA_P (insn)) 10984 return 0; 10985 10986 /* Some complex insns don't need length adjustment and therefore 10987 the length need not/must not be adjusted for these insns. 10988 It is easier to state this in an insn attribute "adjust_len" than 10989 to clutter up code here... */ 10990 10991 if (!NONDEBUG_INSN_P (insn) || recog_memoized (insn) == -1) 10992 { 10993 return len; 10994 } 10995 10996 /* Read from insn attribute "adjust_len" if/how length is to be adjusted. */ 10997 10998 enum attr_adjust_len adjust_len = get_attr_adjust_len (insn); 10999 11000 if (adjust_len == ADJUST_LEN_NO) 11001 { 11002 /* Nothing to adjust: The length from attribute "length" is fine. 11003 This is the default. */ 11004 11005 return len; 11006 } 11007 11008 /* Extract insn's operands. */ 11009 11010 extract_constrain_insn_cached (insn); 11011 11012 /* Dispatch to right function. */ 11013 11014 switch (adjust_len) 11015 { 11016 case ADJUST_LEN_RELOAD_IN16: output_reload_inhi (op, op[2], &len); break; 11017 case ADJUST_LEN_RELOAD_IN24: avr_out_reload_inpsi (op, op[2], &len); break; 11018 case ADJUST_LEN_RELOAD_IN32: output_reload_insisf (op, op[2], &len); break; 11019 11020 case ADJUST_LEN_OUT_BITOP: avr_out_bitop (insn, op, &len); break; 11021 case ADJUST_LEN_EXTR_NOT: avr_out_extr_not (insn, op, &len); break; 11022 case ADJUST_LEN_EXTR: avr_out_extr (insn, op, &len); break; 11023 case ADJUST_LEN_INSV: avr_out_insv (insn, op, &len); break; 11024 11025 case ADJUST_LEN_PLUS: avr_out_plus (insn, op, &len); break; 11026 case ADJUST_LEN_ADDTO_SP: avr_out_addto_sp (op, &len); break; 11027 11028 case ADJUST_LEN_MOV8: output_movqi (insn, op, &len); break; 11029 case ADJUST_LEN_MOV16: output_movhi (insn, op, &len); break; 11030 case ADJUST_LEN_MOV24: avr_out_movpsi (insn, op, &len); break; 11031 case ADJUST_LEN_MOV32: output_movsisf (insn, op, &len); break; 11032 case ADJUST_LEN_CPYMEM: avr_out_cpymem (insn, op, &len); break; 11033 case ADJUST_LEN_XLOAD: avr_out_xload (insn, op, &len); break; 11034 case ADJUST_LEN_SEXT: avr_out_sign_extend (insn, op, &len); break; 11035 11036 case ADJUST_LEN_SFRACT: avr_out_fract (insn, op, true, &len); break; 11037 case ADJUST_LEN_UFRACT: avr_out_fract (insn, op, false, &len); break; 11038 case ADJUST_LEN_ROUND: avr_out_round (insn, op, &len); break; 11039 11040 case ADJUST_LEN_TSTHI: avr_out_tsthi (insn, op, &len); break; 11041 case ADJUST_LEN_TSTPSI: avr_out_tstpsi (insn, op, &len); break; 11042 case ADJUST_LEN_TSTSI: avr_out_tstsi (insn, op, &len); break; 11043 case ADJUST_LEN_COMPARE: avr_out_compare (insn, op, &len); break; 11044 case ADJUST_LEN_COMPARE64: avr_out_compare64 (insn, op, &len); break; 11045 case ADJUST_LEN_CMP_UEXT: avr_out_cmp_ext (op, ZERO_EXTEND, &len); break; 11046 case ADJUST_LEN_CMP_SEXT: avr_out_cmp_ext (op, SIGN_EXTEND, &len); break; 11047 11048 case ADJUST_LEN_LSHRQI: lshrqi3_out (insn, op, &len); break; 11049 case ADJUST_LEN_LSHRHI: lshrhi3_out (insn, op, &len); break; 11050 case ADJUST_LEN_LSHRSI: lshrsi3_out (insn, op, &len); break; 11051 11052 case ADJUST_LEN_ASHRQI: ashrqi3_out (insn, op, &len); break; 11053 case ADJUST_LEN_ASHRHI: ashrhi3_out (insn, op, &len); break; 11054 case ADJUST_LEN_ASHRSI: ashrsi3_out (insn, op, &len); break; 11055 11056 case ADJUST_LEN_ASHLQI: ashlqi3_out (insn, op, &len); break; 11057 case ADJUST_LEN_ASHLHI: ashlhi3_out (insn, op, &len); break; 11058 case ADJUST_LEN_ASHLSI: ashlsi3_out (insn, op, &len); break; 11059 11060 case ADJUST_LEN_ASHLPSI: avr_out_ashlpsi3 (insn, op, &len); break; 11061 case ADJUST_LEN_ASHRPSI: avr_out_ashrpsi3 (insn, op, &len); break; 11062 case ADJUST_LEN_LSHRPSI: avr_out_lshrpsi3 (insn, op, &len); break; 11063 11064 case ADJUST_LEN_CALL: len = AVR_HAVE_JMP_CALL ? 2 : 1; break; 11065 11066 case ADJUST_LEN_INSERT_BITS: avr_out_insert_bits (op, &len); break; 11067 case ADJUST_LEN_ADD_SET_ZN: avr_out_plus_set_ZN (op, &len); break; 11068 11069 case ADJUST_LEN_INSV_NOTBIT: avr_out_insert_notbit (insn, op, &len); break; 11070 11071 default: 11072 gcc_unreachable(); 11073 } 11074 11075 return len; 11076 } 11077 11078 /* Return nonzero if register REG dead after INSN. */ 11079 11080 int 11081 reg_unused_after (rtx_insn *insn, rtx reg) 11082 { 11083 return (dead_or_set_p (insn, reg) 11084 || (REG_P (reg) && _reg_unused_after (insn, reg, true))); 11085 } 11086 11087 /* A helper for the previous function. 11088 Return nonzero if REG is not used after INSN. 11089 We assume REG is a reload reg, and therefore does 11090 not live past labels. It may live past calls or jumps though. */ 11091 11092 bool 11093 _reg_unused_after (rtx_insn *insn, rtx reg, bool look_at_insn) 11094 { 11095 if (look_at_insn) 11096 { 11097 /* If the reg is set by this instruction, then it is safe for our 11098 case. Disregard the case where this is a store to memory, since 11099 we are checking a register used in the store address. */ 11100 rtx set = single_set (insn); 11101 if (set && !MEM_P (SET_DEST (set)) 11102 && reg_overlap_mentioned_p (reg, SET_DEST (set))) 11103 return 1; 11104 } 11105 11106 while ((insn = NEXT_INSN (insn))) 11107 { 11108 rtx set; 11109 enum rtx_code code = GET_CODE (insn); 11110 11111 #if 0 11112 /* If this is a label that existed before reload, then the register 11113 if dead here. However, if this is a label added by reorg, then 11114 the register may still be live here. We can't tell the difference, 11115 so we just ignore labels completely. */ 11116 if (code == CODE_LABEL) 11117 return 1; 11118 /* else */ 11119 #endif 11120 11121 if (!INSN_P (insn)) 11122 continue; 11123 11124 if (code == JUMP_INSN) 11125 return 0; 11126 11127 /* If this is a sequence, we must handle them all at once. 11128 We could have for instance a call that sets the target register, 11129 and an insn in a delay slot that uses the register. In this case, 11130 we must return 0. */ 11131 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE) 11132 { 11133 rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (insn)); 11134 int retval = 0; 11135 11136 for (int i = 0; i < seq->len (); i++) 11137 { 11138 rtx_insn *this_insn = seq->insn (i); 11139 rtx set = single_set (this_insn); 11140 11141 if (CALL_P (this_insn)) 11142 code = CALL_INSN; 11143 else if (JUMP_P (this_insn)) 11144 { 11145 if (INSN_ANNULLED_BRANCH_P (this_insn)) 11146 return 0; 11147 code = JUMP_INSN; 11148 } 11149 11150 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set))) 11151 return 0; 11152 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set))) 11153 { 11154 if (!MEM_P (SET_DEST (set))) 11155 retval = 1; 11156 else 11157 return 0; 11158 } 11159 if (set == 0 11160 && reg_overlap_mentioned_p (reg, PATTERN (this_insn))) 11161 return 0; 11162 } 11163 if (retval == 1) 11164 return 1; 11165 else if (code == JUMP_INSN) 11166 return 0; 11167 } 11168 11169 if (code == CALL_INSN) 11170 { 11171 rtx tem; 11172 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1)) 11173 if (GET_CODE (XEXP (tem, 0)) == USE 11174 && REG_P (XEXP (XEXP (tem, 0), 0)) 11175 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0))) 11176 return 0; 11177 if (call_used_or_fixed_reg_p (REGNO (reg))) 11178 return 1; 11179 } 11180 11181 set = single_set (insn); 11182 11183 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set))) 11184 return 0; 11185 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set))) 11186 return !MEM_P (SET_DEST (set)); 11187 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn))) 11188 return 0; 11189 } 11190 return 1; 11191 } 11192 11193 11194 /* Implement `TARGET_ASM_INTEGER'. */ 11195 /* Target hook for assembling integer objects. The AVR version needs 11196 special handling for references to certain labels. */ 11197 11198 static bool 11199 avr_assemble_integer (rtx x, unsigned int size, int aligned_p) 11200 { 11201 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p 11202 && text_segment_operand (x, VOIDmode)) 11203 { 11204 fputs ("\t.word\tgs(", asm_out_file); 11205 output_addr_const (asm_out_file, x); 11206 fputs (")\n", asm_out_file); 11207 11208 return true; 11209 } 11210 else if (GET_MODE (x) == PSImode) 11211 { 11212 /* This needs binutils 2.23+, see PR binutils/13503 */ 11213 11214 fputs ("\t.byte\tlo8(", asm_out_file); 11215 output_addr_const (asm_out_file, x); 11216 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file); 11217 11218 fputs ("\t.byte\thi8(", asm_out_file); 11219 output_addr_const (asm_out_file, x); 11220 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file); 11221 11222 fputs ("\t.byte\thh8(", asm_out_file); 11223 output_addr_const (asm_out_file, x); 11224 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file); 11225 11226 return true; 11227 } 11228 else if (CONST_FIXED_P (x)) 11229 { 11230 /* varasm fails to handle big fixed modes that don't fit in hwi. */ 11231 11232 for (unsigned n = 0; n < size; n++) 11233 { 11234 rtx xn = simplify_gen_subreg (QImode, x, GET_MODE (x), n); 11235 default_assemble_integer (xn, 1, aligned_p); 11236 } 11237 11238 return true; 11239 } 11240 11241 if (AVR_TINY 11242 && avr_address_tiny_pm_p (x)) 11243 { 11244 x = plus_constant (Pmode, x, avr_arch->flash_pm_offset); 11245 } 11246 11247 return default_assemble_integer (x, size, aligned_p); 11248 } 11249 11250 /* Implement `TARGET_CLASS_MAX_NREGS'. Reasons described in comments for 11251 avr_hard_regno_nregs. */ 11252 11253 static unsigned char 11254 avr_class_max_nregs (reg_class_t rclass, machine_mode mode) 11255 { 11256 if (rclass == CC_REG && mode == CCmode) 11257 return 1; 11258 11259 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); 11260 } 11261 11262 11263 /* Implement `TARGET_CLASS_LIKELY_SPILLED_P'. */ 11264 /* Return value is nonzero if pseudos that have been 11265 assigned to registers of class CLASS would likely be spilled 11266 because registers of CLASS are needed for spill registers. */ 11267 11268 static bool 11269 avr_class_likely_spilled_p (reg_class_t c) 11270 { 11271 return (c != ALL_REGS 11272 && (AVR_TINY ? 1 : c != ADDW_REGS)); 11273 } 11274 11275 11276 /* Valid attributes: 11277 progmem - Put data to program memory. 11278 signal - Make a function to be hardware interrupt. 11279 After function prologue interrupts remain disabled. 11280 interrupt - Make a function to be hardware interrupt. Before function 11281 prologue interrupts are enabled by means of SEI. 11282 naked - Don't generate function prologue/epilogue and RET 11283 instruction. */ 11284 11285 /* Handle a "progmem" attribute; arguments as in 11286 struct attribute_spec.handler. */ 11287 11288 static tree 11289 avr_handle_progmem_attribute (tree *node, tree name, tree args, 11290 int /*flags*/, bool *no_add_attrs) 11291 { 11292 if (DECL_P (*node)) 11293 { 11294 if (TREE_CODE (*node) == TYPE_DECL) 11295 { 11296 /* This is really a decl attribute, not a type attribute, 11297 but try to handle it for GCC 3.0 backwards compatibility. */ 11298 11299 tree type = TREE_TYPE (*node); 11300 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type)); 11301 tree newtype = build_type_attribute_variant (type, attr); 11302 11303 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type); 11304 TREE_TYPE (*node) = newtype; 11305 *no_add_attrs = true; 11306 } 11307 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node)) 11308 { 11309 *no_add_attrs = false; 11310 } 11311 else 11312 { 11313 warning (OPT_Wattributes, "%qE attribute ignored", 11314 name); 11315 *no_add_attrs = true; 11316 } 11317 } 11318 11319 return NULL_TREE; 11320 } 11321 11322 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in 11323 struct attribute_spec.handler. */ 11324 11325 static tree 11326 avr_handle_fndecl_attribute (tree *node, tree name, tree /*args*/, 11327 int /*flags*/, bool *no_add_attrs) 11328 { 11329 if (TREE_CODE (*node) != FUNCTION_DECL) 11330 { 11331 warning (OPT_Wattributes, "%qE attribute only applies to functions", 11332 name); 11333 *no_add_attrs = true; 11334 } 11335 11336 return NULL_TREE; 11337 } 11338 11339 static tree 11340 avr_handle_fntype_attribute (tree *node, tree name, tree /*args*/, 11341 int /*flags*/, bool *no_add_attrs) 11342 { 11343 if (TREE_CODE (*node) != FUNCTION_TYPE) 11344 { 11345 warning (OPT_Wattributes, "%qE attribute only applies to functions", 11346 name); 11347 *no_add_attrs = true; 11348 } 11349 11350 return NULL_TREE; 11351 } 11352 11353 static tree 11354 avr_handle_absdata_attribute (tree *node, tree name, tree /* args */, 11355 int /* flags */, bool *no_add) 11356 { 11357 location_t loc = DECL_SOURCE_LOCATION (*node); 11358 11359 if (AVR_TINY) 11360 { 11361 if (TREE_CODE (*node) != VAR_DECL 11362 || (!TREE_STATIC (*node) && !DECL_EXTERNAL (*node))) 11363 { 11364 warning_at (loc, OPT_Wattributes, "%qE attribute only applies to" 11365 " variables in static storage", name); 11366 *no_add = true; 11367 } 11368 } 11369 else 11370 { 11371 warning_at (loc, OPT_Wattributes, "%qE attribute only supported" 11372 " for reduced Tiny cores", name); 11373 *no_add = true; 11374 } 11375 11376 return NULL_TREE; 11377 } 11378 11379 static tree 11380 avr_handle_addr_attribute (tree *node, tree name, tree args, 11381 int /*flags*/, bool *no_add) 11382 { 11383 bool io_p = startswith (IDENTIFIER_POINTER (name), "io"); 11384 HOST_WIDE_INT io_start = avr_arch->sfr_offset; 11385 HOST_WIDE_INT io_end = strcmp (IDENTIFIER_POINTER (name), "io_low") == 0 11386 ? io_start + 0x1f 11387 : io_start + 0x3f; 11388 location_t loc = DECL_SOURCE_LOCATION (*node); 11389 11390 if (!VAR_P (*node)) 11391 { 11392 warning_at (loc, OPT_Wattributes, "%qE attribute only applies to " 11393 "variables", name); 11394 *no_add = true; 11395 return NULL_TREE; 11396 } 11397 11398 if (args != NULL_TREE) 11399 { 11400 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR) 11401 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0); 11402 tree arg = TREE_VALUE (args); 11403 if (TREE_CODE (arg) != INTEGER_CST) 11404 { 11405 warning_at (loc, OPT_Wattributes, "%qE attribute allows only an " 11406 "integer constant argument", name); 11407 *no_add = true; 11408 } 11409 else if (io_p 11410 && (!tree_fits_shwi_p (arg) 11411 || ! IN_RANGE (TREE_INT_CST_LOW (arg), io_start, io_end))) 11412 { 11413 warning_at (loc, OPT_Wattributes, "%qE attribute address out of range" 11414 " 0x%x%s0x%x", name, (int) io_start, "...", (int) io_end); 11415 *no_add = true; 11416 } 11417 else 11418 { 11419 tree attribs = DECL_ATTRIBUTES (*node); 11420 const char *names[] = { "io", "io_low", "address", NULL }; 11421 for (const char **p = names; *p; p++) 11422 { 11423 tree other = lookup_attribute (*p, attribs); 11424 if (other && TREE_VALUE (other)) 11425 { 11426 warning_at (loc, OPT_Wattributes, 11427 "both %s and %qE attribute provide address", 11428 *p, name); 11429 *no_add = true; 11430 break; 11431 } 11432 } 11433 } 11434 } 11435 11436 if (*no_add == false && io_p && !TREE_THIS_VOLATILE (*node)) 11437 warning_at (loc, OPT_Wattributes, "%qE attribute on non-volatile variable", 11438 name); 11439 11440 // Optimizers must not draw any conclusions from "static int addr;" etc. 11441 // because the contents of `addr' are not given by its initializer but 11442 // by the contents at the address as specified by the attribute. 11443 if (VAR_P (*node) && ! *no_add) 11444 TREE_THIS_VOLATILE (*node) = 1; 11445 11446 return NULL_TREE; 11447 } 11448 11449 rtx 11450 avr_eval_addr_attrib (rtx x) 11451 { 11452 if (SYMBOL_REF_P (x) 11453 && (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_ADDRESS)) 11454 { 11455 tree decl = SYMBOL_REF_DECL (x); 11456 tree attr = NULL_TREE; 11457 11458 if (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_IO) 11459 { 11460 attr = lookup_attribute ("io", DECL_ATTRIBUTES (decl)); 11461 if (!attr || !TREE_VALUE (attr)) 11462 attr = lookup_attribute ("io_low", DECL_ATTRIBUTES (decl)); 11463 } 11464 if (!attr || !TREE_VALUE (attr)) 11465 attr = lookup_attribute ("address", DECL_ATTRIBUTES (decl)); 11466 gcc_assert (attr && TREE_VALUE (attr) && TREE_VALUE (TREE_VALUE (attr))); 11467 return GEN_INT (TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)))); 11468 } 11469 return x; 11470 } 11471 11472 11473 /* AVR attributes. */ 11474 TARGET_GNU_ATTRIBUTES (avr_attribute_table, 11475 { 11476 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, 11477 affects_type_identity, handler, exclude } */ 11478 { "progmem", 0, 0, false, false, false, false, 11479 avr_handle_progmem_attribute, NULL }, 11480 { "signal", 0, 0, true, false, false, false, 11481 avr_handle_fndecl_attribute, NULL }, 11482 { "interrupt", 0, 0, true, false, false, false, 11483 avr_handle_fndecl_attribute, NULL }, 11484 { "no_gccisr", 0, 0, true, false, false, false, 11485 avr_handle_fndecl_attribute, NULL }, 11486 { "naked", 0, 0, false, true, true, false, 11487 avr_handle_fntype_attribute, NULL }, 11488 { "OS_task", 0, 0, false, true, true, false, 11489 avr_handle_fntype_attribute, NULL }, 11490 { "OS_main", 0, 0, false, true, true, false, 11491 avr_handle_fntype_attribute, NULL }, 11492 { "io", 0, 1, true, false, false, false, 11493 avr_handle_addr_attribute, NULL }, 11494 { "io_low", 0, 1, true, false, false, false, 11495 avr_handle_addr_attribute, NULL }, 11496 { "address", 1, 1, true, false, false, false, 11497 avr_handle_addr_attribute, NULL }, 11498 { "absdata", 0, 0, true, false, false, false, 11499 avr_handle_absdata_attribute, NULL } 11500 }); 11501 11502 11503 /* Return true if we support address space AS for the architecture in effect 11504 and false, otherwise. If LOC is not UNKNOWN_LOCATION then also issue 11505 a respective error. */ 11506 11507 bool 11508 avr_addr_space_supported_p (addr_space_t as, location_t loc) 11509 { 11510 if (AVR_TINY) 11511 { 11512 if (loc != UNKNOWN_LOCATION) 11513 error_at (loc, "address spaces are not supported for reduced " 11514 "Tiny devices"); 11515 return false; 11516 } 11517 else if (avr_addrspace[as].segment >= avr_n_flash) 11518 { 11519 if (loc != UNKNOWN_LOCATION) 11520 error_at (loc, "address space %qs not supported for devices with " 11521 "flash size up to %d KiB", avr_addrspace[as].name, 11522 64 * avr_n_flash); 11523 return false; 11524 } 11525 11526 return true; 11527 } 11528 11529 11530 /* Implement `TARGET_ADDR_SPACE_DIAGNOSE_USAGE'. */ 11531 11532 static void 11533 avr_addr_space_diagnose_usage (addr_space_t as, location_t loc) 11534 { 11535 (void) avr_addr_space_supported_p (as, loc); 11536 } 11537 11538 11539 /* Implement `TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID'. Zero is a valid 11540 address in all address spaces. Even in ADDR_SPACE_FLASH1 etc.., 11541 a zero address is valid and means 0x<RAMPZ val>0000, where RAMPZ is 11542 set to the appropriate segment value. */ 11543 11544 static bool 11545 avr_addr_space_zero_address_valid (addr_space_t) 11546 { 11547 return true; 11548 } 11549 11550 11551 /* Look if DECL shall be placed in program memory space by 11552 means of attribute `progmem' or some address-space qualifier. 11553 Return non-zero if DECL is data that must end up in Flash and 11554 zero if the data lives in RAM (.bss, .data, .rodata, ...). 11555 11556 Return 2 if DECL is located in 24-bit flash address-space 11557 Return 1 if DECL is located in 16-bit flash address-space 11558 Return -1 if attribute `progmem' occurs in DECL or ATTRIBUTES 11559 Return 0 otherwise */ 11560 11561 int 11562 avr_progmem_p (tree decl, tree attributes) 11563 { 11564 if (TREE_CODE (decl) != VAR_DECL) 11565 return 0; 11566 11567 if (avr_decl_memx_p (decl)) 11568 return 2; 11569 11570 if (avr_decl_flash_p (decl)) 11571 return 1; 11572 11573 if (NULL_TREE 11574 != lookup_attribute ("progmem", attributes)) 11575 return -1; 11576 11577 tree a = decl; 11578 11579 do 11580 a = TREE_TYPE(a); 11581 while (TREE_CODE (a) == ARRAY_TYPE); 11582 11583 if (a == error_mark_node) 11584 return 0; 11585 11586 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a))) 11587 return -1; 11588 11589 return 0; 11590 } 11591 11592 11593 /* Return true if DECL has attribute `absdata' set. This function should 11594 only be used for AVR_TINY. */ 11595 11596 static bool 11597 avr_decl_absdata_p (tree decl, tree attributes) 11598 { 11599 return (VAR_P (decl) 11600 && NULL_TREE != lookup_attribute ("absdata", attributes)); 11601 } 11602 11603 11604 /* Scan type TYP for pointer references to address space ASn. 11605 Return ADDR_SPACE_GENERIC (i.e. 0) if all pointers targeting 11606 the AS are also declared to be CONST. 11607 Otherwise, return the respective address space, i.e. a value != 0. */ 11608 11609 static addr_space_t 11610 avr_nonconst_pointer_addrspace (tree typ) 11611 { 11612 while (ARRAY_TYPE == TREE_CODE (typ)) 11613 typ = TREE_TYPE (typ); 11614 11615 if (POINTER_TYPE_P (typ)) 11616 { 11617 tree target = TREE_TYPE (typ); 11618 11619 /* Pointer to function: Test the function's return type. */ 11620 11621 if (FUNCTION_TYPE == TREE_CODE (target)) 11622 return avr_nonconst_pointer_addrspace (TREE_TYPE (target)); 11623 11624 /* "Ordinary" pointers... */ 11625 11626 while (TREE_CODE (target) == ARRAY_TYPE) 11627 target = TREE_TYPE (target); 11628 11629 /* Pointers to non-generic address space must be const. */ 11630 11631 addr_space_t as = TYPE_ADDR_SPACE (target); 11632 11633 if (!ADDR_SPACE_GENERIC_P (as) 11634 && !TYPE_READONLY (target) 11635 && avr_addr_space_supported_p (as)) 11636 { 11637 return as; 11638 } 11639 11640 /* Scan pointer's target type. */ 11641 11642 return avr_nonconst_pointer_addrspace (target); 11643 } 11644 11645 return ADDR_SPACE_GENERIC; 11646 } 11647 11648 11649 /* Sanity check NODE so that all pointers targeting non-generic address spaces 11650 go along with CONST qualifier. Writing to these address spaces should 11651 be detected and complained about as early as possible. */ 11652 11653 static bool 11654 avr_pgm_check_var_decl (tree node) 11655 { 11656 const char *reason = NULL; 11657 11658 addr_space_t as = ADDR_SPACE_GENERIC; 11659 11660 gcc_assert (as == 0); 11661 11662 if (avr_log.progmem) 11663 avr_edump ("%?: %t\n", node); 11664 11665 switch (TREE_CODE (node)) 11666 { 11667 default: 11668 break; 11669 11670 case VAR_DECL: 11671 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as) 11672 reason = _("variable"); 11673 break; 11674 11675 case PARM_DECL: 11676 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as) 11677 reason = _("function parameter"); 11678 break; 11679 11680 case FIELD_DECL: 11681 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as) 11682 reason = _("structure field"); 11683 break; 11684 11685 case FUNCTION_DECL: 11686 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (TREE_TYPE (node))), 11687 as) 11688 reason = _("return type of function"); 11689 break; 11690 11691 case POINTER_TYPE: 11692 if (as = avr_nonconst_pointer_addrspace (node), as) 11693 reason = _("pointer"); 11694 break; 11695 } 11696 11697 if (reason) 11698 { 11699 if (TYPE_P (node)) 11700 error ("pointer targeting address space %qs must be const in %qT", 11701 avr_addrspace[as].name, node); 11702 else 11703 error ("pointer targeting address space %qs must be const" 11704 " in %s %q+D", 11705 avr_addrspace[as].name, reason, node); 11706 } 11707 11708 return reason == NULL; 11709 } 11710 11711 11712 /* Implement `TARGET_INSERT_ATTRIBUTES'. */ 11713 11714 static void 11715 avr_insert_attributes (tree node, tree *attributes) 11716 { 11717 if (VAR_P (node) 11718 && ! TREE_STATIC (node) 11719 && ! DECL_EXTERNAL (node)) 11720 { 11721 const char *names[] = { "io", "io_low", "address", NULL }; 11722 for (const char **p = names; *p; ++p) 11723 if (lookup_attribute (*p, *attributes)) 11724 error ("variable %q+D with attribute %qs must be located in " 11725 "static storage", node, *p); 11726 } 11727 11728 avr_pgm_check_var_decl (node); 11729 11730 if (TARGET_MAIN_IS_OS_TASK 11731 && TREE_CODE (node) == FUNCTION_DECL 11732 && MAIN_NAME_P (DECL_NAME (node)) 11733 // FIXME: We'd like to also test `flag_hosted' which is only 11734 // available in the C-ish fronts, hence no such test for now. 11735 // Instead, we test the return type of "main" which is not exactly 11736 // the same but good enough. 11737 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (node))) 11738 && NULL == lookup_attribute ("OS_task", *attributes)) 11739 { 11740 *attributes = tree_cons (get_identifier ("OS_task"), 11741 NULL, *attributes); 11742 } 11743 11744 /* Add the section attribute if the variable is in progmem. */ 11745 11746 if (VAR_P (node) 11747 && (TREE_STATIC (node) || DECL_EXTERNAL (node)) 11748 && avr_progmem_p (node, *attributes)) 11749 { 11750 tree node0 = node; 11751 11752 /* For C++, we have to peel arrays in order to get correct 11753 determination of readonlyness. */ 11754 11755 do 11756 node0 = TREE_TYPE (node0); 11757 while (TREE_CODE (node0) == ARRAY_TYPE); 11758 11759 if (error_mark_node == node0) 11760 return; 11761 11762 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (node)); 11763 11764 if (!TYPE_READONLY (node0) 11765 && !TREE_READONLY (node)) 11766 { 11767 const char *reason = "__attribute__((progmem))"; 11768 11769 if (!ADDR_SPACE_GENERIC_P (as)) 11770 reason = avr_addrspace[as].name; 11771 11772 if (avr_log.progmem) 11773 avr_edump ("\n%?: %t\n%t\n", node, node0); 11774 11775 error ("variable %q+D must be const in order to be put into" 11776 " read-only section by means of %qs", node, reason); 11777 } 11778 } 11779 } 11780 11781 #ifdef HAVE_LD_AVR_AVRXMEGA2_FLMAP 11782 static const bool have_avrxmega2_flmap = true; 11783 #else 11784 static const bool have_avrxmega2_flmap = false; 11785 #endif 11786 11787 #ifdef HAVE_LD_AVR_AVRXMEGA4_FLMAP 11788 static const bool have_avrxmega4_flmap = true; 11789 #else 11790 static const bool have_avrxmega4_flmap = false; 11791 #endif 11792 11793 #ifdef HAVE_LD_AVR_AVRXMEGA3_RODATA_IN_FLASH 11794 static const bool have_avrxmega3_rodata_in_flash = true; 11795 #else 11796 static const bool have_avrxmega3_rodata_in_flash = false; 11797 #endif 11798 11799 11800 static bool 11801 avr_rodata_in_flash_p () 11802 { 11803 switch (avr_arch_index) 11804 { 11805 default: 11806 break; 11807 11808 case ARCH_AVRTINY: 11809 return true; 11810 11811 case ARCH_AVRXMEGA3: 11812 return have_avrxmega3_rodata_in_flash; 11813 11814 case ARCH_AVRXMEGA2: 11815 return avr_flmap && have_avrxmega2_flmap && avr_rodata_in_ram != 1; 11816 11817 case ARCH_AVRXMEGA4: 11818 return avr_flmap && have_avrxmega4_flmap && avr_rodata_in_ram != 1; 11819 } 11820 11821 return false; 11822 } 11823 11824 11825 /* Implement `ASM_OUTPUT_ALIGNED_DECL_LOCAL'. */ 11826 /* Implement `ASM_OUTPUT_ALIGNED_DECL_COMMON'. */ 11827 /* Track need of __do_clear_bss. */ 11828 11829 void 11830 avr_asm_output_aligned_decl_common (FILE *stream, tree /* decl */, 11831 const char *name, 11832 unsigned HOST_WIDE_INT size, 11833 unsigned int align, bool local_p) 11834 { 11835 /* __gnu_lto_slim is just a marker for the linker injected by toplev.cc. 11836 There is no need to trigger __do_clear_bss code for them. */ 11837 11838 if (!startswith (name, "__gnu_lto")) 11839 avr_need_clear_bss_p = true; 11840 11841 if (local_p) 11842 ASM_OUTPUT_ALIGNED_LOCAL (stream, name, size, align); 11843 else 11844 ASM_OUTPUT_ALIGNED_COMMON (stream, name, size, align); 11845 } 11846 11847 11848 /* Implement `ASM_OUTPUT_ALIGNED_BSS'. */ 11849 11850 void 11851 avr_asm_asm_output_aligned_bss (FILE *file, tree decl, const char *name, 11852 unsigned HOST_WIDE_INT size, int align, 11853 void (*default_func) 11854 (FILE *, tree, const char *, 11855 unsigned HOST_WIDE_INT, int)) 11856 { 11857 if (!startswith (name, "__gnu_lto")) 11858 avr_need_clear_bss_p = true; 11859 11860 default_func (file, decl, name, size, align); 11861 } 11862 11863 11864 /* Unnamed section callback for data_section 11865 to track need of __do_copy_data. */ 11866 11867 static void 11868 avr_output_data_section_asm_op (const char *data) 11869 { 11870 avr_need_copy_data_p = true; 11871 11872 /* Dispatch to default. */ 11873 output_section_asm_op (data); 11874 } 11875 11876 11877 /* Unnamed section callback for bss_section 11878 to track need of __do_clear_bss. */ 11879 11880 static void 11881 avr_output_bss_section_asm_op (const char *data) 11882 { 11883 avr_need_clear_bss_p = true; 11884 11885 /* Dispatch to default. */ 11886 output_section_asm_op (data); 11887 } 11888 11889 11890 /* Unnamed section callback for progmem*.data sections. */ 11891 11892 static void 11893 avr_output_progmem_section_asm_op (const char *data) 11894 { 11895 fprintf (asm_out_file, "\t.section\t%s,\"a\",@progbits\n", data); 11896 } 11897 11898 11899 /* A noswitch section callback to output symbol definitions for 11900 attributes "io", "io_low" and "address". */ 11901 11902 static bool 11903 avr_output_addr_attrib (tree decl, const char *name, 11904 unsigned HOST_WIDE_INT /* size */, 11905 unsigned HOST_WIDE_INT /* align */) 11906 { 11907 gcc_assert (DECL_RTL_SET_P (decl)); 11908 11909 FILE *stream = asm_out_file; 11910 bool local_p = ! DECL_WEAK (decl) && ! TREE_PUBLIC (decl); 11911 rtx symbol, mem = DECL_RTL (decl); 11912 11913 if (mem != NULL_RTX && MEM_P (mem) 11914 && SYMBOL_REF_P ((symbol = XEXP (mem, 0))) 11915 && (SYMBOL_REF_FLAGS (symbol) & (SYMBOL_FLAG_IO | SYMBOL_FLAG_ADDRESS))) 11916 { 11917 if (! local_p) 11918 { 11919 fprintf (stream, "\t%s\t", DECL_WEAK (decl) ? ".weak" : ".globl"); 11920 assemble_name (stream, name); 11921 fprintf (stream, "\n"); 11922 } 11923 11924 if (SYMBOL_REF_FLAGS (symbol) & SYMBOL_FLAG_ADDRESS) 11925 { 11926 assemble_name (stream, name); 11927 fprintf (stream, " = %ld\n", 11928 (long) INTVAL (avr_eval_addr_attrib (symbol))); 11929 } 11930 else if (local_p) 11931 { 11932 const char *names[] = { "io", "io_low", "address", NULL }; 11933 for (const char **p = names; *p; ++p) 11934 if (lookup_attribute (*p, DECL_ATTRIBUTES (decl))) 11935 { 11936 error ("static attribute %qs declaration for %q+D needs an " 11937 "address", *p, decl); 11938 break; 11939 } 11940 } 11941 11942 return true; 11943 } 11944 11945 gcc_unreachable(); 11946 11947 return false; 11948 } 11949 11950 11951 /* Implement `TARGET_ASM_INIT_SECTIONS'. */ 11952 11953 static void 11954 avr_asm_init_sections (void) 11955 { 11956 /* Override section callbacks to keep track of `avr_need_clear_bss_p', 11957 `avr_need_copy_data_p' and `avr_has_rodata_p'. 11958 Track also .rodata for the case when .rodata is located in RAM. */ 11959 11960 if (! avr_rodata_in_flash_p ()) 11961 readonly_data_section->unnamed.callback = avr_output_data_section_asm_op; 11962 data_section->unnamed.callback = avr_output_data_section_asm_op; 11963 bss_section->unnamed.callback = avr_output_bss_section_asm_op; 11964 tls_comm_section->noswitch.callback = avr_output_addr_attrib; 11965 } 11966 11967 11968 /* Implement `TARGET_ASM_NAMED_SECTION'. */ 11969 /* Track need of __do_clear_bss, __do_copy_data for named sections. */ 11970 11971 static void 11972 avr_asm_named_section (const char *name, unsigned int flags, tree decl) 11973 { 11974 if (flags & AVR_SECTION_PROGMEM 11975 // Only use section .progmem*.data if there is no attribute section. 11976 && ! (decl 11977 && DECL_SECTION_NAME (decl) 11978 && symtab_node::get (decl) 11979 && ! symtab_node::get (decl)->implicit_section)) 11980 { 11981 addr_space_t as = (flags & AVR_SECTION_PROGMEM) / SECTION_MACH_DEP; 11982 const char *old_prefix = ".rodata"; 11983 const char *new_prefix = avr_addrspace[as].section_name; 11984 11985 if (startswith (name, old_prefix)) 11986 { 11987 const char *sname = ACONCAT ((new_prefix, 11988 name + strlen (old_prefix), NULL)); 11989 default_elf_asm_named_section (sname, flags, decl); 11990 return; 11991 } 11992 11993 default_elf_asm_named_section (new_prefix, flags, decl); 11994 return; 11995 } 11996 11997 if (!avr_need_copy_data_p) 11998 avr_need_copy_data_p = (startswith (name, ".data") 11999 || startswith (name, ".gnu.linkonce.d")); 12000 12001 if (!avr_has_rodata_p) 12002 avr_has_rodata_p = (startswith (name, ".rodata") 12003 || startswith (name, ".gnu.linkonce.r")); 12004 12005 if (!avr_need_clear_bss_p) 12006 avr_need_clear_bss_p = startswith (name, ".bss"); 12007 12008 default_elf_asm_named_section (name, flags, decl); 12009 } 12010 12011 12012 /* Implement `TARGET_SECTION_TYPE_FLAGS'. */ 12013 12014 static unsigned int 12015 avr_section_type_flags (tree decl, const char *name, int reloc) 12016 { 12017 unsigned int flags = default_section_type_flags (decl, name, reloc); 12018 12019 if (startswith (name, ".noinit")) 12020 { 12021 if (decl && VAR_P (decl) 12022 && DECL_INITIAL (decl) == NULL_TREE) 12023 flags |= SECTION_BSS; /* @nobits */ 12024 else 12025 warning (0, "only uninitialized variables can be placed in the " 12026 "%<.noinit%> section"); 12027 } 12028 12029 if (decl && DECL_P (decl) 12030 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl))) 12031 { 12032 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl)); 12033 12034 /* Attribute progmem puts data in generic address space. 12035 Set section flags as if it was in __flash to get the right 12036 section prefix in the remainder. */ 12037 12038 if (ADDR_SPACE_GENERIC_P (as)) 12039 as = ADDR_SPACE_FLASH; 12040 12041 flags |= as * SECTION_MACH_DEP; 12042 flags &= ~SECTION_WRITE; 12043 flags &= ~SECTION_BSS; 12044 flags &= ~SECTION_NOTYPE; 12045 } 12046 12047 return flags; 12048 } 12049 12050 12051 /* A helper for the next function. NODE is a decl that is associated with 12052 a symbol. Return TRUE if the respective object may be accessed by LDS. 12053 There might still be other reasons for why LDS is not appropriate. 12054 This function is only appropriate for AVR_TINY. */ 12055 12056 static bool 12057 avr_decl_maybe_lds_p (tree node) 12058 { 12059 if (!node 12060 || TREE_CODE (node) != VAR_DECL 12061 || DECL_SECTION_NAME (node) != NULL) 12062 return false; 12063 12064 /* Don't use LDS for objects that go to .rodata. The current default 12065 linker description file still locates .rodata in RAM, but this is not 12066 a must. A better linker script would just keep .rodata in flash and 12067 add an offset of 0x4000 to the VMA. Hence avoid LDS for such data. */ 12068 12069 if (TREE_READONLY (node)) 12070 return false; 12071 12072 // C++ requires peeling arrays. 12073 12074 do 12075 node = TREE_TYPE (node); 12076 while (ARRAY_TYPE == TREE_CODE (node)); 12077 12078 return (node != error_mark_node 12079 && !TYPE_READONLY (node)); 12080 } 12081 12082 12083 /* Implement `TARGET_ENCODE_SECTION_INFO'. */ 12084 12085 static void 12086 avr_encode_section_info (tree decl, rtx rtl, int new_decl_p) 12087 { 12088 tree addr_attr = NULL_TREE; 12089 12090 /* In avr_handle_progmem_attribute, DECL_INITIAL is not yet 12091 readily available, see PR34734. So we postpone the warning 12092 about uninitialized data in program memory section until here. */ 12093 12094 if (new_decl_p 12095 && decl && DECL_P (decl) 12096 && !DECL_EXTERNAL (decl) 12097 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl))) 12098 { 12099 if (!TREE_READONLY (decl)) 12100 { 12101 // This might happen with C++ if stuff needs constructing. 12102 error ("variable %q+D with dynamic initialization put " 12103 "into program memory area", decl); 12104 } 12105 else if (NULL_TREE == DECL_INITIAL (decl)) 12106 { 12107 // Don't warn for (implicit) aliases like in PR80462. 12108 tree asmname = DECL_ASSEMBLER_NAME (decl); 12109 varpool_node *node = varpool_node::get_for_asmname (asmname); 12110 bool alias_p = node && node->alias; 12111 12112 if (!alias_p) 12113 warning (OPT_Wuninitialized, "uninitialized variable %q+D put " 12114 "into program memory area", decl); 12115 } 12116 } 12117 12118 default_encode_section_info (decl, rtl, new_decl_p); 12119 12120 if (decl && DECL_P (decl) 12121 && TREE_CODE (decl) != FUNCTION_DECL 12122 && MEM_P (rtl) 12123 && SYMBOL_REF_P (XEXP (rtl, 0))) 12124 { 12125 rtx sym = XEXP (rtl, 0); 12126 tree type = TREE_TYPE (decl); 12127 tree attr = DECL_ATTRIBUTES (decl); 12128 if (type == error_mark_node) 12129 return; 12130 12131 addr_space_t as = TYPE_ADDR_SPACE (type); 12132 12133 /* PSTR strings are in generic space but located in flash: 12134 patch address space. */ 12135 12136 if (!AVR_TINY && avr_progmem_p (decl, attr) == -1) 12137 as = ADDR_SPACE_FLASH; 12138 12139 AVR_SYMBOL_SET_ADDR_SPACE (sym, as); 12140 12141 tree io_low_attr = lookup_attribute ("io_low", attr); 12142 tree io_attr = lookup_attribute ("io", attr); 12143 tree address_attr = lookup_attribute ("address", attr); 12144 12145 if (io_low_attr 12146 && TREE_VALUE (io_low_attr) && TREE_VALUE (TREE_VALUE (io_low_attr))) 12147 addr_attr = io_low_attr; 12148 else if (io_attr 12149 && TREE_VALUE (io_attr) && TREE_VALUE (TREE_VALUE (io_attr))) 12150 addr_attr = io_attr; 12151 else 12152 addr_attr = address_attr; 12153 12154 if (io_low_attr 12155 || (io_attr && addr_attr 12156 && low_io_address_operand 12157 (GEN_INT (TREE_INT_CST_LOW 12158 (TREE_VALUE (TREE_VALUE (addr_attr)))), QImode))) 12159 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_IO_LOW; 12160 if (io_attr || io_low_attr) 12161 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_IO; 12162 /* If we have an (io) address attribute specification, but the variable 12163 is external, treat the address as only a tentative definition 12164 to be used to determine if an io port is in the lower range, but 12165 don't use the exact value for constant propagation. */ 12166 if (addr_attr && !DECL_EXTERNAL (decl)) 12167 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_ADDRESS; 12168 12169 if (io_attr || io_low_attr || address_attr) 12170 { 12171 if (DECL_INITIAL (decl)) 12172 { 12173 /* Initializers are not yet parsed in TARGET_INSERT_ATTRIBUTES, 12174 hence deny initializers now. The values of symbols with an 12175 address attribute are determined by the attribute, not by 12176 some initializer. */ 12177 12178 error ("variable %q+D with attribute %qs must not have an " 12179 "initializer", decl, 12180 io_low_attr ? "io_low" : io_attr ? "io" : "address"); 12181 } 12182 else 12183 { 12184 /* PR112952: The only way to output a variable declaration in a 12185 custom manner is by means of a noswitch section callback. 12186 There are only three noswitch sections: comm_section, 12187 lcomm_section and tls_comm_section. And there is no way to 12188 wire a custom noswitch section to a decl. As lcomm_section 12189 is bypassed with -fdata-sections -fno-common, there is no 12190 other way than making use of tls_comm_section. As we are 12191 using that section anyway, also use it in the public case. */ 12192 12193 DECL_COMMON (decl) = 1; 12194 set_decl_section_name (decl, (const char *) nullptr); 12195 set_decl_tls_model (decl, (tls_model) 2); 12196 } 12197 } 12198 } 12199 12200 if (AVR_TINY 12201 && decl 12202 && VAR_P (decl) 12203 && MEM_P (rtl) 12204 && SYMBOL_REF_P (XEXP (rtl, 0))) 12205 { 12206 rtx sym = XEXP (rtl, 0); 12207 bool progmem_p = avr_progmem_p (decl, DECL_ATTRIBUTES (decl)) == -1; 12208 12209 if (progmem_p) 12210 { 12211 // Tag symbols for addition of 0x4000 (avr_arch->flash_pm_offset). 12212 SYMBOL_REF_FLAGS (sym) |= AVR_SYMBOL_FLAG_TINY_PM; 12213 } 12214 12215 if (avr_decl_absdata_p (decl, DECL_ATTRIBUTES (decl)) 12216 || (TARGET_ABSDATA 12217 && !progmem_p 12218 && !addr_attr 12219 && avr_decl_maybe_lds_p (decl)) 12220 || (addr_attr 12221 // If addr_attr is non-null, it has an argument. Peek into it. 12222 && TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (addr_attr))) < 0xc0)) 12223 { 12224 // May be accessed by LDS / STS. 12225 SYMBOL_REF_FLAGS (sym) |= AVR_SYMBOL_FLAG_TINY_ABSDATA; 12226 } 12227 12228 if (progmem_p 12229 && avr_decl_absdata_p (decl, DECL_ATTRIBUTES (decl))) 12230 { 12231 error ("%q+D has incompatible attributes %qs and %qs", 12232 decl, "progmem", "absdata"); 12233 } 12234 } 12235 } 12236 12237 12238 /* Implement `TARGET_ASM_SELECT_SECTION' */ 12239 12240 static section * 12241 avr_asm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align) 12242 { 12243 section *sect = default_elf_select_section (decl, reloc, align); 12244 12245 if (decl && DECL_P (decl) 12246 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl))) 12247 { 12248 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl)); 12249 12250 /* __progmem__ goes in generic space but shall be allocated to 12251 .progmem.data */ 12252 12253 if (ADDR_SPACE_GENERIC_P (as)) 12254 as = ADDR_SPACE_FLASH; 12255 12256 if (sect->common.flags & SECTION_NAMED) 12257 { 12258 const char *name = sect->named.name; 12259 const char *old_prefix = ".rodata"; 12260 const char *new_prefix = avr_addrspace[as].section_name; 12261 12262 if (startswith (name, old_prefix)) 12263 { 12264 const char *sname = ACONCAT ((new_prefix, 12265 name + strlen (old_prefix), NULL)); 12266 return get_section (sname, 12267 sect->common.flags & ~SECTION_DECLARED, 12268 sect->named.decl); 12269 } 12270 } 12271 12272 if (!progmem_section[as]) 12273 { 12274 progmem_section[as] 12275 = get_unnamed_section (0, avr_output_progmem_section_asm_op, 12276 avr_addrspace[as].section_name); 12277 } 12278 12279 return progmem_section[as]; 12280 } 12281 12282 return sect; 12283 } 12284 12285 /* Implement `TARGET_ASM_FILE_START'. */ 12286 /* Outputs some text at the start of each assembler file. */ 12287 12288 static void 12289 avr_file_start (void) 12290 { 12291 int sfr_offset = avr_arch->sfr_offset; 12292 12293 if (avr_arch->asm_only) 12294 error ("architecture %qs supported for assembler only", avr_mmcu); 12295 12296 default_file_start (); 12297 12298 /* Print I/O addresses of some SFRs used with IN and OUT. */ 12299 12300 if (AVR_HAVE_SPH) 12301 fprintf (asm_out_file, "__SP_H__ = 0x%02x\n", avr_addr.sp_h - sfr_offset); 12302 12303 fprintf (asm_out_file, "__SP_L__ = 0x%02x\n", avr_addr.sp_l - sfr_offset); 12304 fprintf (asm_out_file, "__SREG__ = 0x%02x\n", avr_addr.sreg - sfr_offset); 12305 if (AVR_HAVE_RAMPZ) 12306 fprintf (asm_out_file, "__RAMPZ__ = 0x%02x\n", avr_addr.rampz - sfr_offset); 12307 if (AVR_HAVE_RAMPY) 12308 fprintf (asm_out_file, "__RAMPY__ = 0x%02x\n", avr_addr.rampy - sfr_offset); 12309 if (AVR_HAVE_RAMPX) 12310 fprintf (asm_out_file, "__RAMPX__ = 0x%02x\n", avr_addr.rampx - sfr_offset); 12311 if (AVR_HAVE_RAMPD) 12312 fprintf (asm_out_file, "__RAMPD__ = 0x%02x\n", avr_addr.rampd - sfr_offset); 12313 if (AVR_XMEGA || AVR_TINY) 12314 fprintf (asm_out_file, "__CCP__ = 0x%02x\n", avr_addr.ccp - sfr_offset); 12315 fprintf (asm_out_file, "__tmp_reg__ = %d\n", AVR_TMP_REGNO); 12316 fprintf (asm_out_file, "__zero_reg__ = %d\n", AVR_ZERO_REGNO); 12317 } 12318 12319 12320 /* Implement `TARGET_ASM_FILE_END'. */ 12321 /* Outputs to the stdio stream FILE some 12322 appropriate text to go at the end of an assembler file. */ 12323 12324 static void 12325 avr_file_end (void) 12326 { 12327 /* Output these only if there is anything in the 12328 .data* / .rodata* / .gnu.linkonce.* resp. .bss* or COMMON 12329 input section(s) - some code size can be saved by not 12330 linking in the initialization code from libgcc if resp. 12331 sections are empty, see PR18145. */ 12332 12333 if (avr_need_copy_data_p 12334 || (avr_has_rodata_p && ! avr_rodata_in_flash_p ())) 12335 fputs (".global __do_copy_data\n", asm_out_file); 12336 12337 if (avr_need_clear_bss_p) 12338 fputs (".global __do_clear_bss\n", asm_out_file); 12339 } 12340 12341 12342 /* Worker function for `ADJUST_REG_ALLOC_ORDER'. */ 12343 /* Choose the order in which to allocate hard registers for 12344 pseudo-registers local to a basic block. 12345 12346 Store the desired register order in the array `reg_alloc_order'. 12347 Element 0 should be the register to allocate first; element 1, the 12348 next register; and so on. */ 12349 12350 void 12351 avr_adjust_reg_alloc_order (void) 12352 { 12353 static const int order_0[] = 12354 { 12355 24, 25, 12356 18, 19, 20, 21, 22, 23, 12357 30, 31, 12358 26, 27, 28, 29, 12359 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 12360 0, 1, 12361 32, 33, 34, 35 12362 }; 12363 static const int tiny_order_0[] = { 12364 20, 21, 12365 22, 23, 12366 24, 25, 12367 30, 31, 12368 26, 27, 12369 28, 29, 12370 19, 18, 12371 16, 17, 12372 32, 33, 34, 35, 12373 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 12374 }; 12375 static const int order_1[] = 12376 { 12377 18, 19, 20, 21, 22, 23, 24, 25, 12378 30, 31, 12379 26, 27, 28, 29, 12380 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 12381 0, 1, 12382 32, 33, 34, 35 12383 }; 12384 static const int tiny_order_1[] = { 12385 22, 23, 12386 24, 25, 12387 30, 31, 12388 26, 27, 12389 28, 29, 12390 21, 20, 19, 18, 12391 16, 17, 12392 32, 33, 34, 35, 12393 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 12394 }; 12395 static const int order_2[] = 12396 { 12397 25, 24, 23, 22, 21, 20, 19, 18, 12398 30, 31, 12399 26, 27, 28, 29, 12400 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 12401 1, 0, 12402 32, 33, 34, 35 12403 }; 12404 12405 /* Select specific register allocation order. 12406 Tiny Core (ATtiny4/5/9/10/20/40) devices have only 16 registers, 12407 so different allocation order should be used. */ 12408 12409 const int *order = (TARGET_ORDER_1 ? (AVR_TINY ? tiny_order_1 : order_1) 12410 : TARGET_ORDER_2 ? (AVR_TINY ? tiny_order_0 : order_2) 12411 : (AVR_TINY ? tiny_order_0 : order_0)); 12412 12413 for (size_t i = 0; i < ARRAY_SIZE (order_0); ++i) 12414 reg_alloc_order[i] = order[i]; 12415 } 12416 12417 12418 /* Implement `TARGET_REGISTER_MOVE_COST' */ 12419 12420 static int 12421 avr_register_move_cost (machine_mode /*mode*/, reg_class_t from, reg_class_t to) 12422 { 12423 return (from == STACK_REG ? 6 12424 : to == STACK_REG ? 12 12425 : 2); 12426 } 12427 12428 12429 /* Implement `TARGET_MEMORY_MOVE_COST' */ 12430 12431 static int 12432 avr_memory_move_cost (machine_mode mode, reg_class_t /*rclass*/, bool /*in*/) 12433 { 12434 return (mode == QImode ? 2 12435 : mode == HImode ? 4 12436 : mode == SImode ? 8 12437 : mode == SFmode ? 8 12438 : 16); 12439 } 12440 12441 12442 /* Cost for mul highpart. X is a LSHIFTRT, i.e. the outer TRUNCATE is 12443 already stripped off. */ 12444 12445 static int 12446 avr_mul_highpart_cost (rtx x, int) 12447 { 12448 if (AVR_HAVE_MUL 12449 && LSHIFTRT == GET_CODE (x) 12450 && MULT == GET_CODE (XEXP (x, 0)) 12451 && CONST_INT_P (XEXP (x, 1))) 12452 { 12453 // This is the wider mode. 12454 machine_mode mode = GET_MODE (x); 12455 12456 // The middle-end might still have PR81444, i.e. it is calling the cost 12457 // functions with strange modes. Fix this now by also considering 12458 // PSImode (should actually be SImode instead). 12459 if (HImode == mode || PSImode == mode || SImode == mode) 12460 { 12461 return COSTS_N_INSNS (2); 12462 } 12463 } 12464 12465 return 10000; 12466 } 12467 12468 12469 /* Return the expected cost of a conditional branch like 12470 (set (pc) 12471 (if_then_else (X) 12472 (label_ref *) 12473 (pc))) 12474 where X is some comparison operator. */ 12475 12476 static int 12477 avr_cbranch_cost (rtx x) 12478 { 12479 bool difficult_p = difficult_comparison_operator (x, VOIDmode); 12480 12481 if (reload_completed) 12482 { 12483 // After reload, we basically just have plain branches. 12484 return COSTS_N_INSNS (1 + difficult_p); 12485 } 12486 12487 rtx xreg = XEXP (x, 0); 12488 rtx xval = XEXP (x, 1); 12489 machine_mode mode = GET_MODE (xreg); 12490 if (mode == VOIDmode) 12491 mode = GET_MODE (xval); 12492 int size = GET_MODE_SIZE (mode); 12493 12494 if (GET_CODE (xreg) == ZERO_EXTEND 12495 || GET_CODE (xval) == ZERO_EXTEND) 12496 { 12497 // *cbranch<HISI:mode>.<code><QIPSI:mode>.0/1, code = zero_extend. 12498 return COSTS_N_INSNS (size + 1); 12499 } 12500 12501 if (GET_CODE (xreg) == SIGN_EXTEND 12502 || GET_CODE (xval) == SIGN_EXTEND) 12503 { 12504 // *cbranch<HISI:mode>.<code><QIPSI:mode>.0/1, code = sign_extend. 12505 // Make it a bit cheaper than it actually is (less reg pressure). 12506 return COSTS_N_INSNS (size + 1 + 1); 12507 } 12508 12509 if (GET_CODE (xreg) == ZERO_EXTRACT 12510 && XEXP (xreg, 1) == const1_rtx) 12511 { 12512 // Branch on a single bit, with an additional edge due to less 12513 // register pressure. 12514 return (int) COSTS_N_INSNS (1.5); 12515 } 12516 12517 bool reg_p = register_operand (xreg, mode); 12518 bool reg_or_0_p = reg_or_0_operand (xval, mode); 12519 12520 return COSTS_N_INSNS (size 12521 // For the branch 12522 + 1 + difficult_p 12523 // Combine might propagate constants other than zero 12524 // into the 2nd operand. Make that more expensive. 12525 + 1 * (!reg_p || !reg_or_0_p)); 12526 } 12527 12528 12529 /* Mutually recursive subroutine of avr_rtx_cost for calculating the 12530 cost of an RTX operand given its context. X is the rtx of the 12531 operand, MODE is its mode, and OUTER is the rtx_code of this 12532 operand's parent operator. */ 12533 12534 static int 12535 avr_operand_rtx_cost (rtx x, machine_mode mode, enum rtx_code outer, 12536 int opno, bool speed) 12537 { 12538 enum rtx_code code = GET_CODE (x); 12539 12540 switch (code) 12541 { 12542 case REG: 12543 case SUBREG: 12544 return 0; 12545 12546 case CONST_INT: 12547 case CONST_FIXED: 12548 case CONST_DOUBLE: 12549 return COSTS_N_INSNS (GET_MODE_SIZE (mode)); 12550 12551 default: 12552 break; 12553 } 12554 12555 int total = 0; 12556 avr_rtx_costs (x, mode, outer, opno, &total, speed); 12557 return total; 12558 } 12559 12560 /* Worker function for AVR backend's rtx_cost function. 12561 X is rtx expression whose cost is to be calculated. 12562 Return true if the complete cost has been computed. 12563 Return false if subexpressions should be scanned. 12564 In either case, *TOTAL contains the cost result. */ 12565 12566 static bool 12567 avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, 12568 int /*opno*/, int *total, bool speed) 12569 { 12570 enum rtx_code code = GET_CODE (x); 12571 HOST_WIDE_INT val; 12572 12573 switch (code) 12574 { 12575 case CONST_INT: 12576 case CONST_FIXED: 12577 case CONST_DOUBLE: 12578 case SYMBOL_REF: 12579 case CONST: 12580 case LABEL_REF: 12581 /* Immediate constants are as cheap as registers. */ 12582 *total = 0; 12583 return true; 12584 12585 case MEM: 12586 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)); 12587 return true; 12588 12589 case NEG: 12590 switch (mode) 12591 { 12592 case E_QImode: 12593 case E_SFmode: 12594 *total = COSTS_N_INSNS (1); 12595 break; 12596 12597 case E_HImode: 12598 case E_PSImode: 12599 case E_SImode: 12600 *total = COSTS_N_INSNS (2 * GET_MODE_SIZE (mode) - 1); 12601 break; 12602 12603 default: 12604 return false; 12605 } 12606 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed); 12607 return true; 12608 12609 case ABS: 12610 switch (mode) 12611 { 12612 case E_QImode: 12613 case E_SFmode: 12614 *total = COSTS_N_INSNS (1); 12615 break; 12616 12617 default: 12618 return false; 12619 } 12620 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed); 12621 return true; 12622 12623 case NOT: 12624 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)); 12625 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed); 12626 return true; 12627 12628 case ZERO_EXTEND: 12629 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) 12630 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0)))); 12631 *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)), 12632 code, 0, speed); 12633 return true; 12634 12635 case SIGN_EXTEND: 12636 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2 12637 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0)))); 12638 *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)), 12639 code, 0, speed); 12640 return true; 12641 12642 case PLUS: 12643 // uint16_t += 2 * uint8_t; 12644 if (mode == HImode 12645 && GET_CODE (XEXP (x, 0)) == ASHIFT 12646 && REG_P (XEXP (x, 1)) 12647 && XEXP (XEXP (x, 0), 1) == const1_rtx 12648 && GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND) 12649 { 12650 *total = COSTS_N_INSNS (4); 12651 return true; 12652 } 12653 12654 // *usum_widenqihi 12655 if (mode == HImode 12656 && GET_CODE (XEXP (x, 0)) == ZERO_EXTEND 12657 && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND) 12658 { 12659 *total = COSTS_N_INSNS (3); 12660 return true; 12661 } 12662 12663 if (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND 12664 && REG_P (XEXP (x, 1))) 12665 { 12666 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)); 12667 return true; 12668 } 12669 if (REG_P (XEXP (x, 0)) 12670 && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND) 12671 { 12672 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)); 12673 return true; 12674 } 12675 12676 switch (mode) 12677 { 12678 case E_QImode: 12679 if (AVR_HAVE_MUL 12680 && MULT == GET_CODE (XEXP (x, 0)) 12681 && register_operand (XEXP (x, 1), QImode)) 12682 { 12683 /* multiply-add */ 12684 *total = COSTS_N_INSNS (speed ? 4 : 3); 12685 /* multiply-add with constant: will be split and load constant. */ 12686 if (CONST_INT_P (XEXP (XEXP (x, 0), 1))) 12687 *total = COSTS_N_INSNS (1) + *total; 12688 return true; 12689 } 12690 *total = COSTS_N_INSNS (1); 12691 if (!CONST_INT_P (XEXP (x, 1))) 12692 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed); 12693 break; 12694 12695 case E_HImode: 12696 if (AVR_HAVE_MUL 12697 && (MULT == GET_CODE (XEXP (x, 0)) 12698 || ASHIFT == GET_CODE (XEXP (x, 0))) 12699 && register_operand (XEXP (x, 1), HImode) 12700 && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0)) 12701 || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0)))) 12702 { 12703 /* multiply-add */ 12704 *total = COSTS_N_INSNS (speed ? 5 : 4); 12705 /* multiply-add with constant: will be split and load constant. */ 12706 if (CONST_INT_P (XEXP (XEXP (x, 0), 1))) 12707 *total = COSTS_N_INSNS (1) + *total; 12708 return true; 12709 } 12710 if (!CONST_INT_P (XEXP (x, 1))) 12711 { 12712 *total = COSTS_N_INSNS (2); 12713 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, 12714 speed); 12715 } 12716 else if (IN_RANGE (INTVAL (XEXP (x, 1)), -63, 63)) 12717 *total = COSTS_N_INSNS (1); 12718 else 12719 *total = COSTS_N_INSNS (2); 12720 break; 12721 12722 case E_PSImode: 12723 if (!CONST_INT_P (XEXP (x, 1))) 12724 { 12725 *total = COSTS_N_INSNS (3); 12726 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, 12727 speed); 12728 } 12729 else if (IN_RANGE (INTVAL (XEXP (x, 1)), -63, 63)) 12730 *total = COSTS_N_INSNS (2); 12731 else 12732 *total = COSTS_N_INSNS (3); 12733 break; 12734 12735 case E_SImode: 12736 if (!CONST_INT_P (XEXP (x, 1))) 12737 { 12738 *total = COSTS_N_INSNS (4); 12739 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, 12740 speed); 12741 } 12742 else if (IN_RANGE (INTVAL (XEXP (x, 1)), -63, 63)) 12743 *total = COSTS_N_INSNS (1); 12744 else 12745 *total = COSTS_N_INSNS (4); 12746 break; 12747 12748 default: 12749 return false; 12750 } 12751 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed); 12752 return true; 12753 12754 case MINUS: 12755 // *udiff_widenqihi 12756 if (mode == HImode 12757 && GET_CODE (XEXP (x, 0)) == ZERO_EXTEND 12758 && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND) 12759 { 12760 *total = COSTS_N_INSNS (2); 12761 return true; 12762 } 12763 // *sub<mode>3_zero_extend1 12764 if (REG_P (XEXP (x, 0)) 12765 && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND) 12766 { 12767 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)); 12768 return true; 12769 } 12770 // *sub<mode>3.sign_extend2 12771 if (REG_P (XEXP (x, 0)) 12772 && GET_CODE (XEXP (x, 1)) == SIGN_EXTEND) 12773 { 12774 *total = COSTS_N_INSNS (2 + GET_MODE_SIZE (mode)); 12775 return true; 12776 } 12777 12778 if (AVR_HAVE_MUL 12779 && QImode == mode 12780 && register_operand (XEXP (x, 0), QImode) 12781 && MULT == GET_CODE (XEXP (x, 1))) 12782 { 12783 /* multiply-sub */ 12784 *total = COSTS_N_INSNS (speed ? 4 : 3); 12785 /* multiply-sub with constant: will be split and load constant. */ 12786 if (CONST_INT_P (XEXP (XEXP (x, 1), 1))) 12787 *total = COSTS_N_INSNS (1) + *total; 12788 return true; 12789 } 12790 if (AVR_HAVE_MUL 12791 && HImode == mode 12792 && register_operand (XEXP (x, 0), HImode) 12793 && (MULT == GET_CODE (XEXP (x, 1)) 12794 || ASHIFT == GET_CODE (XEXP (x, 1))) 12795 && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0)) 12796 || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0)))) 12797 { 12798 /* multiply-sub */ 12799 *total = COSTS_N_INSNS (speed ? 5 : 4); 12800 /* multiply-sub with constant: will be split and load constant. */ 12801 if (CONST_INT_P (XEXP (XEXP (x, 1), 1))) 12802 *total = COSTS_N_INSNS (1) + *total; 12803 return true; 12804 } 12805 /* FALLTHRU */ 12806 case AND: 12807 case IOR: 12808 if (IOR == code 12809 && HImode == mode 12810 && ASHIFT == GET_CODE (XEXP (x, 0))) 12811 { 12812 *total = COSTS_N_INSNS (2); 12813 // Just a rough estimate. If we see no sign- or zero-extend, 12814 // then increase the cost a little bit. 12815 if (REG_P (XEXP (XEXP (x, 0), 0))) 12816 *total += COSTS_N_INSNS (1); 12817 if (REG_P (XEXP (x, 1))) 12818 *total += COSTS_N_INSNS (1); 12819 return true; 12820 } 12821 if (IOR == code 12822 && AND == GET_CODE (XEXP (x, 0)) 12823 && AND == GET_CODE (XEXP (x, 1)) 12824 && single_zero_operand (XEXP (XEXP (x, 0), 1), mode)) 12825 { 12826 // Open-coded bit transfer. 12827 *total = COSTS_N_INSNS (2); 12828 return true; 12829 } 12830 if (AND == code 12831 && single_one_operand (XEXP (x, 1), mode) 12832 && (ASHIFT == GET_CODE (XEXP (x, 0)) 12833 || ASHIFTRT == GET_CODE (XEXP (x, 0)) 12834 || LSHIFTRT == GET_CODE (XEXP (x, 0)))) 12835 { 12836 // "*insv.any_shift.<mode> 12837 *total = COSTS_N_INSNS (1 + GET_MODE_SIZE (mode)); 12838 return true; 12839 } 12840 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)); 12841 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed); 12842 if (!CONST_INT_P (XEXP (x, 1))) 12843 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed); 12844 return true; 12845 12846 case XOR: 12847 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)); 12848 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed); 12849 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed); 12850 return true; 12851 12852 case MULT: 12853 switch (mode) 12854 { 12855 case E_QImode: 12856 if (AVR_HAVE_MUL) 12857 *total = COSTS_N_INSNS (!speed ? 3 : 4); 12858 else if (!speed) 12859 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1); 12860 else 12861 return false; 12862 break; 12863 12864 case E_HImode: 12865 if (AVR_HAVE_MUL) 12866 { 12867 rtx op0 = XEXP (x, 0); 12868 rtx op1 = XEXP (x, 1); 12869 enum rtx_code code0 = GET_CODE (op0); 12870 enum rtx_code code1 = GET_CODE (op1); 12871 bool ex0 = SIGN_EXTEND == code0 || ZERO_EXTEND == code0; 12872 bool ex1 = SIGN_EXTEND == code1 || ZERO_EXTEND == code1; 12873 12874 if (ex0 12875 && (u8_operand (op1, HImode) 12876 || s8_operand (op1, HImode))) 12877 { 12878 *total = COSTS_N_INSNS (!speed ? 4 : 6); 12879 return true; 12880 } 12881 if (ex0 12882 && register_operand (op1, HImode)) 12883 { 12884 *total = COSTS_N_INSNS (!speed ? 5 : 8); 12885 return true; 12886 } 12887 else if (ex0 || ex1) 12888 { 12889 *total = COSTS_N_INSNS (!speed ? 3 : 5); 12890 return true; 12891 } 12892 else if (register_operand (op0, HImode) 12893 && (u8_operand (op1, HImode) 12894 || s8_operand (op1, HImode))) 12895 { 12896 *total = COSTS_N_INSNS (!speed ? 6 : 9); 12897 return true; 12898 } 12899 else 12900 *total = COSTS_N_INSNS (!speed ? 7 : 10); 12901 } 12902 else if (!speed) 12903 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1); 12904 else 12905 return false; 12906 break; 12907 12908 case E_PSImode: 12909 if (!speed) 12910 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1); 12911 else 12912 *total = 10; 12913 break; 12914 12915 case E_SImode: 12916 case E_DImode: 12917 if (AVR_HAVE_MUL) 12918 { 12919 if (!speed) 12920 { 12921 /* Add some additional costs besides CALL like moves etc. */ 12922 12923 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4); 12924 } 12925 else 12926 { 12927 /* Just a rough estimate. Even with -O2 we don't want bulky 12928 code expanded inline. */ 12929 12930 *total = COSTS_N_INSNS (25); 12931 } 12932 } 12933 else 12934 { 12935 if (speed) 12936 *total = COSTS_N_INSNS (300); 12937 else 12938 /* Add some additional costs besides CALL like moves etc. */ 12939 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4); 12940 } 12941 12942 if (mode == DImode) 12943 *total *= 2; 12944 12945 return true; 12946 12947 default: 12948 return false; 12949 } 12950 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed); 12951 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed); 12952 return true; 12953 12954 case DIV: 12955 case MOD: 12956 case UDIV: 12957 case UMOD: 12958 if (!speed) 12959 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1); 12960 else 12961 *total = COSTS_N_INSNS (15 * GET_MODE_SIZE (mode)); 12962 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed); 12963 /* For div/mod with const-int divisor we have at least the cost of 12964 loading the divisor. */ 12965 if (CONST_INT_P (XEXP (x, 1))) 12966 *total += COSTS_N_INSNS (GET_MODE_SIZE (mode)); 12967 /* Add some overall penaly for clobbering and moving around registers */ 12968 *total += COSTS_N_INSNS (2); 12969 return true; 12970 12971 case ROTATE: 12972 switch (mode) 12973 { 12974 case E_QImode: 12975 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 4) 12976 *total = COSTS_N_INSNS (1); 12977 12978 break; 12979 12980 case E_HImode: 12981 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 8) 12982 *total = COSTS_N_INSNS (3); 12983 12984 break; 12985 12986 case E_SImode: 12987 if (CONST_INT_P (XEXP (x, 1))) 12988 switch (INTVAL (XEXP (x, 1))) 12989 { 12990 case 8: 12991 case 24: 12992 *total = COSTS_N_INSNS (5); 12993 break; 12994 case 16: 12995 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 6); 12996 break; 12997 } 12998 break; 12999 13000 default: 13001 return false; 13002 } 13003 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed); 13004 return true; 13005 13006 case ASHIFT: 13007 switch (mode) 13008 { 13009 case E_QImode: 13010 if (!CONST_INT_P (XEXP (x, 1))) 13011 { 13012 *total = COSTS_N_INSNS (!speed ? 4 : 17); 13013 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, 13014 speed); 13015 } 13016 else 13017 { 13018 val = INTVAL (XEXP (x, 1)); 13019 if (val == 7) 13020 *total = COSTS_N_INSNS (3); 13021 else if (val >= 0 && val <= 7) 13022 *total = COSTS_N_INSNS (val); 13023 else 13024 *total = COSTS_N_INSNS (1); 13025 } 13026 break; 13027 13028 case E_HImode: 13029 if (AVR_HAVE_MUL) 13030 { 13031 if (const_2_to_7_operand (XEXP (x, 1), HImode) 13032 && (SIGN_EXTEND == GET_CODE (XEXP (x, 0)) 13033 || ZERO_EXTEND == GET_CODE (XEXP (x, 0)))) 13034 { 13035 *total = COSTS_N_INSNS (!speed ? 4 : 6); 13036 return true; 13037 } 13038 } 13039 13040 if (const1_rtx == (XEXP (x, 1)) 13041 && SIGN_EXTEND == GET_CODE (XEXP (x, 0))) 13042 { 13043 *total = COSTS_N_INSNS (2); 13044 return true; 13045 } 13046 13047 if (!CONST_INT_P (XEXP (x, 1))) 13048 { 13049 *total = COSTS_N_INSNS (!speed ? 5 : 41); 13050 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, 13051 speed); 13052 } 13053 else 13054 switch (INTVAL (XEXP (x, 1))) 13055 { 13056 case 0: 13057 *total = 0; 13058 break; 13059 case 1: 13060 case 8: 13061 *total = COSTS_N_INSNS (2); 13062 break; 13063 case 9: 13064 *total = COSTS_N_INSNS (3); 13065 break; 13066 case 2: 13067 case 3: 13068 case 10: 13069 case 15: 13070 *total = COSTS_N_INSNS (4); 13071 break; 13072 case 7: 13073 case 11: 13074 case 12: 13075 *total = COSTS_N_INSNS (5); 13076 break; 13077 case 4: 13078 *total = COSTS_N_INSNS (!speed ? 5 : 8); 13079 break; 13080 case 6: 13081 *total = COSTS_N_INSNS (!speed ? 5 : 9); 13082 break; 13083 case 5: 13084 *total = COSTS_N_INSNS (!speed ? 5 : 10); 13085 break; 13086 default: 13087 *total = COSTS_N_INSNS (!speed ? 5 : 41); 13088 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, 13089 speed); 13090 } 13091 break; 13092 13093 case E_PSImode: 13094 if (!CONST_INT_P (XEXP (x, 1))) 13095 { 13096 *total = COSTS_N_INSNS (!speed ? 6 : 73); 13097 } 13098 else 13099 switch (INTVAL (XEXP (x, 1))) 13100 { 13101 case 0: 13102 *total = 0; 13103 break; 13104 case 1: 13105 case 8: 13106 case 16: 13107 *total = COSTS_N_INSNS (3); 13108 break; 13109 case 23: 13110 *total = COSTS_N_INSNS (5); 13111 break; 13112 default: 13113 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1))); 13114 break; 13115 } 13116 break; 13117 13118 case E_SImode: 13119 if (!CONST_INT_P (XEXP (x, 1))) 13120 { 13121 *total = COSTS_N_INSNS (!speed ? 7 : 113); 13122 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, 13123 speed); 13124 } 13125 else 13126 switch (INTVAL (XEXP (x, 1))) 13127 { 13128 case 0: 13129 *total = 0; 13130 break; 13131 case 24: 13132 *total = COSTS_N_INSNS (3); 13133 break; 13134 case 1: 13135 case 8: 13136 case 16: 13137 *total = COSTS_N_INSNS (4); 13138 break; 13139 case 31: 13140 *total = COSTS_N_INSNS (6); 13141 break; 13142 case 2: 13143 *total = COSTS_N_INSNS (!speed ? 7 : 8); 13144 break; 13145 default: 13146 *total = COSTS_N_INSNS (!speed ? 7 : 113); 13147 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, 13148 speed); 13149 } 13150 break; 13151 13152 default: 13153 return false; 13154 } 13155 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed); 13156 return true; 13157 13158 case ASHIFTRT: 13159 switch (mode) 13160 { 13161 case E_QImode: 13162 if (!CONST_INT_P (XEXP (x, 1))) 13163 { 13164 *total = COSTS_N_INSNS (!speed ? 4 : 17); 13165 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, 13166 speed); 13167 } 13168 else 13169 { 13170 val = INTVAL (XEXP (x, 1)); 13171 if (val == 6) 13172 *total = COSTS_N_INSNS (4); 13173 else if (val == 7) 13174 *total = COSTS_N_INSNS (2); 13175 else if (val >= 0 && val <= 7) 13176 *total = COSTS_N_INSNS (val); 13177 else 13178 *total = COSTS_N_INSNS (1); 13179 } 13180 break; 13181 13182 case E_HImode: 13183 if (!CONST_INT_P (XEXP (x, 1))) 13184 { 13185 *total = COSTS_N_INSNS (!speed ? 5 : 41); 13186 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, 13187 speed); 13188 } 13189 else 13190 switch (INTVAL (XEXP (x, 1))) 13191 { 13192 case 0: 13193 *total = 0; 13194 break; 13195 case 1: 13196 *total = COSTS_N_INSNS (2); 13197 break; 13198 case 15: 13199 *total = COSTS_N_INSNS (3); 13200 break; 13201 case 2: 13202 case 7: 13203 case 8: 13204 case 9: 13205 *total = COSTS_N_INSNS (4); 13206 break; 13207 case 10: 13208 case 14: 13209 *total = COSTS_N_INSNS (5); 13210 break; 13211 case 11: 13212 *total = COSTS_N_INSNS (!speed ? 5 : 6); 13213 break; 13214 case 12: 13215 *total = COSTS_N_INSNS (!speed ? 5 : 7); 13216 break; 13217 case 6: 13218 case 13: 13219 *total = COSTS_N_INSNS (!speed ? 5 : 8); 13220 break; 13221 default: 13222 *total = COSTS_N_INSNS (!speed ? 5 : 41); 13223 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, 13224 speed); 13225 } 13226 break; 13227 13228 case E_PSImode: 13229 if (!CONST_INT_P (XEXP (x, 1))) 13230 { 13231 *total = COSTS_N_INSNS (!speed ? 6 : 73); 13232 } 13233 else 13234 switch (INTVAL (XEXP (x, 1))) 13235 { 13236 case 0: 13237 *total = 0; 13238 break; 13239 case 1: 13240 *total = COSTS_N_INSNS (3); 13241 break; 13242 case 16: 13243 case 8: 13244 *total = COSTS_N_INSNS (5); 13245 break; 13246 case 23: 13247 *total = COSTS_N_INSNS (4); 13248 break; 13249 default: 13250 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1))); 13251 break; 13252 } 13253 break; 13254 13255 case E_SImode: 13256 if (!CONST_INT_P (XEXP (x, 1))) 13257 { 13258 *total = COSTS_N_INSNS (!speed ? 7 : 113); 13259 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, 13260 speed); 13261 } 13262 else 13263 switch (INTVAL (XEXP (x, 1))) 13264 { 13265 case 0: 13266 *total = 0; 13267 break; 13268 case 1: 13269 *total = COSTS_N_INSNS (4); 13270 break; 13271 case 8: 13272 case 16: 13273 case 24: 13274 *total = COSTS_N_INSNS (6); 13275 break; 13276 case 2: 13277 *total = COSTS_N_INSNS (!speed ? 7 : 8); 13278 break; 13279 case 31: 13280 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 5); 13281 break; 13282 default: 13283 *total = COSTS_N_INSNS (!speed ? 7 : 113); 13284 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, 13285 speed); 13286 } 13287 break; 13288 13289 default: 13290 return false; 13291 } 13292 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed); 13293 return true; 13294 13295 case LSHIFTRT: 13296 if (outer_code == TRUNCATE) 13297 { 13298 *total = avr_mul_highpart_cost (x, speed); 13299 return true; 13300 } 13301 13302 switch (mode) 13303 { 13304 case E_QImode: 13305 if (!CONST_INT_P (XEXP (x, 1))) 13306 { 13307 *total = COSTS_N_INSNS (!speed ? 4 : 17); 13308 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, 13309 speed); 13310 } 13311 else 13312 { 13313 val = INTVAL (XEXP (x, 1)); 13314 if (val == 7) 13315 *total = COSTS_N_INSNS (3); 13316 else if (val >= 0 && val <= 7) 13317 *total = COSTS_N_INSNS (val); 13318 else 13319 *total = COSTS_N_INSNS (1); 13320 } 13321 break; 13322 13323 case E_HImode: 13324 if (!CONST_INT_P (XEXP (x, 1))) 13325 { 13326 *total = COSTS_N_INSNS (!speed ? 5 : 41); 13327 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, 13328 speed); 13329 } 13330 else 13331 switch (INTVAL (XEXP (x, 1))) 13332 { 13333 case 0: 13334 *total = 0; 13335 break; 13336 case 1: 13337 case 8: 13338 *total = COSTS_N_INSNS (2); 13339 break; 13340 case 9: 13341 *total = COSTS_N_INSNS (3); 13342 break; 13343 case 2: 13344 case 10: 13345 case 15: 13346 *total = COSTS_N_INSNS (4); 13347 break; 13348 case 7: 13349 case 11: 13350 *total = COSTS_N_INSNS (5); 13351 break; 13352 case 3: 13353 case 12: 13354 case 13: 13355 case 14: 13356 *total = COSTS_N_INSNS (!speed ? 5 : 6); 13357 break; 13358 case 4: 13359 *total = COSTS_N_INSNS (!speed ? 5 : 7); 13360 break; 13361 case 5: 13362 case 6: 13363 *total = COSTS_N_INSNS (!speed ? 5 : 9); 13364 break; 13365 default: 13366 *total = COSTS_N_INSNS (!speed ? 5 : 41); 13367 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, 13368 speed); 13369 } 13370 break; 13371 13372 case E_PSImode: 13373 if (!CONST_INT_P (XEXP (x, 1))) 13374 { 13375 *total = COSTS_N_INSNS (!speed ? 6 : 73); 13376 } 13377 else 13378 switch (INTVAL (XEXP (x, 1))) 13379 { 13380 case 0: 13381 *total = 0; 13382 break; 13383 case 1: 13384 case 8: 13385 case 16: 13386 *total = COSTS_N_INSNS (3); 13387 break; 13388 case 23: 13389 *total = COSTS_N_INSNS (5); 13390 break; 13391 default: 13392 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1))); 13393 break; 13394 } 13395 break; 13396 13397 case E_SImode: 13398 if (!CONST_INT_P (XEXP (x, 1))) 13399 { 13400 *total = COSTS_N_INSNS (!speed ? 7 : 113); 13401 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, 13402 speed); 13403 } 13404 else 13405 switch (INTVAL (XEXP (x, 1))) 13406 { 13407 case 0: 13408 *total = 0; 13409 break; 13410 case 1: 13411 *total = COSTS_N_INSNS (4); 13412 break; 13413 case 2: 13414 *total = COSTS_N_INSNS (!speed ? 7 : 8); 13415 break; 13416 case 8: 13417 case 16: 13418 case 24: 13419 *total = COSTS_N_INSNS (4); 13420 break; 13421 case 31: 13422 *total = COSTS_N_INSNS (6); 13423 break; 13424 default: 13425 *total = COSTS_N_INSNS (!speed ? 7 : 113); 13426 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, 13427 speed); 13428 } 13429 break; 13430 13431 default: 13432 return false; 13433 } 13434 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed); 13435 return true; 13436 13437 case COMPARE: 13438 switch (GET_MODE (XEXP (x, 0))) 13439 { 13440 case E_QImode: 13441 *total = COSTS_N_INSNS (1); 13442 if (!CONST_INT_P (XEXP (x, 1))) 13443 *total += avr_operand_rtx_cost (XEXP (x, 1), QImode, code, 13444 1, speed); 13445 break; 13446 13447 case E_HImode: 13448 *total = COSTS_N_INSNS (2); 13449 if (!CONST_INT_P (XEXP (x, 1))) 13450 *total += avr_operand_rtx_cost (XEXP (x, 1), HImode, code, 13451 1, speed); 13452 else if (INTVAL (XEXP (x, 1)) != 0) 13453 *total += COSTS_N_INSNS (1); 13454 break; 13455 13456 case E_PSImode: 13457 *total = COSTS_N_INSNS (3); 13458 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) != 0) 13459 *total += COSTS_N_INSNS (2); 13460 break; 13461 13462 case E_SImode: 13463 *total = COSTS_N_INSNS (4); 13464 if (!CONST_INT_P (XEXP (x, 1))) 13465 *total += avr_operand_rtx_cost (XEXP (x, 1), SImode, code, 13466 1, speed); 13467 else if (INTVAL (XEXP (x, 1)) != 0) 13468 *total += COSTS_N_INSNS (3); 13469 break; 13470 13471 default: 13472 return false; 13473 } 13474 *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)), 13475 code, 0, speed); 13476 return true; 13477 13478 case TRUNCATE: 13479 if (LSHIFTRT == GET_CODE (XEXP (x, 0))) 13480 { 13481 *total = avr_mul_highpart_cost (XEXP (x, 0), speed); 13482 return true; 13483 } 13484 break; 13485 13486 case IF_THEN_ELSE: 13487 if (outer_code == SET 13488 && XEXP (x, 2) == pc_rtx 13489 && ordered_comparison_operator (XEXP (x, 0), VOIDmode)) 13490 { 13491 *total = avr_cbranch_cost (XEXP (x, 0)); 13492 return true; 13493 } 13494 13495 default: 13496 break; 13497 } 13498 return false; 13499 } 13500 13501 13502 /* Implement `TARGET_RTX_COSTS'. */ 13503 13504 static bool 13505 avr_rtx_costs (rtx x, machine_mode mode, int outer_code, 13506 int opno, int *total, bool speed) 13507 { 13508 bool done = avr_rtx_costs_1 (x, mode, outer_code, opno, total, speed); 13509 13510 if (avr_log.rtx_costs) 13511 { 13512 avr_edump ("\n%?=%b (%s) total=%d, outer=%C:\n%r\n", 13513 done, speed ? "speed" : "size", *total, outer_code, x); 13514 } 13515 13516 return done; 13517 } 13518 13519 13520 /* Implement `TARGET_INSN_COST'. */ 13521 /* For some insns, it is not enough to look at the cost of the SET_SRC. 13522 In that case, have a look at the entire insn, e.g. during insn combine. */ 13523 13524 static int 13525 avr_insn_cost (rtx_insn *insn, bool speed) 13526 { 13527 const int unknown_cost = -1; 13528 int cost = unknown_cost; 13529 13530 rtx set = single_set (insn); 13531 13532 if (set 13533 && ZERO_EXTRACT == GET_CODE (SET_DEST (set))) 13534 { 13535 // Try find anything that would flip the extracted bit. 13536 bool not_bit_p = false; 13537 13538 subrtx_iterator::array_type array; 13539 FOR_EACH_SUBRTX (iter, array, SET_SRC (set), NONCONST) 13540 { 13541 enum rtx_code code = GET_CODE (*iter); 13542 not_bit_p |= code == NOT || code == XOR || code == GE; 13543 } 13544 13545 // Don't go too deep into the analysis. In almost all cases, 13546 // using BLD/BST is the best we can do for single-bit moves, 13547 // even considering CSE. 13548 cost = COSTS_N_INSNS (2 + not_bit_p); 13549 } 13550 13551 if (cost != unknown_cost) 13552 { 13553 if (avr_log.rtx_costs) 13554 avr_edump ("\n%? (%s) insn_cost=%d\n%r\n", 13555 speed ? "speed" : "size", cost, insn); 13556 return cost; 13557 } 13558 13559 // Resort to what rtlanal.cc::insn_cost() implements as a default 13560 // when targetm.insn_cost() is not implemented. 13561 13562 return pattern_cost (PATTERN (insn), speed); 13563 } 13564 13565 13566 /* Implement `TARGET_ADDRESS_COST'. */ 13567 13568 static int 13569 avr_address_cost (rtx x, machine_mode mode, addr_space_t /*as*/, 13570 bool /*speed*/) 13571 { 13572 int cost = 4; 13573 13574 if (GET_CODE (x) == PLUS 13575 && CONST_INT_P (XEXP (x, 1)) 13576 && (REG_P (XEXP (x, 0)) 13577 || SUBREG_P (XEXP (x, 0)))) 13578 { 13579 if (INTVAL (XEXP (x, 1)) > MAX_LD_OFFSET(mode)) 13580 cost = 18; 13581 } 13582 else if (CONSTANT_ADDRESS_P (x)) 13583 { 13584 if (io_address_operand (x, QImode)) 13585 cost = 2; 13586 13587 if (AVR_TINY 13588 && avr_address_tiny_absdata_p (x, QImode)) 13589 cost = 2; 13590 } 13591 13592 if (avr_log.address_cost) 13593 avr_edump ("\n%?: %d = %r\n", cost, x); 13594 13595 return cost; 13596 } 13597 13598 /* Test for extra memory constraint 'Q'. 13599 It's a memory address based on Y or Z pointer with valid displacement. */ 13600 13601 int 13602 extra_constraint_Q (rtx x) 13603 { 13604 int ok = 0; 13605 rtx plus = XEXP (x, 0); 13606 13607 if (GET_CODE (plus) == PLUS 13608 && REG_P (XEXP (plus, 0)) 13609 && CONST_INT_P (XEXP (plus, 1)) 13610 && (INTVAL (XEXP (plus, 1)) 13611 <= MAX_LD_OFFSET (GET_MODE (x)))) 13612 { 13613 rtx xx = XEXP (plus, 0); 13614 int regno = REGNO (xx); 13615 13616 ok = (/* allocate pseudos */ 13617 regno >= FIRST_PSEUDO_REGISTER 13618 /* strictly check */ 13619 || regno == REG_Z || regno == REG_Y 13620 /* XXX frame & arg pointer checks */ 13621 || xx == frame_pointer_rtx 13622 || xx == arg_pointer_rtx); 13623 13624 if (avr_log.constraints) 13625 avr_edump ("\n%?=%d reload_completed=%d reload_in_progress=%d\n %r\n", 13626 ok, reload_completed, reload_in_progress, x); 13627 } 13628 13629 return ok; 13630 } 13631 13632 /* Convert condition code CONDITION to the valid AVR condition code. */ 13633 13634 RTX_CODE 13635 avr_normalize_condition (RTX_CODE condition) 13636 { 13637 switch (condition) 13638 { 13639 case GT: 13640 return GE; 13641 case GTU: 13642 return GEU; 13643 case LE: 13644 return LT; 13645 case LEU: 13646 return LTU; 13647 default: 13648 gcc_unreachable (); 13649 } 13650 } 13651 13652 13653 /* Returns register number for function return value.*/ 13654 13655 static inline unsigned int 13656 avr_ret_register (void) 13657 { 13658 return REG_24; 13659 } 13660 13661 13662 /* Implement `TARGET_FUNCTION_VALUE_REGNO_P'. */ 13663 13664 static bool 13665 avr_function_value_regno_p (const unsigned int regno) 13666 { 13667 return regno == avr_ret_register (); 13668 } 13669 13670 13671 /* Implement `TARGET_LIBCALL_VALUE'. */ 13672 /* Create an RTX representing the place where a 13673 library function returns a value of mode MODE. */ 13674 13675 static rtx 13676 avr_libcall_value (machine_mode mode, const_rtx /*func*/) 13677 { 13678 int offs = GET_MODE_SIZE (mode); 13679 13680 if (offs <= 4) 13681 offs = (offs + 1) & ~1; 13682 13683 return gen_rtx_REG (mode, avr_ret_register () + 2 - offs); 13684 } 13685 13686 13687 /* Implement `TARGET_FUNCTION_VALUE'. */ 13688 /* Create an RTX representing the place where a 13689 function returns a value of data type VALTYPE. */ 13690 13691 static rtx 13692 avr_function_value (const_tree type, const_tree /*fn_decl_or_type*/, 13693 bool /*outgoing*/) 13694 { 13695 if (TYPE_MODE (type) != BLKmode) 13696 return avr_libcall_value (TYPE_MODE (type), NULL_RTX); 13697 13698 unsigned int offs = int_size_in_bytes (type); 13699 if (offs < 2) 13700 offs = 2; 13701 if (offs > 2 && offs < GET_MODE_SIZE (SImode)) 13702 offs = GET_MODE_SIZE (SImode); 13703 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode)) 13704 offs = GET_MODE_SIZE (DImode); 13705 13706 return gen_rtx_REG (BLKmode, avr_ret_register () + 2 - offs); 13707 } 13708 13709 int 13710 test_hard_reg_class (enum reg_class rclass, rtx x) 13711 { 13712 int regno = true_regnum (x); 13713 if (regno < 0) 13714 return 0; 13715 13716 if (TEST_HARD_REG_CLASS (rclass, regno)) 13717 return 1; 13718 13719 return 0; 13720 } 13721 13722 13723 /* Helper for jump_over_one_insn_p: Test if INSN is a 2-word instruction 13724 and thus is suitable to be skipped by CPSE, SBRC, etc. */ 13725 13726 static bool 13727 avr_2word_insn_p (rtx_insn *insn) 13728 { 13729 if (TARGET_SKIP_BUG || !insn || get_attr_length (insn) != 2) 13730 { 13731 return false; 13732 } 13733 13734 switch (INSN_CODE (insn)) 13735 { 13736 default: 13737 return false; 13738 13739 case CODE_FOR_movqi_insn: 13740 case CODE_FOR_movuqq_insn: 13741 case CODE_FOR_movqq_insn: 13742 { 13743 rtx set = single_set (insn); 13744 rtx src = SET_SRC (set); 13745 rtx dest = SET_DEST (set); 13746 13747 /* Factor out LDS and STS from movqi_insn. */ 13748 13749 if (MEM_P (dest) 13750 && (REG_P (src) || src == CONST0_RTX (GET_MODE (dest)))) 13751 { 13752 return CONSTANT_ADDRESS_P (XEXP (dest, 0)); 13753 } 13754 else if (REG_P (dest) 13755 && MEM_P (src)) 13756 { 13757 return CONSTANT_ADDRESS_P (XEXP (src, 0)); 13758 } 13759 13760 return false; 13761 } 13762 13763 case CODE_FOR_call_insn: 13764 case CODE_FOR_call_value_insn: 13765 return true; 13766 } 13767 } 13768 13769 13770 int 13771 jump_over_one_insn_p (rtx_insn *insn, rtx dest) 13772 { 13773 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF 13774 ? XEXP (dest, 0) 13775 : dest); 13776 int jump_addr = INSN_ADDRESSES (INSN_UID (insn)); 13777 int dest_addr = INSN_ADDRESSES (uid); 13778 int jump_offset = dest_addr - jump_addr - get_attr_length (insn); 13779 13780 return (jump_offset == 1 13781 || (jump_offset == 2 13782 && avr_2word_insn_p (next_active_insn (insn)))); 13783 } 13784 13785 13786 /* Implement `TARGET_HARD_REGNO_NREGS'. CCmode is four units for historical 13787 reasons. If this hook is not defined, TARGET_HARD_REGNO_NREGS 13788 reports that CCmode requires four registers. 13789 Define this hook to allow CCmode to fit in a single REG_CC. For 13790 other modes and regs, return the number of words in mode (i.e whatever 13791 the default implementation of the hook returned). */ 13792 13793 static unsigned int 13794 avr_hard_regno_nregs (unsigned int regno, machine_mode mode) 13795 { 13796 if (regno == REG_CC && mode == CCmode) 13797 return 1; 13798 13799 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); 13800 } 13801 13802 13803 /* Implement `TARGET_HARD_REGNO_MODE_OK'. On the enhanced core, anything 13804 larger than 1 byte must start in even numbered register for "movw" to 13805 work (this way we don't have to check for odd registers everywhere). */ 13806 13807 static bool 13808 avr_hard_regno_mode_ok (unsigned int regno, machine_mode mode) 13809 { 13810 if (regno == REG_CC) 13811 return mode == CCmode; 13812 13813 /* NOTE: 8-bit values must not be disallowed for R28 or R29. 13814 Disallowing QI et al. in these regs might lead to code like 13815 (set (subreg:QI (reg:HI 28) n) ...) 13816 which will result in wrong code because reload does not 13817 handle SUBREGs of hard regsisters like this. 13818 This could be fixed in reload. However, it appears 13819 that fixing reload is not wanted by reload people. */ 13820 13821 /* Any GENERAL_REGS register can hold 8-bit values. */ 13822 13823 if (GET_MODE_SIZE (mode) == 1) 13824 return true; 13825 13826 /* FIXME: Ideally, the following test is not needed. 13827 However, it turned out that it can reduce the number 13828 of spill fails. AVR and it's poor endowment with 13829 address registers is extreme stress test for reload. */ 13830 13831 if (GET_MODE_SIZE (mode) >= 4 13832 && regno >= REG_X) 13833 return false; 13834 13835 /* All modes larger than 8 bits should start in an even register. */ 13836 13837 return !(regno & 1); 13838 } 13839 13840 13841 /* Implement `TARGET_HARD_REGNO_CALL_PART_CLOBBERED'. */ 13842 13843 static bool 13844 avr_hard_regno_call_part_clobbered (unsigned, unsigned regno, 13845 machine_mode mode) 13846 { 13847 /* FIXME: This hook gets called with MODE:REGNO combinations that don't 13848 represent valid hard registers like, e.g. HI:29. Returning TRUE 13849 for such registers can lead to performance degradation as mentioned 13850 in PR53595. Thus, report invalid hard registers as FALSE. */ 13851 13852 if (!avr_hard_regno_mode_ok (regno, mode)) 13853 return 0; 13854 13855 /* Return true if any of the following boundaries is crossed: 13856 17/18 or 19/20 (if AVR_TINY), 27/28 and 29/30. */ 13857 13858 return ((regno <= LAST_CALLEE_SAVED_REG 13859 && regno + GET_MODE_SIZE (mode) > 1 + LAST_CALLEE_SAVED_REG) 13860 || (regno < REG_Y && regno + GET_MODE_SIZE (mode) > REG_Y) 13861 || (regno < REG_Z && regno + GET_MODE_SIZE (mode) > REG_Z)); 13862 } 13863 13864 13865 /* Implement `MODE_CODE_BASE_REG_CLASS'. */ 13866 13867 enum reg_class 13868 avr_mode_code_base_reg_class (machine_mode /*mode*/, addr_space_t as, 13869 RTX_CODE outer_code, RTX_CODE /*index_code*/) 13870 { 13871 if (!ADDR_SPACE_GENERIC_P (as)) 13872 { 13873 return POINTER_Z_REGS; 13874 } 13875 13876 if (AVR_TINY) 13877 // We allow all offsets for all pointer regs. Pass .avr-fuse-add 13878 // will rectify it (register allocation cannot do it). 13879 return POINTER_REGS; 13880 13881 if (!avr_strict_X) 13882 return reload_completed ? BASE_POINTER_REGS : POINTER_REGS; 13883 13884 return PLUS == outer_code ? BASE_POINTER_REGS : POINTER_REGS; 13885 } 13886 13887 13888 /* Implement `REGNO_MODE_CODE_OK_FOR_BASE_P'. */ 13889 13890 bool 13891 avr_regno_mode_code_ok_for_base_p (int regno, machine_mode /*mode*/, 13892 addr_space_t as, RTX_CODE outer_code, 13893 RTX_CODE /*index_code*/) 13894 { 13895 bool ok = false; 13896 13897 if (!ADDR_SPACE_GENERIC_P (as)) 13898 { 13899 if (regno < FIRST_PSEUDO_REGISTER 13900 && regno == REG_Z) 13901 { 13902 return true; 13903 } 13904 13905 if (reg_renumber) 13906 { 13907 regno = reg_renumber[regno]; 13908 13909 if (regno == REG_Z) 13910 { 13911 return true; 13912 } 13913 } 13914 13915 return false; 13916 } 13917 13918 if (regno < FIRST_PSEUDO_REGISTER 13919 && (regno == REG_X 13920 || regno == REG_Y 13921 || regno == REG_Z 13922 || regno == ARG_POINTER_REGNUM)) 13923 { 13924 ok = true; 13925 } 13926 else if (reg_renumber) 13927 { 13928 regno = reg_renumber[regno]; 13929 13930 if (regno == REG_X 13931 || regno == REG_Y 13932 || regno == REG_Z 13933 || regno == ARG_POINTER_REGNUM) 13934 { 13935 ok = true; 13936 } 13937 } 13938 13939 if (avr_strict_X 13940 // On Reduced Tiny, all registers are equal in that they do not 13941 // support PLUS addressing; respective addresses will be fake, 13942 // even for the frame pointer. They must be handled in the 13943 // printers by add-store-sub sequences -- or may be split after 13944 // reload by `avr_split_tiny_move'. 13945 && ! AVR_TINY 13946 && PLUS == outer_code 13947 && regno == REG_X) 13948 { 13949 ok = false; 13950 } 13951 13952 return ok; 13953 } 13954 13955 13956 /* A helper for `output_reload_insisf' and `output_reload_inhi'. */ 13957 /* Set 32-bit register OP[0] to compile-time constant OP[1]. 13958 CLOBBER_REG is a QI clobber register or NULL_RTX. 13959 LEN == NULL: output instructions. 13960 LEN != NULL: set *LEN to the length of the instruction sequence 13961 (in words) printed with LEN = NULL. 13962 If CLEAR_P is true, OP[0] had been cleard to Zero already. 13963 If CLEAR_P is false, nothing is known about OP[0]. 13964 13965 The effect on cc0 is as follows: 13966 13967 Load 0 to any register except ZERO_REG : NONE 13968 Load ld register with any value : NONE 13969 Anything else: : CLOBBER */ 13970 13971 static void 13972 output_reload_in_const (rtx *op, rtx clobber_reg, int *len, bool clear_p) 13973 { 13974 rtx src = op[1]; 13975 rtx dest = op[0]; 13976 rtx xval, xdest[4]; 13977 int ival[4]; 13978 int clobber_val = 1234; 13979 bool cooked_clobber_p = false; 13980 bool set_p = false; 13981 machine_mode mode = GET_MODE (dest); 13982 int n_bytes = GET_MODE_SIZE (mode); 13983 13984 gcc_assert (REG_P (dest) 13985 && CONSTANT_P (src)); 13986 13987 if (len) 13988 *len = 0; 13989 13990 /* (REG:SI 14) is special: It's neither in LD_REGS nor in NO_LD_REGS 13991 but has some subregs that are in LD_REGS. Use the MSB (REG:QI 17). */ 13992 13993 if (REGNO (dest) < REG_16 13994 && REGNO (dest) + GET_MODE_SIZE (mode) > REG_16) 13995 { 13996 clobber_reg = all_regs_rtx[REGNO (dest) + n_bytes - 1]; 13997 } 13998 13999 /* We might need a clobber reg but don't have one. Look at the value to 14000 be loaded more closely. A clobber is only needed if it is a symbol 14001 or contains a byte that is neither 0, -1 or a power of 2. */ 14002 14003 if (NULL_RTX == clobber_reg 14004 && !test_hard_reg_class (LD_REGS, dest) 14005 && (! (CONST_INT_P (src) || CONST_FIXED_P (src) || CONST_DOUBLE_P (src)) 14006 || !avr_popcount_each_byte (src, n_bytes, 14007 (1 << 0) | (1 << 1) | (1 << 8)))) 14008 { 14009 /* We have no clobber register but need one. Cook one up. 14010 That's cheaper than loading from constant pool. */ 14011 14012 cooked_clobber_p = true; 14013 clobber_reg = all_regs_rtx[REG_Z + 1]; 14014 avr_asm_len ("mov __tmp_reg__,%0", &clobber_reg, len, 1); 14015 } 14016 14017 /* Now start filling DEST from LSB to MSB. */ 14018 14019 for (int n = 0; n < n_bytes; n++) 14020 { 14021 bool done_byte = false; 14022 rtx xop[3]; 14023 14024 /* Crop the n-th destination byte. */ 14025 14026 xdest[n] = simplify_gen_subreg (QImode, dest, mode, n); 14027 int ldreg_p = test_hard_reg_class (LD_REGS, xdest[n]); 14028 14029 if (!CONST_INT_P (src) 14030 && !CONST_FIXED_P (src) 14031 && !CONST_DOUBLE_P (src)) 14032 { 14033 static const char *const asm_code[][2] = 14034 { 14035 { "ldi %2,lo8(%1)" CR_TAB "mov %0,%2", "ldi %0,lo8(%1)" }, 14036 { "ldi %2,hi8(%1)" CR_TAB "mov %0,%2", "ldi %0,hi8(%1)" }, 14037 { "ldi %2,hlo8(%1)" CR_TAB "mov %0,%2", "ldi %0,hlo8(%1)" }, 14038 { "ldi %2,hhi8(%1)" CR_TAB "mov %0,%2", "ldi %0,hhi8(%1)" } 14039 }; 14040 14041 xop[0] = xdest[n]; 14042 xop[1] = src; 14043 xop[2] = clobber_reg; 14044 14045 avr_asm_len (asm_code[n][ldreg_p], xop, len, ldreg_p ? 1 : 2); 14046 14047 continue; 14048 } 14049 14050 /* Crop the n-th source byte. */ 14051 14052 xval = simplify_gen_subreg (QImode, src, mode, n); 14053 ival[n] = INTVAL (xval); 14054 14055 /* Look if we can reuse the low word by means of MOVW. */ 14056 14057 if (n == 2 14058 && n_bytes >= 4 14059 && AVR_HAVE_MOVW) 14060 { 14061 rtx lo16 = simplify_gen_subreg (HImode, src, mode, 0); 14062 rtx hi16 = simplify_gen_subreg (HImode, src, mode, 2); 14063 14064 if (INTVAL (lo16) == INTVAL (hi16)) 14065 { 14066 if (INTVAL (lo16) != 0 || !clear_p) 14067 avr_asm_len ("movw %C0,%A0", &op[0], len, 1); 14068 14069 break; 14070 } 14071 } 14072 14073 /* Don't use CLR so that cc0 is set as expected. */ 14074 14075 if (ival[n] == 0) 14076 { 14077 if (!clear_p) 14078 avr_asm_len (ldreg_p ? "ldi %0,0" 14079 : AVR_ZERO_REGNO == REGNO (xdest[n]) ? "clr %0" 14080 : "mov %0,__zero_reg__", 14081 &xdest[n], len, 1); 14082 continue; 14083 } 14084 14085 if (clobber_val == ival[n] 14086 && REGNO (clobber_reg) == REGNO (xdest[n])) 14087 { 14088 continue; 14089 } 14090 14091 /* LD_REGS can use LDI to move a constant value */ 14092 14093 if (ldreg_p) 14094 { 14095 xop[0] = xdest[n]; 14096 xop[1] = xval; 14097 avr_asm_len ("ldi %0,lo8(%1)", xop, len, 1); 14098 continue; 14099 } 14100 14101 /* Try to reuse value already loaded in some lower byte. */ 14102 14103 for (int j = 0; j < n; j++) 14104 if (ival[j] == ival[n]) 14105 { 14106 xop[0] = xdest[n]; 14107 xop[1] = xdest[j]; 14108 14109 avr_asm_len ("mov %0,%1", xop, len, 1); 14110 done_byte = true; 14111 break; 14112 } 14113 14114 if (done_byte) 14115 continue; 14116 14117 /* Need no clobber reg for -1: Use CLR/DEC */ 14118 14119 if (ival[n] == -1) 14120 { 14121 if (!clear_p) 14122 avr_asm_len ("clr %0", &xdest[n], len, 1); 14123 14124 avr_asm_len ("dec %0", &xdest[n], len, 1); 14125 continue; 14126 } 14127 else if (ival[n] == 1) 14128 { 14129 if (!clear_p) 14130 avr_asm_len ("clr %0", &xdest[n], len, 1); 14131 14132 avr_asm_len ("inc %0", &xdest[n], len, 1); 14133 continue; 14134 } 14135 14136 /* Use T flag or INC to manage powers of 2 if we have 14137 no clobber reg. */ 14138 14139 if (NULL_RTX == clobber_reg 14140 && single_one_operand (xval, QImode)) 14141 { 14142 xop[0] = xdest[n]; 14143 xop[1] = GEN_INT (exact_log2 (ival[n] & GET_MODE_MASK (QImode))); 14144 14145 gcc_assert (constm1_rtx != xop[1]); 14146 14147 if (!set_p) 14148 { 14149 set_p = true; 14150 avr_asm_len ("set", xop, len, 1); 14151 } 14152 14153 if (!clear_p) 14154 avr_asm_len ("clr %0", xop, len, 1); 14155 14156 avr_asm_len ("bld %0,%1", xop, len, 1); 14157 continue; 14158 } 14159 14160 /* We actually need the LD_REGS clobber reg. */ 14161 14162 gcc_assert (NULL_RTX != clobber_reg); 14163 14164 xop[0] = xdest[n]; 14165 xop[1] = xval; 14166 xop[2] = clobber_reg; 14167 clobber_val = ival[n]; 14168 14169 avr_asm_len ("ldi %2,lo8(%1)" CR_TAB 14170 "mov %0,%2", xop, len, 2); 14171 } 14172 14173 /* If we cooked up a clobber reg above, restore it. */ 14174 14175 if (cooked_clobber_p) 14176 { 14177 avr_asm_len ("mov %0,__tmp_reg__", &clobber_reg, len, 1); 14178 } 14179 } 14180 14181 14182 /* Reload the constant OP[1] into the HI register OP[0]. 14183 CLOBBER_REG is a QI clobber reg needed to move vast majority of consts 14184 into a NO_LD_REGS register. If CLOBBER_REG is NULL_RTX we either don't 14185 need a clobber reg or have to cook one up. 14186 14187 PLEN == NULL: Output instructions. 14188 PLEN != NULL: Output nothing. Set *PLEN to number of words occupied 14189 by the insns printed. 14190 14191 Return "". */ 14192 14193 const char * 14194 output_reload_inhi (rtx *op, rtx clobber_reg, int *plen) 14195 { 14196 output_reload_in_const (op, clobber_reg, plen, false); 14197 return ""; 14198 } 14199 14200 14201 /* Reload a SI or SF compile time constant OP[1] into the register OP[0]. 14202 CLOBBER_REG is a QI clobber reg needed to move vast majority of consts 14203 into a NO_LD_REGS register. If CLOBBER_REG is NULL_RTX we either don't 14204 need a clobber reg or have to cook one up. 14205 14206 LEN == NULL: Output instructions. 14207 14208 LEN != NULL: Output nothing. Set *LEN to number of words occupied 14209 by the insns printed. 14210 14211 Return "". */ 14212 14213 const char * 14214 output_reload_insisf (rtx *op, rtx clobber_reg, int *len) 14215 { 14216 if (AVR_HAVE_MOVW 14217 && !test_hard_reg_class (LD_REGS, op[0]) 14218 && (CONST_INT_P (op[1]) 14219 || CONST_FIXED_P (op[1]) 14220 || CONST_DOUBLE_P (op[1]))) 14221 { 14222 /* In some cases it is better to clear the destination beforehand, e.g. 14223 14224 CLR R2 CLR R3 MOVW R4,R2 INC R2 14225 14226 is shorther than 14227 14228 CLR R2 INC R2 CLR R3 CLR R4 CLR R5 14229 14230 We find it too tedious to work that out in the print function. 14231 Instead, we call the print function twice to get the lengths of 14232 both methods and use the shortest one. */ 14233 14234 int len_clr, len_noclr; 14235 output_reload_in_const (op, clobber_reg, &len_clr, true); 14236 output_reload_in_const (op, clobber_reg, &len_noclr, false); 14237 14238 if (len_noclr - len_clr == 4) 14239 { 14240 /* Default needs 4 CLR instructions: clear register beforehand. */ 14241 14242 avr_asm_len ("mov %A0,__zero_reg__" CR_TAB 14243 "mov %B0,__zero_reg__" CR_TAB 14244 "movw %C0,%A0", &op[0], len, 3); 14245 14246 output_reload_in_const (op, clobber_reg, len, true); 14247 14248 if (len) 14249 *len += 3; 14250 14251 return ""; 14252 } 14253 } 14254 14255 /* Default: destination not pre-cleared. */ 14256 14257 output_reload_in_const (op, clobber_reg, len, false); 14258 return ""; 14259 } 14260 14261 const char * 14262 avr_out_reload_inpsi (rtx *op, rtx clobber_reg, int *len) 14263 { 14264 output_reload_in_const (op, clobber_reg, len, false); 14265 return ""; 14266 } 14267 14268 14269 /* Worker function for `ASM_OUTPUT_ADDR_VEC'. */ 14270 /* Emit jump tables out-of-line so that branches crossing the table 14271 get shorter offsets. If we have JUMP + CALL, then put the tables 14272 in a dedicated non-.text section so that CALLs get better chance to 14273 be relaxed to RCALLs. 14274 14275 We emit the tables by hand because `function_rodata_section' does not 14276 work as expected, cf. PR71151, and we do *NOT* want the table to be 14277 in .rodata, hence setting JUMP_TABLES_IN_TEXT_SECTION = 0 is of limited 14278 use; and setting it to 1 attributes table lengths to branch offsets... 14279 Moreover, fincal.c keeps switching section before each table entry 14280 which we find too fragile as to rely on section caching. */ 14281 14282 void 14283 avr_output_addr_vec (rtx_insn *labl, rtx table) 14284 { 14285 FILE *stream = asm_out_file; 14286 14287 app_disable(); 14288 14289 // Switch to appropriate (sub)section. 14290 14291 if (DECL_SECTION_NAME (current_function_decl) 14292 && symtab_node::get (current_function_decl) 14293 && ! symtab_node::get (current_function_decl)->implicit_section) 14294 { 14295 // .subsection will emit the code after the function and in the 14296 // section as chosen by the user. 14297 14298 switch_to_section (current_function_section ()); 14299 fprintf (stream, "\t.subsection\t1\n"); 14300 } 14301 else 14302 { 14303 // Since PR63223 there is no restriction where to put the table; it 14304 // may even reside above 128 KiB. We put it in a section as high as 14305 // possible and avoid progmem in order not to waste flash <= 64 KiB. 14306 14307 const char *sec_name = ".jumptables.gcc"; 14308 14309 // The table belongs to its host function, therefore use fine 14310 // grained sections so that, if that function is removed by 14311 // --gc-sections, the child table(s) may also be removed. */ 14312 14313 tree asm_name = DECL_ASSEMBLER_NAME (current_function_decl); 14314 const char *fname = IDENTIFIER_POINTER (asm_name); 14315 fname = targetm.strip_name_encoding (fname); 14316 sec_name = ACONCAT ((sec_name, ".", fname, NULL)); 14317 14318 fprintf (stream, "\t.section\t%s,\"%s\",@progbits\n", sec_name, 14319 AVR_HAVE_JMP_CALL ? "a" : "ax"); 14320 } 14321 14322 // Output the label that preceeds the table. 14323 14324 ASM_OUTPUT_ALIGN (stream, 1); 14325 targetm.asm_out.internal_label (stream, "L", CODE_LABEL_NUMBER (labl)); 14326 14327 // Output the table's content. 14328 14329 int vlen = XVECLEN (table, 0); 14330 14331 for (int idx = 0; idx < vlen; idx++) 14332 { 14333 int value = CODE_LABEL_NUMBER (XEXP (XVECEXP (table, 0, idx), 0)); 14334 14335 if (AVR_HAVE_JMP_CALL) 14336 fprintf (stream, "\t.word gs(.L%d)\n", value); 14337 else 14338 fprintf (stream, "\trjmp .L%d\n", value); 14339 } 14340 14341 // Switch back to original section. As we clobbered the section above, 14342 // forget the current section before switching back. 14343 14344 in_section = NULL; 14345 switch_to_section (current_function_section ()); 14346 } 14347 14348 14349 /* Implement `TARGET_CONDITIONAL_REGISTER_USAGE'. */ 14350 14351 static void 14352 avr_conditional_register_usage (void) 14353 { 14354 if (AVR_TINY) 14355 { 14356 const int tiny_reg_alloc_order[] = { 14357 24, 25, 14358 22, 23, 14359 30, 31, 14360 26, 27, 14361 28, 29, 14362 21, 20, 19, 18, 14363 16, 17, 14364 32, 33, 34, 35, 14365 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 14366 }; 14367 14368 /* Set R0-R17 as fixed registers. Reset R0-R17 in call used register list 14369 - R0-R15 are not available in Tiny Core devices 14370 - R16 and R17 are fixed registers. */ 14371 14372 for (size_t i = REG_0; i <= REG_17; i++) 14373 { 14374 fixed_regs[i] = 1; 14375 call_used_regs[i] = 1; 14376 } 14377 14378 /* Set R18 to R21 as callee saved registers 14379 - R18, R19, R20 and R21 are the callee saved registers in 14380 Tiny Core devices */ 14381 14382 for (size_t i = REG_18; i <= LAST_CALLEE_SAVED_REG; i++) 14383 { 14384 call_used_regs[i] = 0; 14385 } 14386 14387 /* Update register allocation order for Tiny Core devices */ 14388 14389 for (size_t i = 0; i < ARRAY_SIZE (tiny_reg_alloc_order); i++) 14390 { 14391 reg_alloc_order[i] = tiny_reg_alloc_order[i]; 14392 } 14393 14394 CLEAR_HARD_REG_SET (reg_class_contents[(int) NO_LD_REGS]); 14395 } 14396 } 14397 14398 /* Implement `TARGET_HARD_REGNO_SCRATCH_OK'. */ 14399 /* Returns true if SCRATCH are safe to be allocated as a scratch 14400 registers (for a define_peephole2) in the current function. */ 14401 14402 static bool 14403 avr_hard_regno_scratch_ok (unsigned int regno) 14404 { 14405 /* Interrupt functions can only use registers that have already been saved 14406 by the prologue, even if they would normally be call-clobbered. */ 14407 14408 if ((cfun->machine->is_interrupt || cfun->machine->is_signal) 14409 && !df_regs_ever_live_p (regno)) 14410 return false; 14411 14412 /* Don't allow hard registers that might be part of the frame pointer. 14413 Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM 14414 and don't care for a frame pointer that spans more than one register. */ 14415 14416 if ((!reload_completed || frame_pointer_needed) 14417 && (regno == REG_Y || regno == REG_Y + 1)) 14418 { 14419 return false; 14420 } 14421 14422 return true; 14423 } 14424 14425 14426 /* Worker function for `HARD_REGNO_RENAME_OK'. */ 14427 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */ 14428 14429 int 14430 avr_hard_regno_rename_ok (unsigned int old_reg, unsigned int new_reg) 14431 { 14432 /* Interrupt functions can only use registers that have already been 14433 saved by the prologue, even if they would normally be 14434 call-clobbered. */ 14435 14436 if ((cfun->machine->is_interrupt || cfun->machine->is_signal) 14437 && !df_regs_ever_live_p (new_reg)) 14438 return 0; 14439 14440 /* Don't allow hard registers that might be part of the frame pointer. 14441 Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM 14442 and don't care for a frame pointer that spans more than one register. */ 14443 14444 if ((!reload_completed || frame_pointer_needed) 14445 && (old_reg == REG_Y || old_reg == REG_Y + 1 14446 || new_reg == REG_Y || new_reg == REG_Y + 1)) 14447 { 14448 return 0; 14449 } 14450 14451 return 1; 14452 } 14453 14454 /* Output a branch that tests a single bit of a register (QI, HI, SI or DImode) 14455 or memory location in the I/O space (QImode only). 14456 14457 Operand 0: comparison operator (must be EQ or NE, compare bit to zero). 14458 Operand 1: register operand to test, or CONST_INT memory address. 14459 Operand 2: bit number. 14460 Operand 3: label to jump to if the test is true. */ 14461 14462 const char * 14463 avr_out_sbxx_branch (rtx_insn *insn, rtx operands[]) 14464 { 14465 enum rtx_code comp = GET_CODE (operands[0]); 14466 bool long_jump = get_attr_length (insn) >= 4; 14467 bool reverse = long_jump || jump_over_one_insn_p (insn, operands[3]); 14468 14469 // PR116953: jump_over_one_insn_p may call extract on the next insn, 14470 // clobbering recog_data.operand. Thus, restore recog_data. 14471 extract_constrain_insn_cached (insn); 14472 14473 if (comp == GE) 14474 comp = EQ; 14475 else if (comp == LT) 14476 comp = NE; 14477 14478 if (reverse) 14479 comp = reverse_condition (comp); 14480 14481 switch (GET_CODE (operands[1])) 14482 { 14483 default: 14484 gcc_unreachable(); 14485 14486 case CONST_INT: 14487 case CONST: 14488 case SYMBOL_REF: 14489 14490 if (low_io_address_operand (operands[1], QImode)) 14491 { 14492 if (comp == EQ) 14493 output_asm_insn ("sbis %i1,%2", operands); 14494 else 14495 output_asm_insn ("sbic %i1,%2", operands); 14496 } 14497 else 14498 { 14499 gcc_assert (io_address_operand (operands[1], QImode)); 14500 output_asm_insn ("in __tmp_reg__,%i1", operands); 14501 if (comp == EQ) 14502 output_asm_insn ("sbrs __tmp_reg__,%2", operands); 14503 else 14504 output_asm_insn ("sbrc __tmp_reg__,%2", operands); 14505 } 14506 14507 break; /* CONST_INT */ 14508 14509 case REG: 14510 14511 if (comp == EQ) 14512 output_asm_insn ("sbrs %T1%T2", operands); 14513 else 14514 output_asm_insn ("sbrc %T1%T2", operands); 14515 14516 break; /* REG */ 14517 } /* switch */ 14518 14519 if (long_jump) 14520 return ("rjmp .+4" CR_TAB 14521 "jmp %x3"); 14522 14523 if (!reverse) 14524 return "rjmp %x3"; 14525 14526 return ""; 14527 } 14528 14529 14530 /* Worker function for `TARGET_ASM_CONSTRUCTOR'. */ 14531 14532 static void 14533 avr_asm_out_ctor (rtx symbol, int priority) 14534 { 14535 fputs ("\t.global __do_global_ctors\n", asm_out_file); 14536 default_ctor_section_asm_out_constructor (symbol, priority); 14537 } 14538 14539 14540 /* Worker function for `TARGET_ASM_DESTRUCTOR'. */ 14541 14542 static void 14543 avr_asm_out_dtor (rtx symbol, int priority) 14544 { 14545 fputs ("\t.global __do_global_dtors\n", asm_out_file); 14546 default_dtor_section_asm_out_destructor (symbol, priority); 14547 } 14548 14549 14550 /* Implement `TARGET_RETURN_IN_MEMORY'. */ 14551 14552 static bool 14553 avr_return_in_memory (const_tree type, const_tree /*fntype*/) 14554 { 14555 HOST_WIDE_INT size = int_size_in_bytes (type); 14556 HOST_WIDE_INT ret_size_limit = AVR_TINY ? 4 : 8; 14557 14558 /* In avr, there are 8 return registers. But, for Tiny Core 14559 (ATtiny4/5/9/10/20/40) devices, only 4 registers are available. 14560 Return true if size is unknown or greater than the limit. */ 14561 14562 if (size == -1 || size > ret_size_limit) 14563 { 14564 return true; 14565 } 14566 else 14567 { 14568 return false; 14569 } 14570 } 14571 14572 14573 /* Implement `CASE_VALUES_THRESHOLD'. */ 14574 /* Supply the default for --param case-values-threshold=0 */ 14575 14576 static unsigned int 14577 avr_case_values_threshold (void) 14578 { 14579 /* The exact break-even point between a jump table and an if-else tree 14580 depends on several factors not available here like, e.g. if 8-bit 14581 comparisons can be used in the if-else tree or not, on the 14582 range of the case values, if the case value can be reused, on the 14583 register allocation, etc. '7' appears to be a good choice. */ 14584 14585 return 7; 14586 } 14587 14588 14589 /* Implement `TARGET_ADDR_SPACE_ADDRESS_MODE'. */ 14590 14591 static scalar_int_mode 14592 avr_addr_space_address_mode (addr_space_t as) 14593 { 14594 return avr_addrspace[as].pointer_size == 3 ? PSImode : HImode; 14595 } 14596 14597 14598 /* Implement `TARGET_ADDR_SPACE_POINTER_MODE'. */ 14599 14600 static scalar_int_mode 14601 avr_addr_space_pointer_mode (addr_space_t as) 14602 { 14603 return avr_addr_space_address_mode (as); 14604 } 14605 14606 14607 /* Helper for following function. */ 14608 14609 static bool 14610 avr_reg_ok_for_pgm_addr (rtx reg, bool strict) 14611 { 14612 gcc_assert (REG_P (reg)); 14613 14614 if (strict) 14615 { 14616 return REGNO (reg) == REG_Z; 14617 } 14618 14619 /* Avoid combine to propagate hard regs. */ 14620 14621 if (can_create_pseudo_p() 14622 && REGNO (reg) < REG_Z) 14623 { 14624 return false; 14625 } 14626 14627 return true; 14628 } 14629 14630 14631 /* Implement `TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P'. */ 14632 14633 static bool 14634 avr_addr_space_legitimate_address_p (machine_mode mode, rtx x, bool strict, 14635 addr_space_t as, code_helper = ERROR_MARK) 14636 { 14637 bool ok = false; 14638 14639 switch (as) 14640 { 14641 default: 14642 gcc_unreachable(); 14643 14644 case ADDR_SPACE_GENERIC: 14645 return avr_legitimate_address_p (mode, x, strict); 14646 14647 case ADDR_SPACE_FLASH: 14648 case ADDR_SPACE_FLASH1: 14649 case ADDR_SPACE_FLASH2: 14650 case ADDR_SPACE_FLASH3: 14651 case ADDR_SPACE_FLASH4: 14652 case ADDR_SPACE_FLASH5: 14653 14654 switch (GET_CODE (x)) 14655 { 14656 case REG: 14657 ok = avr_reg_ok_for_pgm_addr (x, strict); 14658 break; 14659 14660 case POST_INC: 14661 ok = avr_reg_ok_for_pgm_addr (XEXP (x, 0), strict); 14662 break; 14663 14664 default: 14665 break; 14666 } 14667 14668 break; /* FLASH */ 14669 14670 case ADDR_SPACE_MEMX: 14671 if (REG_P (x)) 14672 ok = (!strict 14673 && can_create_pseudo_p()); 14674 14675 if (LO_SUM == GET_CODE (x)) 14676 { 14677 rtx hi = XEXP (x, 0); 14678 rtx lo = XEXP (x, 1); 14679 14680 ok = (REG_P (hi) 14681 && (!strict || REGNO (hi) < FIRST_PSEUDO_REGISTER) 14682 && REG_P (lo) 14683 && REGNO (lo) == REG_Z); 14684 } 14685 14686 break; /* MEMX */ 14687 } 14688 14689 if (avr_log.legitimate_address_p) 14690 { 14691 avr_edump ("\n%?: ret=%b, mode=%m strict=%d " 14692 "reload_completed=%d reload_in_progress=%d %s:", 14693 ok, mode, strict, reload_completed, reload_in_progress, 14694 reg_renumber ? "(reg_renumber)" : ""); 14695 14696 if (GET_CODE (x) == PLUS 14697 && REG_P (XEXP (x, 0)) 14698 && CONST_INT_P (XEXP (x, 1)) 14699 && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode)) 14700 && reg_renumber) 14701 { 14702 avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)), 14703 true_regnum (XEXP (x, 0))); 14704 } 14705 14706 avr_edump ("\n%r\n", x); 14707 } 14708 14709 return ok; 14710 } 14711 14712 14713 /* Implement `TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS'. */ 14714 14715 static rtx 14716 avr_addr_space_legitimize_address (rtx x, rtx old_x, 14717 machine_mode mode, addr_space_t as) 14718 { 14719 if (ADDR_SPACE_GENERIC_P (as)) 14720 return avr_legitimize_address (x, old_x, mode); 14721 14722 if (avr_log.legitimize_address) 14723 { 14724 avr_edump ("\n%?: mode=%m\n %r\n", mode, old_x); 14725 } 14726 14727 return old_x; 14728 } 14729 14730 14731 /* Implement `TARGET_ADDR_SPACE_CONVERT'. */ 14732 14733 static rtx 14734 avr_addr_space_convert (rtx src, tree type_from, tree type_to) 14735 { 14736 addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (type_from)); 14737 addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type_to)); 14738 14739 if (avr_log.progmem) 14740 avr_edump ("\n%!: op = %r\nfrom = %t\nto = %t\n", 14741 src, type_from, type_to); 14742 14743 /* Up-casting from 16-bit to 24-bit pointer. */ 14744 14745 if (as_from != ADDR_SPACE_MEMX 14746 && as_to == ADDR_SPACE_MEMX) 14747 { 14748 rtx sym = src; 14749 rtx reg = gen_reg_rtx (PSImode); 14750 14751 while (CONST == GET_CODE (sym) || PLUS == GET_CODE (sym)) 14752 sym = XEXP (sym, 0); 14753 14754 /* Look at symbol flags: avr_encode_section_info set the flags 14755 also if attribute progmem was seen so that we get the right 14756 promotion for, e.g. PSTR-like strings that reside in generic space 14757 but are located in flash. In that case we patch the incoming 14758 address space. */ 14759 14760 if (SYMBOL_REF_P (sym) 14761 && ADDR_SPACE_FLASH == AVR_SYMBOL_GET_ADDR_SPACE (sym)) 14762 { 14763 as_from = ADDR_SPACE_FLASH; 14764 } 14765 14766 /* Linearize memory: RAM has bit 23 set. */ 14767 14768 int msb = ADDR_SPACE_GENERIC_P (as_from) 14769 ? 0x80 14770 : avr_addrspace[as_from].segment; 14771 14772 src = force_reg (Pmode, src); 14773 14774 emit_insn (msb == 0 14775 ? gen_zero_extendhipsi2 (reg, src) 14776 : gen_n_extendhipsi2 (reg, gen_int_mode (msb, QImode), src)); 14777 14778 return reg; 14779 } 14780 14781 /* Down-casting from 24-bit to 16-bit throws away the high byte. */ 14782 14783 if (as_from == ADDR_SPACE_MEMX 14784 && as_to != ADDR_SPACE_MEMX) 14785 { 14786 rtx new_src = gen_reg_rtx (Pmode); 14787 14788 src = force_reg (PSImode, src); 14789 14790 emit_move_insn (new_src, 14791 simplify_gen_subreg (Pmode, src, PSImode, 0)); 14792 return new_src; 14793 } 14794 14795 return src; 14796 } 14797 14798 14799 /* Implement `TARGET_ADDR_SPACE_SUBSET_P'. */ 14800 14801 static bool 14802 avr_addr_space_subset_p (addr_space_t /*subset*/, addr_space_t /*superset*/) 14803 { 14804 /* Allow any kind of pointer mess. */ 14805 14806 return true; 14807 } 14808 14809 14810 /* Implement `TARGET_CONVERT_TO_TYPE'. */ 14811 14812 static tree 14813 avr_convert_to_type (tree type, tree expr) 14814 { 14815 /* Print a diagnose for pointer conversion that changes the address 14816 space of the pointer target to a non-enclosing address space, 14817 provided -Waddr-space-convert is on. 14818 14819 FIXME: Filter out cases where the target object is known to 14820 be located in the right memory, like in 14821 14822 (const __flash*) PSTR ("text") 14823 14824 Also try to distinguish between explicit casts requested by 14825 the user and implicit casts like 14826 14827 void f (const __flash char*); 14828 14829 void g (const char *p) 14830 { 14831 f ((const __flash*) p); 14832 } 14833 14834 under the assumption that an explicit casts means that the user 14835 knows what he is doing, e.g. interface with PSTR or old style 14836 code with progmem and pgm_read_xxx. 14837 */ 14838 14839 if (avr_warn_addr_space_convert 14840 && expr != error_mark_node 14841 && POINTER_TYPE_P (type) 14842 && POINTER_TYPE_P (TREE_TYPE (expr))) 14843 { 14844 addr_space_t as_old = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr))); 14845 addr_space_t as_new = TYPE_ADDR_SPACE (TREE_TYPE (type)); 14846 14847 if (avr_log.progmem) 14848 avr_edump ("%?: type = %t\nexpr = %t\n\n", type, expr); 14849 14850 if (as_new != ADDR_SPACE_MEMX 14851 && as_new != as_old) 14852 { 14853 location_t loc = EXPR_LOCATION (expr); 14854 const char *name_old = avr_addrspace[as_old].name; 14855 const char *name_new = avr_addrspace[as_new].name; 14856 14857 warning (OPT_Waddr_space_convert, 14858 "conversion from address space %qs to address space %qs", 14859 ADDR_SPACE_GENERIC_P (as_old) ? "generic" : name_old, 14860 ADDR_SPACE_GENERIC_P (as_new) ? "generic" : name_new); 14861 14862 return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, expr); 14863 } 14864 } 14865 14866 return NULL_TREE; 14867 } 14868 14869 14870 /* Implement `TARGET_LEGITIMATE_COMBINED_INSN'. */ 14871 /* PR78883: Filter out paradoxical SUBREGs of MEM which are not handled 14872 properly by following passes. As INSN_SCHEDULING is off and hence 14873 general_operand accepts such expressions, ditch them now. */ 14874 14875 static bool 14876 avr_legitimate_combined_insn (rtx_insn *insn) 14877 { 14878 subrtx_iterator::array_type array; 14879 14880 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST) 14881 { 14882 const_rtx op = *iter; 14883 14884 if (SUBREG_P (op) 14885 && MEM_P (SUBREG_REG (op)) 14886 && (GET_MODE_SIZE (GET_MODE (op)) 14887 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))))) 14888 { 14889 return false; 14890 } 14891 } 14892 14893 return true; 14894 } 14895 14896 14897 /* PR63633: The middle-end might come up with hard regs as input operands. 14898 14899 RMASK is a bit mask representing a subset of hard registers R0...R31: 14900 Rn is an element of that set iff bit n of RMASK is set. 14901 OPMASK describes a subset of OP[]: If bit n of OPMASK is 1 then 14902 OP[n] has to be fixed; otherwise OP[n] is left alone. 14903 14904 For each element of OPMASK which is a hard register overlapping RMASK, 14905 replace OP[n] with a newly created pseudo register 14906 14907 HREG == 0: Also emit a move insn that copies the contents of that 14908 hard register into the new pseudo. 14909 14910 HREG != 0: Also set HREG[n] to the hard register. */ 14911 14912 static void 14913 avr_fix_operands (rtx *op, rtx *hreg, unsigned opmask, unsigned rmask) 14914 { 14915 for (; opmask; opmask >>= 1, op++) 14916 { 14917 rtx reg = *op; 14918 14919 if (hreg) 14920 *hreg = NULL_RTX; 14921 14922 if ((opmask & 1) 14923 && REG_P (reg) 14924 && REGNO (reg) < FIRST_PSEUDO_REGISTER 14925 // This hard-reg overlaps other prohibited hard regs? 14926 && (rmask & regmask (GET_MODE (reg), REGNO (reg)))) 14927 { 14928 *op = gen_reg_rtx (GET_MODE (reg)); 14929 if (hreg == NULL) 14930 emit_move_insn (*op, reg); 14931 else 14932 *hreg = reg; 14933 } 14934 14935 if (hreg) 14936 hreg++; 14937 } 14938 } 14939 14940 14941 void 14942 avr_fix_inputs (rtx *op, unsigned opmask, unsigned rmask) 14943 { 14944 avr_fix_operands (op, NULL, opmask, rmask); 14945 } 14946 14947 14948 /* Helper for the function below: If bit n of MASK is set and 14949 HREG[n] != NULL, then emit a move insn to copy OP[n] to HREG[n]. 14950 Otherwise do nothing for that n. Return TRUE. */ 14951 14952 static bool 14953 avr_move_fixed_operands (rtx *op, rtx *hreg, unsigned mask) 14954 { 14955 for (; mask; mask >>= 1, op++, hreg++) 14956 if ((mask & 1) 14957 && *hreg) 14958 emit_move_insn (*hreg, *op); 14959 14960 return true; 14961 } 14962 14963 14964 /* PR63633: The middle-end might come up with hard regs as output operands. 14965 14966 GEN is a sequence generating function like gen_mulsi3 with 3 operands OP[]. 14967 RMASK is a bit mask representing a subset of hard registers R0...R31: 14968 Rn is an element of that set iff bit n of RMASK is set. 14969 OPMASK describes a subset of OP[]: If bit n of OPMASK is 1 then 14970 OP[n] has to be fixed; otherwise OP[n] is left alone. 14971 14972 Emit the insn sequence as generated by GEN() with all elements of OPMASK 14973 which are hard registers overlapping RMASK replaced by newly created 14974 pseudo registers. After the sequence has been emitted, emit insns that 14975 move the contents of respective pseudos to their hard regs. */ 14976 14977 bool 14978 avr_emit3_fix_outputs (rtx (*gen)(rtx,rtx,rtx), rtx *op, 14979 unsigned opmask, unsigned rmask) 14980 { 14981 const int n = 3; 14982 rtx hreg[n]; 14983 14984 /* It is letigimate for GEN to call this function, and in order not to 14985 get self-recursive we use the following static kludge. This is the 14986 only way not to duplicate all expanders and to avoid ugly and 14987 hard-to-maintain C-code instead of the much more appreciated RTL 14988 representation as supplied by define_expand. */ 14989 static bool lock = false; 14990 14991 gcc_assert (opmask < (1u << n)); 14992 14993 if (lock) 14994 return false; 14995 14996 avr_fix_operands (op, hreg, opmask, rmask); 14997 14998 lock = true; 14999 emit_insn (gen (op[0], op[1], op[2])); 15000 lock = false; 15001 15002 return avr_move_fixed_operands (op, hreg, opmask); 15003 } 15004 15005 15006 /* Worker function for cpymemhi expander. 15007 XOP[0] Destination as MEM:BLK 15008 XOP[1] Source " " 15009 XOP[2] # Bytes to copy 15010 15011 Return TRUE if the expansion is accomplished. 15012 Return FALSE if the operand compination is not supported. */ 15013 15014 bool 15015 avr_emit_cpymemhi (rtx *xop) 15016 { 15017 machine_mode loop_mode; 15018 addr_space_t as = MEM_ADDR_SPACE (xop[1]); 15019 rtx loop_reg, addr1, insn; 15020 rtx a_hi8 = NULL_RTX; 15021 15022 if (avr_mem_flash_p (xop[0])) 15023 return false; 15024 15025 if (!CONST_INT_P (xop[2])) 15026 return false; 15027 15028 HOST_WIDE_INT count = INTVAL (xop[2]); 15029 if (count <= 0) 15030 return false; 15031 15032 rtx a_src = XEXP (xop[1], 0); 15033 rtx a_dest = XEXP (xop[0], 0); 15034 15035 if (PSImode == GET_MODE (a_src)) 15036 { 15037 gcc_assert (as == ADDR_SPACE_MEMX); 15038 15039 loop_mode = (count < 0x100) ? QImode : HImode; 15040 loop_reg = gen_rtx_REG (loop_mode, 24); 15041 emit_move_insn (loop_reg, gen_int_mode (count, loop_mode)); 15042 15043 addr1 = simplify_gen_subreg (HImode, a_src, PSImode, 0); 15044 a_hi8 = simplify_gen_subreg (QImode, a_src, PSImode, 2); 15045 } 15046 else 15047 { 15048 int segment = avr_addrspace[as].segment; 15049 15050 if (segment 15051 && avr_n_flash > 1) 15052 { 15053 a_hi8 = GEN_INT (segment); 15054 emit_move_insn (rampz_rtx, a_hi8 = copy_to_mode_reg (QImode, a_hi8)); 15055 } 15056 else if (!ADDR_SPACE_GENERIC_P (as)) 15057 { 15058 as = ADDR_SPACE_FLASH; 15059 } 15060 15061 addr1 = a_src; 15062 15063 loop_mode = (count <= 0x100) ? QImode : HImode; 15064 loop_reg = copy_to_mode_reg (loop_mode, gen_int_mode (count, loop_mode)); 15065 } 15066 15067 rtx xas = GEN_INT (as); 15068 15069 /* FIXME: Register allocator might come up with spill fails if it is left 15070 on its own. Thus, we allocate the pointer registers by hand: 15071 Z = source address 15072 X = destination address */ 15073 15074 emit_move_insn (lpm_addr_reg_rtx, addr1); 15075 emit_move_insn (gen_rtx_REG (HImode, REG_X), a_dest); 15076 15077 /* FIXME: Register allocator does a bad job and might spill address 15078 register(s) inside the loop leading to additional move instruction 15079 to/from stack which could clobber tmp_reg. Thus, do *not* emit 15080 load and store as separate insns. Instead, we perform the copy 15081 by means of one monolithic insn. */ 15082 15083 gcc_assert (TMP_REGNO == LPM_REGNO); 15084 15085 if (as != ADDR_SPACE_MEMX) 15086 { 15087 /* Load instruction ([E]LPM or LD) is known at compile time: 15088 Do the copy-loop inline. */ 15089 15090 rtx (*fun) (rtx, rtx, rtx) 15091 = QImode == loop_mode ? gen_cpymem_qi : gen_cpymem_hi; 15092 15093 insn = fun (xas, loop_reg, loop_reg); 15094 } 15095 else 15096 { 15097 rtx (*fun) (rtx, rtx) 15098 = QImode == loop_mode ? gen_cpymemx_qi : gen_cpymemx_hi; 15099 15100 emit_move_insn (gen_rtx_REG (QImode, 23), a_hi8); 15101 15102 insn = fun (xas, GEN_INT (avr_addr.rampz)); 15103 } 15104 15105 set_mem_addr_space (SET_SRC (XVECEXP (insn, 0, 0)), as); 15106 emit_insn (insn); 15107 15108 return true; 15109 } 15110 15111 15112 /* Print assembler for cpymem_qi, cpymem_hi insns... 15113 $0 : Address Space 15114 $1, $2 : Loop register 15115 Z : Source address 15116 X : Destination address 15117 */ 15118 15119 const char * 15120 avr_out_cpymem (rtx_insn * /*insn*/, rtx *op, int *plen) 15121 { 15122 addr_space_t as = (addr_space_t) INTVAL (op[0]); 15123 machine_mode loop_mode = GET_MODE (op[1]); 15124 bool sbiw_p = avr_adiw_reg_p (op[1]); 15125 rtx xop[3] = { op[0], op[1], tmp_reg_rtx }; 15126 15127 if (plen) 15128 *plen = 0; 15129 15130 /* Loop label */ 15131 15132 avr_asm_len ("0:", xop, plen, 0); 15133 15134 /* Load with post-increment */ 15135 15136 switch (as) 15137 { 15138 default: 15139 gcc_unreachable(); 15140 15141 case ADDR_SPACE_GENERIC: 15142 15143 avr_asm_len ("ld %2,Z+", xop, plen, 1); 15144 break; 15145 15146 case ADDR_SPACE_FLASH: 15147 15148 if (AVR_HAVE_LPMX) 15149 avr_asm_len ("lpm %2,Z+", xop, plen, 1); 15150 else 15151 avr_asm_len ("lpm" CR_TAB 15152 "adiw r30,1", xop, plen, 2); 15153 break; 15154 15155 case ADDR_SPACE_FLASH1: 15156 case ADDR_SPACE_FLASH2: 15157 case ADDR_SPACE_FLASH3: 15158 case ADDR_SPACE_FLASH4: 15159 case ADDR_SPACE_FLASH5: 15160 15161 if (AVR_HAVE_ELPMX) 15162 avr_asm_len ("elpm %2,Z+", xop, plen, 1); 15163 else 15164 avr_asm_len ("elpm" CR_TAB 15165 "adiw r30,1", xop, plen, 2); 15166 break; 15167 } 15168 15169 /* Store with post-increment */ 15170 15171 avr_asm_len ("st X+,%2", xop, plen, 1); 15172 15173 /* Decrement loop-counter and set Z-flag */ 15174 15175 if (QImode == loop_mode) 15176 { 15177 avr_asm_len ("dec %1", xop, plen, 1); 15178 } 15179 else if (sbiw_p) 15180 { 15181 avr_asm_len ("sbiw %1,1", xop, plen, 1); 15182 } 15183 else 15184 { 15185 avr_asm_len ("subi %A1,1" CR_TAB 15186 "sbci %B1,0", xop, plen, 2); 15187 } 15188 15189 /* Loop until zero */ 15190 15191 return avr_asm_len ("brne 0b", xop, plen, 1); 15192 } 15193 15194 15195 15196 /* Helper for __builtin_avr_delay_cycles */ 15198 15199 static rtx 15200 avr_mem_clobber (void) 15201 { 15202 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 15203 MEM_VOLATILE_P (mem) = 1; 15204 return mem; 15205 } 15206 15207 static void 15208 avr_expand_delay_cycles (rtx operands0) 15209 { 15210 unsigned HOST_WIDE_INT cycles = UINTVAL (operands0) & GET_MODE_MASK (SImode); 15211 unsigned HOST_WIDE_INT cycles_used; 15212 unsigned HOST_WIDE_INT loop_count; 15213 15214 if (IN_RANGE (cycles, 83886082, 0xFFFFFFFF)) 15215 { 15216 loop_count = ((cycles - 9) / 6) + 1; 15217 cycles_used = ((loop_count - 1) * 6) + 9; 15218 emit_insn (gen_delay_cycles_4 (gen_int_mode (loop_count, SImode), 15219 avr_mem_clobber())); 15220 cycles -= cycles_used; 15221 } 15222 15223 if (IN_RANGE (cycles, 262145, 83886081)) 15224 { 15225 loop_count = ((cycles - 7) / 5) + 1; 15226 if (loop_count > 0xFFFFFF) 15227 loop_count = 0xFFFFFF; 15228 cycles_used = ((loop_count - 1) * 5) + 7; 15229 emit_insn (gen_delay_cycles_3 (gen_int_mode (loop_count, SImode), 15230 avr_mem_clobber())); 15231 cycles -= cycles_used; 15232 } 15233 15234 if (IN_RANGE (cycles, 768, 262144)) 15235 { 15236 loop_count = ((cycles - 5) / 4) + 1; 15237 if (loop_count > 0xFFFF) 15238 loop_count = 0xFFFF; 15239 cycles_used = ((loop_count - 1) * 4) + 5; 15240 emit_insn (gen_delay_cycles_2 (gen_int_mode (loop_count, HImode), 15241 avr_mem_clobber())); 15242 cycles -= cycles_used; 15243 } 15244 15245 if (IN_RANGE (cycles, 6, 767)) 15246 { 15247 loop_count = cycles / 3; 15248 if (loop_count > 255) 15249 loop_count = 255; 15250 cycles_used = loop_count * 3; 15251 emit_insn (gen_delay_cycles_1 (gen_int_mode (loop_count, QImode), 15252 avr_mem_clobber())); 15253 cycles -= cycles_used; 15254 } 15255 15256 while (cycles >= 2) 15257 { 15258 emit_insn (gen_nopv (GEN_INT (2))); 15259 cycles -= 2; 15260 } 15261 15262 if (cycles == 1) 15263 { 15264 emit_insn (gen_nopv (GEN_INT (1))); 15265 cycles--; 15266 } 15267 } 15268 15269 15270 static void 15271 avr_expand_nops (rtx operands0) 15272 { 15273 unsigned HOST_WIDE_INT n_nops = UINTVAL (operands0) & GET_MODE_MASK (HImode); 15274 15275 while (n_nops--) 15276 { 15277 emit_insn (gen_nopv (const1_rtx)); 15278 } 15279 } 15280 15281 15282 /* Compute the image of x under f, i.e. perform x --> f(x) */ 15283 15284 static int 15285 avr_map (unsigned int f, int x) 15286 { 15287 return x < 8 ? (f >> (4 * x)) & 0xf : 0; 15288 } 15289 15290 15291 /* Return some metrics of map A. */ 15292 15293 enum 15294 { 15295 /* Number of fixed points in { 0 ... 7 } */ 15296 MAP_FIXED_0_7, 15297 15298 /* Size of preimage of non-fixed points in { 0 ... 7 } */ 15299 MAP_NONFIXED_0_7, 15300 15301 /* Mask representing the fixed points in { 0 ... 7 } */ 15302 MAP_MASK_FIXED_0_7, 15303 15304 /* Size of the preimage of { 0 ... 7 } */ 15305 MAP_PREIMAGE_0_7, 15306 15307 /* Mask that represents the preimage of { f } */ 15308 MAP_MASK_PREIMAGE_F 15309 }; 15310 15311 static unsigned 15312 avr_map_metric (unsigned int a, int mode) 15313 { 15314 unsigned metric = 0; 15315 15316 for (unsigned i = 0; i < 8; i++) 15317 { 15318 unsigned ai = avr_map (a, i); 15319 15320 if (mode == MAP_FIXED_0_7) 15321 metric += ai == i; 15322 else if (mode == MAP_NONFIXED_0_7) 15323 metric += ai < 8 && ai != i; 15324 else if (mode == MAP_MASK_FIXED_0_7) 15325 metric |= ((unsigned) (ai == i)) << i; 15326 else if (mode == MAP_PREIMAGE_0_7) 15327 metric += ai < 8; 15328 else if (mode == MAP_MASK_PREIMAGE_F) 15329 metric |= ((unsigned) (ai == 0xf)) << i; 15330 else 15331 gcc_unreachable(); 15332 } 15333 15334 return metric; 15335 } 15336 15337 15338 /* Return true if IVAL has a 0xf in its hexadecimal representation 15339 and false, otherwise. Only nibbles 0..7 are taken into account. 15340 Used as constraint helper for C0f and Cxf. */ 15341 15342 bool 15343 avr_has_nibble_0xf (rtx ival) 15344 { 15345 unsigned int map = UINTVAL (ival) & GET_MODE_MASK (SImode); 15346 return avr_map_metric (map, MAP_MASK_PREIMAGE_F) != 0; 15347 } 15348 15349 15350 /* We have a set of bits that are mapped by a function F. 15351 Try to decompose F by means of a second function G so that 15352 15353 F = F o G^-1 o G 15354 15355 and 15356 15357 cost (F o G^-1) + cost (G) < cost (F) 15358 15359 Example: Suppose builtin insert_bits supplies us with the map 15360 F = 0x3210ffff. Instead of doing 4 bit insertions to get the high 15361 nibble of the result, we can just as well rotate the bits before inserting 15362 them and use the map 0x7654ffff which is cheaper than the original map. 15363 For this example G = G^-1 = 0x32107654 and F o G^-1 = 0x7654ffff. */ 15364 15365 typedef struct 15366 { 15367 /* tree code of binary function G */ 15368 enum tree_code code; 15369 15370 /* The constant second argument of G */ 15371 int arg; 15372 15373 /* G^-1, the inverse of G (*, arg) */ 15374 unsigned ginv; 15375 15376 /* The cost of applying G (*, arg) */ 15377 int cost; 15378 15379 /* The composition F o G^-1 (*, arg) for some function F */ 15380 unsigned int map; 15381 15382 /* For debug purpose only */ 15383 const char *str; 15384 } avr_map_op_t; 15385 15386 static const avr_map_op_t avr_map_op[] = 15387 { 15388 { LROTATE_EXPR, 0, 0x76543210, 0, 0, "id" }, 15389 { LROTATE_EXPR, 1, 0x07654321, 2, 0, "<<<" }, 15390 { LROTATE_EXPR, 2, 0x10765432, 4, 0, "<<<" }, 15391 { LROTATE_EXPR, 3, 0x21076543, 4, 0, "<<<" }, 15392 { LROTATE_EXPR, 4, 0x32107654, 1, 0, "<<<" }, 15393 { LROTATE_EXPR, 5, 0x43210765, 3, 0, "<<<" }, 15394 { LROTATE_EXPR, 6, 0x54321076, 5, 0, "<<<" }, 15395 { LROTATE_EXPR, 7, 0x65432107, 3, 0, "<<<" }, 15396 { RSHIFT_EXPR, 1, 0x6543210c, 1, 0, ">>" }, 15397 { RSHIFT_EXPR, 1, 0x7543210c, 1, 0, ">>" }, 15398 { RSHIFT_EXPR, 2, 0x543210cc, 2, 0, ">>" }, 15399 { RSHIFT_EXPR, 2, 0x643210cc, 2, 0, ">>" }, 15400 { RSHIFT_EXPR, 2, 0x743210cc, 2, 0, ">>" }, 15401 { LSHIFT_EXPR, 1, 0xc7654321, 1, 0, "<<" }, 15402 { LSHIFT_EXPR, 2, 0xcc765432, 2, 0, "<<" } 15403 }; 15404 15405 15406 /* Try to decompose F as F = (F o G^-1) o G as described above. 15407 The result is a struct representing F o G^-1 and G. 15408 If result.cost < 0 then such a decomposition does not exist. */ 15409 15410 static avr_map_op_t 15411 avr_map_decompose (unsigned int f, const avr_map_op_t *g, bool val_const_p) 15412 { 15413 bool val_used_p = avr_map_metric (f, MAP_MASK_PREIMAGE_F) != 0; 15414 avr_map_op_t f_ginv = *g; 15415 unsigned int ginv = g->ginv; 15416 15417 f_ginv.cost = -1; 15418 15419 /* Step 1: Computing F o G^-1 */ 15420 15421 for (int i = 7; i >= 0; i--) 15422 { 15423 int x = avr_map (f, i); 15424 15425 if (x <= 7) 15426 { 15427 x = avr_map (ginv, x); 15428 15429 /* The bit is no element of the image of G: no avail (cost = -1) */ 15430 15431 if (x > 7) 15432 return f_ginv; 15433 } 15434 15435 f_ginv.map = (f_ginv.map << 4) + x; 15436 } 15437 15438 /* Step 2: Compute the cost of the operations. 15439 The overall cost of doing an operation prior to the insertion is 15440 the cost of the insertion plus the cost of the operation. */ 15441 15442 /* Step 2a: Compute cost of F o G^-1 */ 15443 15444 if (avr_map_metric (f_ginv.map, MAP_NONFIXED_0_7) == 0) 15445 /* The mapping consists only of fixed points and can be folded 15446 to AND/OR logic in the remainder. Reasonable cost is 3. */ 15447 f_ginv.cost = 2 + (val_used_p && !val_const_p); 15448 else 15449 { 15450 rtx xop[4]; 15451 15452 /* Get the cost of the insn by calling the output worker with some 15453 fake values. Mimic effect of reloading xop[3]: Unused operands 15454 are mapped to 0 and used operands are reloaded to xop[0]. */ 15455 15456 xop[0] = all_regs_rtx[REG_24]; 15457 xop[1] = gen_int_mode (f_ginv.map, SImode); 15458 xop[2] = all_regs_rtx[REG_25]; 15459 xop[3] = val_used_p ? xop[0] : const0_rtx; 15460 15461 avr_out_insert_bits (xop, &f_ginv.cost); 15462 15463 f_ginv.cost += val_const_p && val_used_p ? 1 : 0; 15464 } 15465 15466 /* Step 2b: Add cost of G */ 15467 15468 f_ginv.cost += g->cost; 15469 15470 if (avr_log.builtin) 15471 avr_edump (" %s%d=%d", g->str, g->arg, f_ginv.cost); 15472 15473 return f_ginv; 15474 } 15475 15476 15477 /* Insert bits from XOP[1] into XOP[0] according to MAP. 15478 XOP[0] and XOP[1] don't overlap. 15479 If FIXP_P = true: Move all bits according to MAP using BLD/BST sequences. 15480 If FIXP_P = false: Just move the bit if its position in the destination 15481 is different to its source position. */ 15482 15483 static void 15484 avr_move_bits (rtx *xop, unsigned int map, bool fixp_p, int *plen) 15485 { 15486 /* T-flag contains this bit of the source, i.e. of XOP[1] */ 15487 int t_bit_src = -1; 15488 15489 /* We order the operations according to the requested source bit b. */ 15490 15491 for (int b = 0; b < 8; b++) 15492 for (int bit_dest = 0; bit_dest < 8; bit_dest++) 15493 { 15494 int bit_src = avr_map (map, bit_dest); 15495 15496 if (b != bit_src 15497 || bit_src >= 8 15498 /* Same position: No need to copy as requested by FIXP_P. */ 15499 || (bit_dest == bit_src && !fixp_p)) 15500 continue; 15501 15502 if (t_bit_src != bit_src) 15503 { 15504 /* Source bit is not yet in T: Store it to T. */ 15505 15506 t_bit_src = bit_src; 15507 15508 xop[3] = GEN_INT (bit_src); 15509 avr_asm_len ("bst %T1%T3", xop, plen, 1); 15510 } 15511 15512 /* Load destination bit with T. */ 15513 15514 xop[3] = GEN_INT (bit_dest); 15515 avr_asm_len ("bld %T0%T3", xop, plen, 1); 15516 } 15517 } 15518 15519 15520 /* PLEN == 0: Print assembler code for `insert_bits'. 15521 PLEN != 0: Compute code length in bytes. 15522 15523 OP[0]: Result 15524 OP[1]: The mapping composed of nibbles. If nibble no. N is 15525 0: Bit N of result is copied from bit OP[2].0 15526 ... ... 15527 7: Bit N of result is copied from bit OP[2].7 15528 0xf: Bit N of result is copied from bit OP[3].N 15529 OP[2]: Bits to be inserted 15530 OP[3]: Target value */ 15531 15532 const char * 15533 avr_out_insert_bits (rtx *op, int *plen) 15534 { 15535 unsigned int map = UINTVAL (op[1]) & GET_MODE_MASK (SImode); 15536 bool fixp_p = true; 15537 rtx xop[4]; 15538 15539 xop[0] = op[0]; 15540 xop[1] = op[2]; 15541 xop[2] = op[3]; 15542 15543 gcc_assert (REG_P (xop[2]) || CONST_INT_P (xop[2])); 15544 15545 if (plen) 15546 *plen = 0; 15547 else if (flag_print_asm_name) 15548 fprintf (asm_out_file, ASM_COMMENT_START "map = 0x%08x\n", map); 15549 15550 /* If MAP has fixed points it might be better to initialize the result 15551 with the bits to be inserted instead of moving all bits by hand. */ 15552 15553 unsigned mask_fixed = avr_map_metric (map, MAP_MASK_FIXED_0_7); 15554 15555 if (REGNO (xop[0]) == REGNO (xop[1])) 15556 { 15557 /* Avoid early-clobber conflicts */ 15558 15559 avr_asm_len ("mov __tmp_reg__,%1", xop, plen, 1); 15560 xop[1] = tmp_reg_rtx; 15561 fixp_p = false; 15562 } 15563 15564 if (avr_map_metric (map, MAP_MASK_PREIMAGE_F)) 15565 { 15566 /* XOP[2] is used and reloaded to XOP[0] already */ 15567 15568 int n_fix = 0, n_nofix = 0; 15569 15570 gcc_assert (REG_P (xop[2])); 15571 15572 /* Get the code size of the bit insertions; once with all bits 15573 moved and once with fixed points omitted. */ 15574 15575 avr_move_bits (xop, map, true, &n_fix); 15576 avr_move_bits (xop, map, false, &n_nofix); 15577 15578 if (fixp_p && n_fix - n_nofix > 3) 15579 { 15580 xop[3] = gen_int_mode (~mask_fixed, QImode); 15581 15582 avr_asm_len ("eor %0,%1" CR_TAB 15583 "andi %0,%3" CR_TAB 15584 "eor %0,%1", xop, plen, 3); 15585 fixp_p = false; 15586 } 15587 } 15588 else 15589 { 15590 /* XOP[2] is unused */ 15591 15592 if (fixp_p && mask_fixed) 15593 { 15594 avr_asm_len ("mov %0,%1", xop, plen, 1); 15595 fixp_p = false; 15596 } 15597 } 15598 15599 /* Move/insert remaining bits. */ 15600 15601 avr_move_bits (xop, map, fixp_p, plen); 15602 15603 return ""; 15604 } 15605 15606 15607 /* IDs for all the AVR builtins. */ 15608 15609 enum avr_builtin_id 15610 { 15611 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME) \ 15612 AVR_BUILTIN_ ## NAME, 15613 #include "builtins.def" 15614 #undef DEF_BUILTIN 15615 15616 AVR_BUILTIN_COUNT 15617 }; 15618 15619 struct GTY(()) avr_builtin_description 15620 { 15621 enum insn_code icode; 15622 int n_args; 15623 tree fndecl; 15624 }; 15625 15626 15627 /* Notice that avr_bdesc[] and avr_builtin_id are initialized in such a way 15628 that a built-in's ID can be used to access the built-in by means of 15629 avr_bdesc[ID] */ 15630 15631 static GTY(()) struct avr_builtin_description 15632 avr_bdesc[AVR_BUILTIN_COUNT] = 15633 { 15634 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, LIBNAME) \ 15635 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE }, 15636 #include "builtins.def" 15637 #undef DEF_BUILTIN 15638 }; 15639 15640 15641 /* Implement `TARGET_BUILTIN_DECL'. */ 15642 15643 static tree 15644 avr_builtin_decl (unsigned id, bool /*initialize_p*/) 15645 { 15646 if (id < AVR_BUILTIN_COUNT) 15647 return avr_bdesc[id].fndecl; 15648 15649 return error_mark_node; 15650 } 15651 15652 15653 static void 15654 avr_init_builtin_int24 (void) 15655 { 15656 for (int i = 0; i < NUM_INT_N_ENTS; ++i) 15657 if (int_n_data[i].bitsize == 24) 15658 { 15659 tree uint24_type = int_n_trees[i].unsigned_type; 15660 lang_hooks.types.register_builtin_type (uint24_type, "__uint24"); 15661 break; 15662 } 15663 } 15664 15665 15666 /* Implement `TARGET_INIT_BUILTINS' */ 15667 /* Set up all builtin functions for this target. */ 15668 15669 static void 15670 avr_init_builtins (void) 15671 { 15672 tree void_ftype_void 15673 = build_function_type_list (void_type_node, NULL_TREE); 15674 tree uintQI_ftype_uintQI 15675 = build_function_type_list (unsigned_intQI_type_node, 15676 unsigned_intQI_type_node, 15677 NULL_TREE); 15678 tree uintHI_ftype_uintQI_uintQI 15679 = build_function_type_list (unsigned_intHI_type_node, 15680 unsigned_intQI_type_node, 15681 unsigned_intQI_type_node, 15682 NULL_TREE); 15683 tree intHI_ftype_intQI_intQI 15684 = build_function_type_list (intHI_type_node, 15685 intQI_type_node, 15686 intQI_type_node, 15687 NULL_TREE); 15688 tree intHI_ftype_intQI_uintQI 15689 = build_function_type_list (intHI_type_node, 15690 intQI_type_node, 15691 unsigned_intQI_type_node, 15692 NULL_TREE); 15693 tree void_ftype_uintSI 15694 = build_function_type_list (void_type_node, 15695 unsigned_intSI_type_node, 15696 NULL_TREE); 15697 15698 tree uintQI_ftype_uintSI_uintQI_uintQI 15699 = build_function_type_list (unsigned_intQI_type_node, 15700 unsigned_intSI_type_node, 15701 unsigned_intQI_type_node, 15702 unsigned_intQI_type_node, 15703 NULL_TREE); 15704 15705 tree const_memx_void_node 15706 = build_qualified_type (void_type_node, 15707 TYPE_QUAL_CONST 15708 | ENCODE_QUAL_ADDR_SPACE (ADDR_SPACE_MEMX)); 15709 15710 tree const_memx_ptr_type_node 15711 = build_pointer_type_for_mode (const_memx_void_node, PSImode, false); 15712 15713 tree intQI_ftype_const_memx_ptr 15714 = build_function_type_list (intQI_type_node, 15715 const_memx_ptr_type_node, 15716 NULL); 15717 15718 #define ITYP(T) \ 15719 lang_hooks.types.type_for_size (TYPE_PRECISION (T), TYPE_UNSIGNED (T)) 15720 15721 #define FX_FTYPE_FX(fx) \ 15722 tree fx##r_ftype_##fx##r \ 15723 = build_function_type_list (node_##fx##r, node_##fx##r, NULL); \ 15724 tree fx##k_ftype_##fx##k \ 15725 = build_function_type_list (node_##fx##k, node_##fx##k, NULL) 15726 15727 #define FX_FTYPE_FX_INT(fx) \ 15728 tree fx##r_ftype_##fx##r_int \ 15729 = build_function_type_list (node_##fx##r, node_##fx##r, \ 15730 integer_type_node, NULL); \ 15731 tree fx##k_ftype_##fx##k_int \ 15732 = build_function_type_list (node_##fx##k, node_##fx##k, \ 15733 integer_type_node, NULL) 15734 15735 #define INT_FTYPE_FX(fx) \ 15736 tree int_ftype_##fx##r \ 15737 = build_function_type_list (integer_type_node, node_##fx##r, NULL); \ 15738 tree int_ftype_##fx##k \ 15739 = build_function_type_list (integer_type_node, node_##fx##k, NULL) 15740 15741 #define INTX_FTYPE_FX(fx) \ 15742 tree int##fx##r_ftype_##fx##r \ 15743 = build_function_type_list (ITYP (node_##fx##r), node_##fx##r, NULL); \ 15744 tree int##fx##k_ftype_##fx##k \ 15745 = build_function_type_list (ITYP (node_##fx##k), node_##fx##k, NULL) 15746 15747 #define FX_FTYPE_INTX(fx) \ 15748 tree fx##r_ftype_int##fx##r \ 15749 = build_function_type_list (node_##fx##r, ITYP (node_##fx##r), NULL); \ 15750 tree fx##k_ftype_int##fx##k \ 15751 = build_function_type_list (node_##fx##k, ITYP (node_##fx##k), NULL) 15752 15753 tree node_hr = short_fract_type_node; 15754 tree node_nr = fract_type_node; 15755 tree node_lr = long_fract_type_node; 15756 tree node_llr = long_long_fract_type_node; 15757 15758 tree node_uhr = unsigned_short_fract_type_node; 15759 tree node_unr = unsigned_fract_type_node; 15760 tree node_ulr = unsigned_long_fract_type_node; 15761 tree node_ullr = unsigned_long_long_fract_type_node; 15762 15763 tree node_hk = short_accum_type_node; 15764 tree node_nk = accum_type_node; 15765 tree node_lk = long_accum_type_node; 15766 tree node_llk = long_long_accum_type_node; 15767 15768 tree node_uhk = unsigned_short_accum_type_node; 15769 tree node_unk = unsigned_accum_type_node; 15770 tree node_ulk = unsigned_long_accum_type_node; 15771 tree node_ullk = unsigned_long_long_accum_type_node; 15772 15773 15774 /* For absfx builtins. */ 15775 15776 FX_FTYPE_FX (h); 15777 FX_FTYPE_FX (n); 15778 FX_FTYPE_FX (l); 15779 FX_FTYPE_FX (ll); 15780 15781 /* For roundfx builtins. */ 15782 15783 FX_FTYPE_FX_INT (h); 15784 FX_FTYPE_FX_INT (n); 15785 FX_FTYPE_FX_INT (l); 15786 FX_FTYPE_FX_INT (ll); 15787 15788 FX_FTYPE_FX_INT (uh); 15789 FX_FTYPE_FX_INT (un); 15790 FX_FTYPE_FX_INT (ul); 15791 FX_FTYPE_FX_INT (ull); 15792 15793 /* For countlsfx builtins. */ 15794 15795 INT_FTYPE_FX (h); 15796 INT_FTYPE_FX (n); 15797 INT_FTYPE_FX (l); 15798 INT_FTYPE_FX (ll); 15799 15800 INT_FTYPE_FX (uh); 15801 INT_FTYPE_FX (un); 15802 INT_FTYPE_FX (ul); 15803 INT_FTYPE_FX (ull); 15804 15805 /* For bitsfx builtins. */ 15806 15807 INTX_FTYPE_FX (h); 15808 INTX_FTYPE_FX (n); 15809 INTX_FTYPE_FX (l); 15810 INTX_FTYPE_FX (ll); 15811 15812 INTX_FTYPE_FX (uh); 15813 INTX_FTYPE_FX (un); 15814 INTX_FTYPE_FX (ul); 15815 INTX_FTYPE_FX (ull); 15816 15817 /* For fxbits builtins. */ 15818 15819 FX_FTYPE_INTX (h); 15820 FX_FTYPE_INTX (n); 15821 FX_FTYPE_INTX (l); 15822 FX_FTYPE_INTX (ll); 15823 15824 FX_FTYPE_INTX (uh); 15825 FX_FTYPE_INTX (un); 15826 FX_FTYPE_INTX (ul); 15827 FX_FTYPE_INTX (ull); 15828 15829 15830 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME) \ 15831 { \ 15832 int id = AVR_BUILTIN_ ## NAME; \ 15833 const char *Name = "__builtin_avr_" #NAME; \ 15834 char *name = (char *) alloca (1 + strlen (Name)); \ 15835 \ 15836 gcc_assert (id < AVR_BUILTIN_COUNT); \ 15837 avr_bdesc[id].fndecl \ 15838 = add_builtin_function (avr_tolower (name, Name), TYPE, id, \ 15839 BUILT_IN_MD, LIBNAME, NULL_TREE); \ 15840 } 15841 #include "builtins.def" 15842 #undef DEF_BUILTIN 15843 15844 avr_init_builtin_int24 (); 15845 } 15846 15847 15848 /* Subroutine of avr_expand_builtin to expand vanilla builtins 15849 with non-void result and 1 ... 3 arguments. */ 15850 15851 static rtx 15852 avr_default_expand_builtin (enum insn_code icode, tree exp, rtx target) 15853 { 15854 rtx pat, xop[3]; 15855 int n_args = call_expr_nargs (exp); 15856 machine_mode tmode = insn_data[icode].operand[0].mode; 15857 15858 gcc_assert (n_args >= 1 && n_args <= 3); 15859 15860 if (target == NULL_RTX 15861 || GET_MODE (target) != tmode 15862 || !insn_data[icode].operand[0].predicate (target, tmode)) 15863 { 15864 target = gen_reg_rtx (tmode); 15865 } 15866 15867 for (int n = 0; n < n_args; n++) 15868 { 15869 tree arg = CALL_EXPR_ARG (exp, n); 15870 rtx op = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL); 15871 machine_mode opmode = GET_MODE (op); 15872 machine_mode mode = insn_data[icode].operand[n + 1].mode; 15873 15874 if ((opmode == SImode || opmode == VOIDmode) && mode == HImode) 15875 { 15876 opmode = HImode; 15877 op = gen_lowpart (HImode, op); 15878 } 15879 15880 /* In case the insn wants input operands in modes different from 15881 the result, abort. */ 15882 15883 gcc_assert (opmode == mode || opmode == VOIDmode); 15884 15885 if (!insn_data[icode].operand[n + 1].predicate (op, mode)) 15886 op = copy_to_mode_reg (mode, op); 15887 15888 xop[n] = op; 15889 } 15890 15891 switch (n_args) 15892 { 15893 case 1: pat = GEN_FCN (icode) (target, xop[0]); break; 15894 case 2: pat = GEN_FCN (icode) (target, xop[0], xop[1]); break; 15895 case 3: pat = GEN_FCN (icode) (target, xop[0], xop[1], xop[2]); break; 15896 15897 default: 15898 gcc_unreachable(); 15899 } 15900 15901 if (pat == NULL_RTX) 15902 return NULL_RTX; 15903 15904 emit_insn (pat); 15905 15906 return target; 15907 } 15908 15909 15910 /* Implement `TARGET_EXPAND_BUILTIN'. */ 15911 /* Expand an expression EXP that calls a built-in function, 15912 with result going to TARGET if that's convenient 15913 (and in mode MODE if that's convenient). 15914 SUBTARGET may be used as the target for computing one of EXP's operands. 15915 IGNORE is nonzero if the value is to be ignored. */ 15916 15917 static rtx 15918 avr_expand_builtin (tree exp, rtx target, rtx /*subtarget*/, 15919 machine_mode mode, int ignore) 15920 { 15921 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 15922 const char *bname = IDENTIFIER_POINTER (DECL_NAME (fndecl)); 15923 unsigned int id = DECL_MD_FUNCTION_CODE (fndecl); 15924 const struct avr_builtin_description *d = &avr_bdesc[id]; 15925 tree arg0; 15926 rtx op0; 15927 15928 gcc_assert (id < AVR_BUILTIN_COUNT); 15929 15930 switch (id) 15931 { 15932 case AVR_BUILTIN_NOP: 15933 emit_insn (gen_nopv (GEN_INT (1))); 15934 return 0; 15935 15936 case AVR_BUILTIN_DELAY_CYCLES: 15937 { 15938 arg0 = CALL_EXPR_ARG (exp, 0); 15939 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL); 15940 15941 if (!CONST_INT_P (op0)) 15942 error ("%s expects a compile time integer constant", bname); 15943 else 15944 avr_expand_delay_cycles (op0); 15945 15946 return NULL_RTX; 15947 } 15948 15949 case AVR_BUILTIN_NOPS: 15950 { 15951 arg0 = CALL_EXPR_ARG (exp, 0); 15952 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL); 15953 15954 if (!CONST_INT_P (op0)) 15955 error ("%s expects a compile time integer constant", bname); 15956 else 15957 avr_expand_nops (op0); 15958 15959 return NULL_RTX; 15960 } 15961 15962 case AVR_BUILTIN_INSERT_BITS: 15963 { 15964 arg0 = CALL_EXPR_ARG (exp, 0); 15965 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL); 15966 15967 if (!CONST_INT_P (op0)) 15968 { 15969 error ("%s expects a compile time long integer constant" 15970 " as first argument", bname); 15971 return target; 15972 } 15973 15974 break; 15975 } 15976 15977 case AVR_BUILTIN_ROUNDHR: case AVR_BUILTIN_ROUNDUHR: 15978 case AVR_BUILTIN_ROUNDR: case AVR_BUILTIN_ROUNDUR: 15979 case AVR_BUILTIN_ROUNDLR: case AVR_BUILTIN_ROUNDULR: 15980 case AVR_BUILTIN_ROUNDLLR: case AVR_BUILTIN_ROUNDULLR: 15981 15982 case AVR_BUILTIN_ROUNDHK: case AVR_BUILTIN_ROUNDUHK: 15983 case AVR_BUILTIN_ROUNDK: case AVR_BUILTIN_ROUNDUK: 15984 case AVR_BUILTIN_ROUNDLK: case AVR_BUILTIN_ROUNDULK: 15985 case AVR_BUILTIN_ROUNDLLK: case AVR_BUILTIN_ROUNDULLK: 15986 15987 /* Warn about odd rounding. Rounding points >= FBIT will have 15988 no effect. */ 15989 15990 if (TREE_CODE (CALL_EXPR_ARG (exp, 1)) != INTEGER_CST) 15991 break; 15992 15993 int rbit = (int) TREE_INT_CST_LOW (CALL_EXPR_ARG (exp, 1)); 15994 15995 if (rbit >= (int) GET_MODE_FBIT (mode)) 15996 { 15997 warning (OPT_Wextra, "rounding to %d bits has no effect for " 15998 "fixed-point value with %d fractional bits", 15999 rbit, GET_MODE_FBIT (mode)); 16000 16001 return expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX, mode, 16002 EXPAND_NORMAL); 16003 } 16004 else if (rbit <= - (int) GET_MODE_IBIT (mode)) 16005 { 16006 warning (0, "rounding result will always be 0"); 16007 return CONST0_RTX (mode); 16008 } 16009 16010 /* The rounding points RP satisfies now: -IBIT < RP < FBIT. 16011 16012 TR 18037 only specifies results for RP > 0. However, the 16013 remaining cases of -IBIT < RP <= 0 can easily be supported 16014 without any additional overhead. */ 16015 16016 break; /* round */ 16017 } 16018 16019 /* No fold found and no insn: Call support function from libgcc. */ 16020 16021 if (d->icode == CODE_FOR_nothing 16022 && DECL_ASSEMBLER_NAME (get_callee_fndecl (exp)) != NULL_TREE) 16023 { 16024 return expand_call (exp, target, ignore); 16025 } 16026 16027 /* No special treatment needed: vanilla expand. */ 16028 16029 gcc_assert (d->icode != CODE_FOR_nothing); 16030 gcc_assert (d->n_args == call_expr_nargs (exp)); 16031 16032 if (d->n_args == 0) 16033 { 16034 emit_insn ((GEN_FCN (d->icode)) (target)); 16035 return NULL_RTX; 16036 } 16037 16038 return avr_default_expand_builtin (d->icode, exp, target); 16039 } 16040 16041 16042 /* Helper for `avr_fold_builtin' that folds absfx (FIXED_CST). */ 16043 16044 static tree 16045 avr_fold_absfx (tree tval) 16046 { 16047 if (FIXED_CST != TREE_CODE (tval)) 16048 return NULL_TREE; 16049 16050 /* Our fixed-points have no padding: Use double_int payload directly. */ 16051 16052 FIXED_VALUE_TYPE fval = TREE_FIXED_CST (tval); 16053 unsigned int bits = GET_MODE_BITSIZE (fval.mode); 16054 double_int ival = fval.data.sext (bits); 16055 16056 if (!ival.is_negative()) 16057 return tval; 16058 16059 /* ISO/IEC TR 18037, 7.18a.6.2: The absfx functions are saturating. */ 16060 16061 fval.data = (ival == double_int::min_value (bits, false).sext (bits)) 16062 ? double_int::max_value (bits, false) 16063 : -ival; 16064 16065 return build_fixed (TREE_TYPE (tval), fval); 16066 } 16067 16068 16069 /* Implement `TARGET_FOLD_BUILTIN'. */ 16070 16071 static tree 16072 avr_fold_builtin (tree fndecl, int /*n_args*/, tree *arg, bool /*ignore*/) 16073 { 16074 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl); 16075 tree val_type = TREE_TYPE (TREE_TYPE (fndecl)); 16076 16077 if (!optimize) 16078 return NULL_TREE; 16079 16080 switch (fcode) 16081 { 16082 default: 16083 break; 16084 16085 case AVR_BUILTIN_SWAP: 16086 { 16087 return fold_build2 (LROTATE_EXPR, val_type, arg[0], 16088 build_int_cst (val_type, 4)); 16089 } 16090 16091 case AVR_BUILTIN_ABSHR: 16092 case AVR_BUILTIN_ABSR: 16093 case AVR_BUILTIN_ABSLR: 16094 case AVR_BUILTIN_ABSLLR: 16095 16096 case AVR_BUILTIN_ABSHK: 16097 case AVR_BUILTIN_ABSK: 16098 case AVR_BUILTIN_ABSLK: 16099 case AVR_BUILTIN_ABSLLK: 16100 /* GCC is not good with folding ABS for fixed-point. Do it by hand. */ 16101 16102 return avr_fold_absfx (arg[0]); 16103 16104 case AVR_BUILTIN_BITSHR: case AVR_BUILTIN_HRBITS: 16105 case AVR_BUILTIN_BITSHK: case AVR_BUILTIN_HKBITS: 16106 case AVR_BUILTIN_BITSUHR: case AVR_BUILTIN_UHRBITS: 16107 case AVR_BUILTIN_BITSUHK: case AVR_BUILTIN_UHKBITS: 16108 16109 case AVR_BUILTIN_BITSR: case AVR_BUILTIN_RBITS: 16110 case AVR_BUILTIN_BITSK: case AVR_BUILTIN_KBITS: 16111 case AVR_BUILTIN_BITSUR: case AVR_BUILTIN_URBITS: 16112 case AVR_BUILTIN_BITSUK: case AVR_BUILTIN_UKBITS: 16113 16114 case AVR_BUILTIN_BITSLR: case AVR_BUILTIN_LRBITS: 16115 case AVR_BUILTIN_BITSLK: case AVR_BUILTIN_LKBITS: 16116 case AVR_BUILTIN_BITSULR: case AVR_BUILTIN_ULRBITS: 16117 case AVR_BUILTIN_BITSULK: case AVR_BUILTIN_ULKBITS: 16118 16119 case AVR_BUILTIN_BITSLLR: case AVR_BUILTIN_LLRBITS: 16120 case AVR_BUILTIN_BITSLLK: case AVR_BUILTIN_LLKBITS: 16121 case AVR_BUILTIN_BITSULLR: case AVR_BUILTIN_ULLRBITS: 16122 case AVR_BUILTIN_BITSULLK: case AVR_BUILTIN_ULLKBITS: 16123 16124 gcc_assert (TYPE_PRECISION (val_type) 16125 == TYPE_PRECISION (TREE_TYPE (arg[0]))); 16126 16127 return build1 (VIEW_CONVERT_EXPR, val_type, arg[0]); 16128 16129 case AVR_BUILTIN_INSERT_BITS: 16130 { 16131 tree tbits = arg[1]; 16132 tree tval = arg[2]; 16133 tree map_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl))); 16134 bool changed = false; 16135 avr_map_op_t best_g; 16136 16137 if (TREE_CODE (arg[0]) != INTEGER_CST) 16138 { 16139 /* No constant as first argument: Don't fold this and run into 16140 error in avr_expand_builtin. */ 16141 16142 break; 16143 } 16144 16145 tree tmap = wide_int_to_tree (map_type, wi::to_wide (arg[0])); 16146 unsigned int map = TREE_INT_CST_LOW (tmap); 16147 16148 if (TREE_CODE (tval) != INTEGER_CST 16149 && avr_map_metric (map, MAP_MASK_PREIMAGE_F) == 0) 16150 { 16151 /* There are no F in the map, i.e. 3rd operand is unused. 16152 Replace that argument with some constant to render 16153 respective input unused. */ 16154 16155 tval = build_int_cst (val_type, 0); 16156 changed = true; 16157 } 16158 16159 if (TREE_CODE (tbits) != INTEGER_CST 16160 && avr_map_metric (map, MAP_PREIMAGE_0_7) == 0) 16161 { 16162 /* Similar for the bits to be inserted. If they are unused, 16163 we can just as well pass 0. */ 16164 16165 tbits = build_int_cst (val_type, 0); 16166 } 16167 16168 if (TREE_CODE (tbits) == INTEGER_CST) 16169 { 16170 /* Inserting bits known at compile time is easy and can be 16171 performed by AND and OR with appropriate masks. */ 16172 16173 int bits = TREE_INT_CST_LOW (tbits); 16174 int mask_ior = 0, mask_and = 0xff; 16175 16176 for (size_t i = 0; i < 8; i++) 16177 { 16178 int mi = avr_map (map, i); 16179 16180 if (mi < 8) 16181 { 16182 if (bits & (1 << mi)) mask_ior |= (1 << i); 16183 else mask_and &= ~(1 << i); 16184 } 16185 } 16186 16187 tval = fold_build2 (BIT_IOR_EXPR, val_type, tval, 16188 build_int_cst (val_type, mask_ior)); 16189 return fold_build2 (BIT_AND_EXPR, val_type, tval, 16190 build_int_cst (val_type, mask_and)); 16191 } 16192 16193 if (changed) 16194 return build_call_expr (fndecl, 3, tmap, tbits, tval); 16195 16196 /* If bits don't change their position, we can use vanilla logic 16197 to merge the two arguments... */ 16198 16199 if (avr_map_metric (map, MAP_NONFIXED_0_7) == 0 16200 // ...except when we are copying just one bit. In that 16201 // case, BLD/BST is better than XOR/AND/XOR, see PR90622. 16202 && avr_map_metric (map, MAP_FIXED_0_7) != 1) 16203 { 16204 int mask_f = avr_map_metric (map, MAP_MASK_PREIMAGE_F); 16205 tree tres, tmask = build_int_cst (val_type, mask_f ^ 0xff); 16206 16207 tres = fold_build2 (BIT_XOR_EXPR, val_type, tbits, tval); 16208 tres = fold_build2 (BIT_AND_EXPR, val_type, tres, tmask); 16209 return fold_build2 (BIT_XOR_EXPR, val_type, tres, tval); 16210 } 16211 16212 /* Try to decomposing map to reduce overall cost. */ 16213 16214 if (avr_log.builtin) 16215 avr_edump ("\n%?: %x\n%?: ROL cost: ", map); 16216 16217 best_g = avr_map_op[0]; 16218 best_g.cost = 1000; 16219 16220 for (size_t i = 0; i < ARRAY_SIZE (avr_map_op); i++) 16221 { 16222 avr_map_op_t g 16223 = avr_map_decompose (map, avr_map_op + i, 16224 TREE_CODE (tval) == INTEGER_CST); 16225 16226 if (g.cost >= 0 && g.cost < best_g.cost) 16227 best_g = g; 16228 } 16229 16230 if (avr_log.builtin) 16231 avr_edump ("\n"); 16232 16233 if (best_g.arg == 0) 16234 /* No optimization found */ 16235 break; 16236 16237 /* Apply operation G to the 2nd argument. */ 16238 16239 if (avr_log.builtin) 16240 avr_edump ("%?: using OP(%s%d, %x) cost %d\n", 16241 best_g.str, best_g.arg, best_g.map, best_g.cost); 16242 16243 /* Do right-shifts arithmetically: They copy the MSB instead of 16244 shifting in a non-usable value (0) as with logic right-shift. */ 16245 16246 tbits = fold_convert (signed_char_type_node, tbits); 16247 tbits = fold_build2 (best_g.code, signed_char_type_node, tbits, 16248 build_int_cst (val_type, best_g.arg)); 16249 tbits = fold_convert (val_type, tbits); 16250 16251 /* Use map o G^-1 instead of original map to undo the effect of G. */ 16252 16253 tmap = wide_int_to_tree (map_type, best_g.map); 16254 16255 return build_call_expr (fndecl, 3, tmap, tbits, tval); 16256 } /* AVR_BUILTIN_INSERT_BITS */ 16257 } 16258 16259 return NULL_TREE; 16260 } 16261 16262 16263 /* Implement `TARGET_MD_ASM_ADJUST'. */ 16264 /* Prepend to CLOBBERS hard registers that are automatically clobbered 16265 for an asm. We do this for CC_REGNUM to maintain source compatibility 16266 with the original cc0-based compiler. */ 16267 16268 static rtx_insn * 16269 avr_md_asm_adjust (vec<rtx> &/*outputs*/, vec<rtx> &/*inputs*/, 16270 vec<machine_mode> & /*input_modes*/, 16271 vec<const char *> &/*constraints*/, 16272 vec<rtx> &/*uses*/, 16273 vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs, 16274 location_t /*loc*/) 16275 { 16276 clobbers.safe_push (cc_reg_rtx); 16277 SET_HARD_REG_BIT (clobbered_regs, REG_CC); 16278 return NULL; 16279 } 16280 16281 16282 /* Worker function for `FLOAT_LIB_COMPARE_RETURNS_BOOL'. */ 16283 16284 bool 16285 avr_float_lib_compare_returns_bool (machine_mode mode, enum rtx_code) 16286 { 16287 if (mode == DFmode) 16288 { 16289 #if WITH_DOUBLE_COMPARISON == 2 16290 return true; 16291 #endif 16292 } 16293 16294 // This is the GCC default and also what AVR-LibC implements. 16295 return false; 16296 } 16297 16298 16299 16301 /* Initialize the GCC target structure. */ 16302 16303 #undef TARGET_ASM_ALIGNED_HI_OP 16304 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t" 16305 #undef TARGET_ASM_ALIGNED_SI_OP 16306 #define TARGET_ASM_ALIGNED_SI_OP "\t.long\t" 16307 #undef TARGET_ASM_UNALIGNED_HI_OP 16308 #define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t" 16309 #undef TARGET_ASM_UNALIGNED_SI_OP 16310 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t" 16311 #undef TARGET_ASM_INTEGER 16312 #define TARGET_ASM_INTEGER avr_assemble_integer 16313 #undef TARGET_ASM_FILE_START 16314 #define TARGET_ASM_FILE_START avr_file_start 16315 #undef TARGET_ASM_FILE_END 16316 #define TARGET_ASM_FILE_END avr_file_end 16317 16318 #undef TARGET_ASM_FUNCTION_END_PROLOGUE 16319 #define TARGET_ASM_FUNCTION_END_PROLOGUE avr_asm_function_end_prologue 16320 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE 16321 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE avr_asm_function_begin_epilogue 16322 16323 #undef TARGET_FUNCTION_VALUE 16324 #define TARGET_FUNCTION_VALUE avr_function_value 16325 #undef TARGET_LIBCALL_VALUE 16326 #define TARGET_LIBCALL_VALUE avr_libcall_value 16327 #undef TARGET_FUNCTION_VALUE_REGNO_P 16328 #define TARGET_FUNCTION_VALUE_REGNO_P avr_function_value_regno_p 16329 16330 #undef TARGET_ATTRIBUTE_TABLE 16331 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table 16332 #undef TARGET_INSERT_ATTRIBUTES 16333 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes 16334 #undef TARGET_SECTION_TYPE_FLAGS 16335 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags 16336 16337 #undef TARGET_ASM_NAMED_SECTION 16338 #define TARGET_ASM_NAMED_SECTION avr_asm_named_section 16339 #undef TARGET_ASM_INIT_SECTIONS 16340 #define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections 16341 #undef TARGET_ENCODE_SECTION_INFO 16342 #define TARGET_ENCODE_SECTION_INFO avr_encode_section_info 16343 #undef TARGET_ASM_SELECT_SECTION 16344 #define TARGET_ASM_SELECT_SECTION avr_asm_select_section 16345 16346 #undef TARGET_ASM_FINAL_POSTSCAN_INSN 16347 #define TARGET_ASM_FINAL_POSTSCAN_INSN avr_asm_final_postscan_insn 16348 16349 #undef TARGET_INSN_COST 16350 #define TARGET_INSN_COST avr_insn_cost 16351 #undef TARGET_REGISTER_MOVE_COST 16352 #define TARGET_REGISTER_MOVE_COST avr_register_move_cost 16353 #undef TARGET_MEMORY_MOVE_COST 16354 #define TARGET_MEMORY_MOVE_COST avr_memory_move_cost 16355 #undef TARGET_RTX_COSTS 16356 #define TARGET_RTX_COSTS avr_rtx_costs 16357 #undef TARGET_ADDRESS_COST 16358 #define TARGET_ADDRESS_COST avr_address_cost 16359 #undef TARGET_FUNCTION_ARG 16360 #define TARGET_FUNCTION_ARG avr_function_arg 16361 #undef TARGET_FUNCTION_ARG_ADVANCE 16362 #define TARGET_FUNCTION_ARG_ADVANCE avr_function_arg_advance 16363 16364 #undef TARGET_SET_CURRENT_FUNCTION 16365 #define TARGET_SET_CURRENT_FUNCTION avr_set_current_function 16366 16367 #undef TARGET_RETURN_IN_MEMORY 16368 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory 16369 16370 #undef TARGET_STRICT_ARGUMENT_NAMING 16371 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true 16372 16373 #undef TARGET_CONDITIONAL_REGISTER_USAGE 16374 #define TARGET_CONDITIONAL_REGISTER_USAGE avr_conditional_register_usage 16375 16376 #undef TARGET_HARD_REGNO_NREGS 16377 #define TARGET_HARD_REGNO_NREGS avr_hard_regno_nregs 16378 16379 #undef TARGET_HARD_REGNO_MODE_OK 16380 #define TARGET_HARD_REGNO_MODE_OK avr_hard_regno_mode_ok 16381 #undef TARGET_HARD_REGNO_SCRATCH_OK 16382 #define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok 16383 #undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED 16384 #define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \ 16385 avr_hard_regno_call_part_clobbered 16386 16387 #undef TARGET_CASE_VALUES_THRESHOLD 16388 #define TARGET_CASE_VALUES_THRESHOLD avr_case_values_threshold 16389 16390 #undef TARGET_FRAME_POINTER_REQUIRED 16391 #define TARGET_FRAME_POINTER_REQUIRED avr_frame_pointer_required_p 16392 #undef TARGET_CAN_ELIMINATE 16393 #define TARGET_CAN_ELIMINATE avr_can_eliminate 16394 16395 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS 16396 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS avr_allocate_stack_slots_for_args 16397 16398 #undef TARGET_WARN_FUNC_RETURN 16399 #define TARGET_WARN_FUNC_RETURN avr_warn_func_return 16400 16401 #undef TARGET_CLASS_LIKELY_SPILLED_P 16402 #define TARGET_CLASS_LIKELY_SPILLED_P avr_class_likely_spilled_p 16403 16404 #undef TARGET_CLASS_MAX_NREGS 16405 #define TARGET_CLASS_MAX_NREGS avr_class_max_nregs 16406 16407 #undef TARGET_OPTION_OVERRIDE 16408 #define TARGET_OPTION_OVERRIDE avr_option_override 16409 16410 #undef TARGET_CANNOT_MODIFY_JUMPS_P 16411 #define TARGET_CANNOT_MODIFY_JUMPS_P avr_cannot_modify_jumps_p 16412 16413 #undef TARGET_FUNCTION_OK_FOR_SIBCALL 16414 #define TARGET_FUNCTION_OK_FOR_SIBCALL avr_function_ok_for_sibcall 16415 16416 #undef TARGET_INIT_BUILTINS 16417 #define TARGET_INIT_BUILTINS avr_init_builtins 16418 16419 #undef TARGET_BUILTIN_DECL 16420 #define TARGET_BUILTIN_DECL avr_builtin_decl 16421 16422 #undef TARGET_EXPAND_BUILTIN 16423 #define TARGET_EXPAND_BUILTIN avr_expand_builtin 16424 16425 #undef TARGET_FOLD_BUILTIN 16426 #define TARGET_FOLD_BUILTIN avr_fold_builtin 16427 16428 #undef TARGET_SCALAR_MODE_SUPPORTED_P 16429 #define TARGET_SCALAR_MODE_SUPPORTED_P avr_scalar_mode_supported_p 16430 16431 #undef TARGET_BUILD_BUILTIN_VA_LIST 16432 #define TARGET_BUILD_BUILTIN_VA_LIST avr_build_builtin_va_list 16433 16434 #undef TARGET_FIXED_POINT_SUPPORTED_P 16435 #define TARGET_FIXED_POINT_SUPPORTED_P hook_bool_void_true 16436 16437 #undef TARGET_CONVERT_TO_TYPE 16438 #define TARGET_CONVERT_TO_TYPE avr_convert_to_type 16439 16440 #undef TARGET_LRA_P 16441 #define TARGET_LRA_P hook_bool_void_false 16442 16443 #undef TARGET_ADDR_SPACE_SUBSET_P 16444 #define TARGET_ADDR_SPACE_SUBSET_P avr_addr_space_subset_p 16445 16446 #undef TARGET_ADDR_SPACE_CONVERT 16447 #define TARGET_ADDR_SPACE_CONVERT avr_addr_space_convert 16448 16449 #undef TARGET_ADDR_SPACE_ADDRESS_MODE 16450 #define TARGET_ADDR_SPACE_ADDRESS_MODE avr_addr_space_address_mode 16451 16452 #undef TARGET_ADDR_SPACE_POINTER_MODE 16453 #define TARGET_ADDR_SPACE_POINTER_MODE avr_addr_space_pointer_mode 16454 16455 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P 16456 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \ 16457 avr_addr_space_legitimate_address_p 16458 16459 #undef TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS 16460 #define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS avr_addr_space_legitimize_address 16461 16462 #undef TARGET_ADDR_SPACE_DIAGNOSE_USAGE 16463 #define TARGET_ADDR_SPACE_DIAGNOSE_USAGE avr_addr_space_diagnose_usage 16464 16465 #undef TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID 16466 #define TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID avr_addr_space_zero_address_valid 16467 16468 #undef TARGET_MODE_DEPENDENT_ADDRESS_P 16469 #define TARGET_MODE_DEPENDENT_ADDRESS_P avr_mode_dependent_address_p 16470 16471 #undef TARGET_PRINT_OPERAND 16472 #define TARGET_PRINT_OPERAND avr_print_operand 16473 #undef TARGET_PRINT_OPERAND_ADDRESS 16474 #define TARGET_PRINT_OPERAND_ADDRESS avr_print_operand_address 16475 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P 16476 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P avr_print_operand_punct_valid_p 16477 16478 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P 16479 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \ 16480 avr_use_by_pieces_infrastructure_p 16481 16482 #undef TARGET_LEGITIMATE_COMBINED_INSN 16483 #define TARGET_LEGITIMATE_COMBINED_INSN avr_legitimate_combined_insn 16484 16485 #undef TARGET_STARTING_FRAME_OFFSET 16486 #define TARGET_STARTING_FRAME_OFFSET avr_starting_frame_offset 16487 16488 #undef TARGET_MD_ASM_ADJUST 16489 #define TARGET_MD_ASM_ADJUST avr_md_asm_adjust 16490 16491 #undef TARGET_CAN_INLINE_P 16492 #define TARGET_CAN_INLINE_P avr_can_inline_p 16493 16494 #undef TARGET_CANONICALIZE_COMPARISON 16495 #define TARGET_CANONICALIZE_COMPARISON avr_canonicalize_comparison 16496 16497 /* According to the opening comment in PR86772, the following applies: 16498 "If the port does not (and never will in the future) need to mitigate 16499 against unsafe speculation." */ 16500 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE 16501 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed 16502 16503 struct gcc_target targetm = TARGET_INITIALIZER; 16504 16505 16506 #include "gt-avr.h" 16508